From 01cb52ac3c77f7ca9b2c0c81c9fa0f37f27f3514 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Mon, 23 Jan 2017 11:11:10 +0100 Subject: [PATCH 1/2] Make JS harness optional --- interpreter/README.md | 2 ++ interpreter/host/flags.ml | 1 + interpreter/host/js.ml | 5 +++-- interpreter/host/main.ml | 3 ++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/interpreter/README.md b/interpreter/README.md index 482173e8e7..b58c1f108a 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -96,6 +96,8 @@ wasm -d script.wast -o script.js The first creates a new test scripts where all embedded modules are converted to binary, the second one where all are converted to textual. The last invocation produces an equivalent, self-contained JavaScript test file. +The flag `-h` can be used to omit the test harness from the converted file; +it then is the client's responsibility to provide versions of the necessary functions. By default, the generated script will require `assert_soft_invalid` (see below) to detect validation failures. Use the `-us` flag ("unchecked soft") to deactivate these assertions to run on implementations that do not validate dead code. #### Command Line Expressions diff --git a/interpreter/host/flags.ml b/interpreter/host/flags.ml index 00b8e6fde3..77471f7ded 100644 --- a/interpreter/host/flags.ml +++ b/interpreter/host/flags.ml @@ -5,3 +5,4 @@ let unchecked_soft = ref false let print_sig = ref false let dry = ref false let width = ref 80 +let harness = ref true diff --git a/interpreter/host/js.ml b/interpreter/host/js.ml index 7afc56fc9d..4045539eb2 100644 --- a/interpreter/host/js.ml +++ b/interpreter/host/js.ml @@ -6,7 +6,7 @@ open Source (* Harness *) -let prefix = +let harness = "'use strict';\n" ^ "\n" ^ "let soft_validate = " ^ string_of_bool (not !Flags.unchecked_soft) ^ ";\n" ^ @@ -352,4 +352,5 @@ let of_command mods cmd = | Meta _ -> assert false let of_script scr = - prefix ^ String.concat "" (List.map (of_command (ref Map.empty)) scr) + (if !Flags.harness then harness else "") ^ + String.concat "" (List.map (of_command (ref Map.empty)) scr) diff --git a/interpreter/host/main.ml b/interpreter/host/main.ml index 8a474db897..a5dd34876e 100644 --- a/interpreter/host/main.ml +++ b/interpreter/host/main.ml @@ -1,5 +1,5 @@ let name = "wasm" -let version = "0.6" +let version = "0.7" let configure () = Import.register "spectest" Spectest.lookup; @@ -31,6 +31,7 @@ let argspec = Arg.align "-s", Arg.Set Flags.print_sig, " show module signatures"; "-u", Arg.Set Flags.unchecked, " unchecked, do not perform validation"; "-us", Arg.Set Flags.unchecked_soft, " do not perform soft validation checks"; + "-h", Arg.Clear Flags.harness, " exclude harness for JS convesion"; "-d", Arg.Set Flags.dry, " dry, do not run program"; "-t", Arg.Set Flags.trace, " trace execution"; "-v", Arg.Unit banner, " show version" From 7a77580b829cc3941bad75fdb4682d0e7f3bc7dc Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Mon, 23 Jan 2017 16:57:50 +0100 Subject: [PATCH 2/2] Abstract JS call, get, and exports --- interpreter/host/js.ml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/interpreter/host/js.ml b/interpreter/host/js.ml index 4045539eb2..5fcb6f597e 100644 --- a/interpreter/host/js.ml +++ b/interpreter/host/js.ml @@ -49,6 +49,18 @@ let harness = " return new WebAssembly.Instance(module(bytes), imports);\n" ^ "}\n" ^ "\n" ^ + "function call(instance, name, args) {\n" ^ + " return instance.exports[name](...args);\n" ^ + "}\n" ^ + "\n" ^ + "function get(instance, name) {\n" ^ + " return instance.exports[name];\n" ^ + "}\n" ^ + "\n" ^ + "function exports(name, instance) {\n" ^ + " return {[name]: instance.exports};\n" ^ + "}\n" ^ + "\n" ^ "function assert_malformed(bytes) {\n" ^ " try { module(bytes, false) } catch (e) {\n" ^ " if (e instanceof WebAssembly.CompileError) return;\n" ^ @@ -248,8 +260,8 @@ let of_string = of_string_with add_char let of_wrapper x_opt name wrap_action wrap_assertion at = let x = of_var_opt x_opt in let bs = wrap x name wrap_action wrap_assertion at in - "instance(" ^ of_bytes bs ^ ", " ^ "{" ^ x ^ ": " ^ x ^ ".exports})" ^ - ".exports.run()" + "call(instance(" ^ of_bytes bs ^ ", " ^ + "exports(" ^ of_string x ^ ", " ^ x ^ ")), " ^ " \"run\", [])" let of_float z = match string_of_float z with @@ -276,8 +288,8 @@ let of_definition def = let of_action mods act = match act.it with | Invoke (x_opt, name, lits) -> - of_var_opt x_opt ^ ".exports[" ^ of_string name ^ "]" ^ - "(" ^ String.concat ", " (List.map of_literal lits) ^ ")", + "call(" ^ of_var_opt x_opt ^ ", " ^ of_string name ^ ", " ^ + "[" ^ String.concat ", " (List.map of_literal lits) ^ "])", (match lookup mods x_opt name act.at with | ExternalFuncType ft when not (is_js_func_type ft) -> let FuncType (_, out) = ft in @@ -285,7 +297,7 @@ let of_action mods act = | _ -> None ) | Get (x_opt, name) -> - of_var_opt x_opt ^ ".exports[" ^ of_string name ^ "]", + "get(" ^ of_var_opt x_opt ^ ", " ^ of_string name ^ ")", (match lookup mods x_opt name act.at with | ExternalGlobalType gt when not (is_js_global_type gt) -> let GlobalType (t, _) = gt in