From 76654e28102e37b65503ae744e8767bb2cba7963 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Tue, 29 Oct 2024 16:23:33 +0100 Subject: [PATCH] [interpreter] Fix (and sanity-check) JS wrapper modules --- .github/workflows/ci-interpreter.yml | 4 +-- interpreter/script/js.ml | 43 ++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-interpreter.yml b/.github/workflows/ci-interpreter.yml index 6c09ffc0f7..7ac7513dd0 100644 --- a/.github/workflows/ci-interpreter.yml +++ b/.github/workflows/ci-interpreter.yml @@ -2,11 +2,11 @@ name: CI for interpreter & tests on: push: - branches: [ main ] + branches: [ main, wasm-3.0 ] paths: [ .github/**, interpreter/**, test/** ] pull_request: - branches: [ main ] + branches: [ main, wasm-3.0 ] paths: [ .github/**, interpreter/**, test/** ] # Allows you to run this workflow manually from the Actions tab diff --git a/interpreter/script/js.ml b/interpreter/script/js.ml index 47640d683e..a9bde93535 100644 --- a/interpreter/script/js.ml +++ b/interpreter/script/js.ml @@ -309,8 +309,15 @@ let value v = | Num n -> [Const (n @@ v.at) @@ v.at] | Vec s -> [VecConst (s @@ v.at) @@ v.at] | Ref (NullRef ht) -> [RefNull (Match.bot_of_heap_type [] ht) @@ v.at] + | Ref (HostRef n) -> + [ Const (I32 n @@ v.at) @@ v.at; + Call (hostref_idx @@ v.at) @@ v.at; + ] | Ref (Extern.ExternRef (HostRef n)) -> - [Const (I32 n @@ v.at) @@ v.at; Call (hostref_idx @@ v.at) @@ v.at] + [ Const (I32 n @@ v.at) @@ v.at; + Call (hostref_idx @@ v.at) @@ v.at; + ExternConvert Externalize @@ v.at; + ] | Ref _ -> assert false let invoke ft vs at = @@ -357,6 +364,7 @@ let rec type_of_result res = ) (List.hd ts) ts let assert_return ress ts at = + let locals = ref [] in let rec test (res, t) = if not ( @@ -436,10 +444,17 @@ let assert_return ress ts at = [ RefIsNull @@ at; Test (Value.I32 I32Op.Eqz) @@ at; BrIf (0l @@ at) @@ at ] - | RefResult (RefPat {it = (HostRef n | Extern.ExternRef (HostRef n)); _}) -> + | RefResult (RefPat {it = HostRef n; _}) -> + [ Const (Value.I32 n @@ at) @@ at; + Call (hostref_idx @@ at) @@ at; + Call (eq_ref_idx @@ at) @@ at; + Test (Value.I32 I32Op.Eqz) @@ at; + BrIf (0l @@ at) @@ at ] + | RefResult (RefPat {it = Extern.ExternRef (HostRef n); _}) -> [ Const (Value.I32 n @@ at) @@ at; Call (hostref_idx @@ at) @@ at; - Call (eq_ref_idx @@ at) @@ at; + ExternConvert Externalize @@ at; + Call (eq_ref_idx @@ at) @@ at; Test (Value.I32 I32Op.Eqz) @@ at; BrIf (0l @@ at) @@ at ] | RefResult (RefPat _) -> @@ -455,9 +470,13 @@ let assert_return ress ts at = Test (I32 I32Op.Eqz) @@ at; BrIf (0l @@ at) @@ at ] | EitherResult ress -> - [ Block (ValBlockType None, + let idx = Lib.List32.length !locals in + locals := !locals @ [{ltype = t} @@ res.at]; + [ LocalSet (idx @@ res.at) @@ res.at; + Block (ValBlockType None, List.map (fun resI -> Block (ValBlockType None, + [LocalGet (idx @@ resI.at) @@ resI.at] @ test (resI, t) @ [Br (1l @@ resI.at) @@ resI.at] ) @@ resI.at @@ -465,7 +484,7 @@ let assert_return ress ts at = [Br (1l @@ at) @@ at] ) @@ at ] - in [], List.flatten (List.rev_map test (List.combine ress ts)) + in !locals, List.flatten (List.rev_map test (List.combine ress ts)) let i32 = NumT I32T let anyref = RefT (Null, AnyHT) @@ -504,12 +523,20 @@ let wrap item_name wrap_action wrap_assertion at = in let funcs = [{ftype = 0l @@ at; locals; body} @@ at] in let m = {empty_module with types; funcs; imports; exports} @@ at in + (try + Valid.check_module m; (* sanity check *) + with Valid.Invalid _ as exn -> + prerr_endline (string_of_region at ^ + ": internal error in JS converter, invalid wrapper module generated:"); + Sexpr.output stderr 80 (Arrange.module_ m); + raise exn + ); Encode.encode m let is_js_num_type = function - | I32T -> true - | I64T | F32T | F64T -> false + | I32T | I64T -> true + | F32T | F64T -> false let is_js_vec_type = function | _ -> false @@ -569,7 +596,7 @@ let of_num n = let open Value in match n with | I32 i -> I32.to_string_s i - | I64 i -> "int64(\"" ^ I64.to_string_s i ^ "\")" + | I64 i -> I64.to_string_s i ^ "n" | F32 z -> of_float (F32.to_float z) | F64 z -> of_float (F64.to_float z)