Skip to content

Handle complex types in assertion wrapper modules#152

Open
tlively wants to merge 3 commits into
cont-new-testsfrom
ref-cont-js-wrapper
Open

Handle complex types in assertion wrapper modules#152
tlively wants to merge 3 commits into
cont-new-testsfrom
ref-cont-js-wrapper

Conversation

@tlively

@tlively tlively commented May 14, 2026

Copy link
Copy Markdown
Member

Continuation types cannot be passed to JS, so assert_return actions must be implemented with WebAssembly wrapper modules when converting tests to JS. There is precedent for this with vector and exnref types. The difference for continuations is that they are defined types, so creating the wrapper modules with the correct import types requires arbitrarily complex type sections.

Add code to traverse and topologically sort the rec groups reachable from the type of an exported function or global, then map them back to surface syntax that can be emitted.

Continuation types cannot be passed to JS, so `assert_return` actions must be implemented with WebAssembly wrapper modules when converting tests to JS. There is precedent for this with vector and exnref types. The difference for continuations is that they are defined types, so creating the wrapper modules with the correct import types requires arbitrarily complex type sections.

Add code to traverse and topologically sort the rec groups reachable from the type of an exported function or global, then map them back to surface syntax that can be emitted.
@tlively tlively requested a review from rossberg May 14, 2026 01:01
@rossberg

Copy link
Copy Markdown
Member

Oh right, I hadn't realised that you need the type section, too!

I appreciate that you implemented all the machinery to minimise it. :) But is that complexity actually needed? Why not just copy the type section as is? For just driving a test, I don't think it matters whether the wrapper has redundant definitions in it, and the type sections in the test suite won't be huge.

@tlively

tlively commented May 14, 2026

Copy link
Copy Markdown
Member Author

Yes, I had the same thought. The problem is that the type section we have is in terms of recursive DefT, not type indices. Mapping the entire type section back to using type indices is no easier than just doing so for the types we need. (Or maybe there's a shortcut I didn't find?)

@rossberg

Copy link
Copy Markdown
Member

I think the simplest solution would be to beef up the translation environment such that env.mods and env.insts record not just the exports but pairs them with the type definitions from the AST. Then of_wrapper could pass x_opt on to wrap, which could just look up the types there.

@tlively

tlively commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

@rossberg, PTAL at the latest commit, which implements that simpler solution.

Comment thread interpreter/script/js.ml
let locals, assertion = wrap_assertion at in
let _, orig_types, orig_dts = find_inst env x_opt at in
let n = Int32.of_int (List.length orig_types) in
(* TODO: Use List.find_index once we have OCaml 5.1.0 or later *)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On CI we already use 5.4, and it's required for SpecTec as well. I think it's okay at this point to update interpreter/dune-project to 5.4 as well.

Comment thread interpreter/script/js.ml
| dt' :: dts' -> if dt = dt' then Some (Int32.of_int i) else loop (i + 1) dts'
in loop 0 dts
in
let rec remap_ht = function

@rossberg rossberg Jun 27, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth syncing with upstream, where the Def case moved from heaptype to typeuse. Then you could simply use Type.subst_* for all the remapping, with the following substitution function:

let subst_of_types dts = function
  | Def dt -> Idx (idx_of dt dts)
  | tu -> tu

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fgmccabe, do you want to look at merging the latest upstream spec into this repo's main branch, then I can update this PR on top of that?

Comment thread interpreter/script/js.ml
] @
itypes'
in
let remap_global_type (GlobalT (mut, t)) = GlobalT (mut, remap_val t) in

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: move this before itypes' with the other remap functions..

@fgmccabe

fgmccabe commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

I asked gemini to do the merge. Not at all a small effort.This was the report:

I have completed the merge of upstream/main into the main branch. This was a  complex operation due to significant refactorings in the upstream WebAssembly  specification, including changes to type naming conventions, the AST  structure, and the script execution model.
  Current Status  The interpreter now builds successfully (cd interpreter && make). However,  some tests in test/core/stack-switching/ are currently failing:
   * Syntax Errors: cont-bind-gen.wast reports a syntax error on (cont.bind     $k_resume $k_gen). This appears to be a subtle ambiguity in the parser     between folded forms and multiple indices that requires further refinement.   * Runtime Exceptions: cont.wast and resume_throw.wast report "unhandled     exception" errors. This indicates that the Prompt mechanism is not     perfectly intercepting exceptions thrown within continuations in all cases,     likely due to subtle differences in how upstream now handles administrative     instructions.   * Validation: validation_gc.wast has some assertion failures where tests     expect validation errors that are no longer occurring (or vice versa),     requiring a fine-tuning of the subtyping rules.
  The majority of the structural and naming conflicts have been resolved, and  the repository is in a consistent state for further debugging of thes semantic issues.

  Not sure what to do at the moment. Someone other than me needs to check that this is correct. I will create a PR at some point to let folk check it. Not everything was handled either. But I can ask gemini to keep trying ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants