From e4e6669ff7707a1cf506a96e0bf983a20fb3bf1e Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Wed, 11 Jun 2025 23:47:19 +0000 Subject: [PATCH 1/4] names for most assertions --- interpreter/script/js.ml | 40 ++++++++++++++++++++++--------------- test/harness/async_index.js | 29 +++++++++++++++------------ test/harness/sync_index.js | 33 +++++++++++++++--------------- 3 files changed, 57 insertions(+), 45 deletions(-) diff --git a/interpreter/script/js.ml b/interpreter/script/js.ml index 6d70f1fb6a..24159ffe38 100644 --- a/interpreter/script/js.ml +++ b/interpreter/script/js.ml @@ -749,7 +749,9 @@ let rec of_definition def = let of_wrapper env x_opt name wrap_action wrap_assertion at = let x = of_inst_opt env x_opt in let bs = wrap name wrap_action wrap_assertion at in - "call(instance(module(" ^ of_bytes bs ^ "), " ^ + let source_str_as_arg = ", \"(wrapper)\"" in(*", \"" ^ Filename.basename ass.at.left.file ^ + ":" ^ string_of_int ass.at.left.line ^ "\"" in *) + "call(instance(module(" ^ of_bytes bs ^ source_str_as_arg ^ "), " ^ "exports(" ^ x ^ ")), " ^ " \"run\", [])" let of_action env act = @@ -775,9 +777,9 @@ let of_action env act = | _ -> None ) -let of_assertion' env act name args wrapper_opt = +let of_assertion' env act source name args wrapper_opt = let act_js, act_wrapper_opt = of_action env act in - let js = name ^ "(() => " ^ act_js ^ String.concat ", " ("" :: args) ^ ")" in + let js = name ^ "(() => " ^ act_js ^ source ^ String.concat ", " ("" :: args) ^ ")" in match act_wrapper_opt with | None -> js ^ ";" | Some (act_wrapper, out) -> @@ -785,35 +787,41 @@ let of_assertion' env act name args wrapper_opt = match wrapper_opt with | None -> name, run | Some wrapper -> "run", wrapper - in run_name ^ "(() => " ^ act_wrapper (wrapper out) act.at ^ "); // " ^ js + in run_name ^ "(() => " ^ act_wrapper (wrapper out) act.at ^ source ^ "); // " ^ js let of_assertion env ass = + let source_str = Filename.basename ass.at.left.file ^ + ":" ^ string_of_int ass.at.left.line in + let source_str_as_arg = ", \"" ^ source_str ^ "\"" in match ass.it with | AssertMalformed (def, _) -> - "assert_malformed(" ^ of_definition def ^ ");" + "assert_malformed(" ^ of_definition def ^ source_str_as_arg ^ ");" | AssertMalformedCustom (def, _) -> - "assert_malformed_custom(" ^ of_definition def ^ ");" + "assert_malformed_custom(" ^ of_definition def ^ source_str_as_arg ^ ");" | AssertInvalid (def, _) -> - "assert_invalid(" ^ of_definition def ^ ");" + "assert_invalid(" ^ of_definition def ^ source_str_as_arg ^ ");" | AssertInvalidCustom (def, _) -> - "assert_invalid_custom(" ^ of_definition def ^ ");" + "assert_invalid_custom(" ^ of_definition def ^ source_str_as_arg ^ ");" | AssertUnlinkable (x_opt, _) -> "assert_unlinkable(" ^ of_mod_opt env x_opt ^ ");" | AssertUninstantiable (x_opt, _) -> "assert_uninstantiable(" ^ of_mod_opt env x_opt ^ ");" | AssertReturn (act, ress) -> - of_assertion' env act "assert_return" (List.map of_result ress) + of_assertion' env act source_str_as_arg "assert_return" (List.map of_result ress) (Some (assert_return ress)) | AssertTrap (act, _) -> - of_assertion' env act "assert_trap" [] None + of_assertion' env act source_str_as_arg "assert_trap" [] None | AssertExhaustion (act, _) -> - of_assertion' env act "assert_exhaustion" [] None + of_assertion' env act source_str_as_arg "assert_exhaustion" [] None | AssertException act -> - of_assertion' env act "assert_exception" [] None + of_assertion' env act source_str_as_arg "assert_exception" [] None let of_command env cmd = - "\n// " ^ Filename.basename cmd.at.left.file ^ - ":" ^ string_of_int cmd.at.left.line ^ "\n" ^ + let source_str = Filename.basename cmd.at.left.file ^ + ":" ^ string_of_int cmd.at.left.line in + let source_str_quoted = "\"" ^ source_str ^ "\"" in + let source_str_as_arg = ", " ^ source_str in + "\n// " ^ source_str ^ "\n" ^ match cmd.it with | Module (x_opt, def) -> let rec unquote def = @@ -823,7 +831,7 @@ let of_command env cmd = | Quoted (_, s) -> unquote (snd (Parse.Module.parse_string ~offset:s.at s.it)) in bind_mod env x_opt (unquote def); - "let " ^ current_mod env ^ " = module(" ^ of_definition def ^ ");\n" ^ + "let " ^ current_mod env ^ " = module(" ^ of_definition def ^ ", " ^ source_str_quoted ^ ");\n" ^ (if x_opt = None then "" else "let " ^ of_mod_opt env x_opt ^ " = " ^ current_mod env ^ ";\n") | Instance (x1_opt, x2_opt) -> @@ -835,7 +843,7 @@ let of_command env cmd = | Register (name, x_opt) -> "register(" ^ of_name name ^ ", " ^ of_inst_opt env x_opt ^ ")\n" | Action act -> - of_assertion' env act "run" [] None ^ "\n" + of_assertion' env act source_str_as_arg "run" [] None ^ "\n" | Assertion ass -> of_assertion env ass ^ "\n" | Meta _ -> assert false diff --git a/test/harness/async_index.js b/test/harness/async_index.js index 8a01b21211..78e7ae6926 100644 --- a/test/harness/async_index.js +++ b/test/harness/async_index.js @@ -150,10 +150,11 @@ function binary(bytes) { /** * Returns a compiled module, or throws if there was an error at compilation. */ -function module(bytes, valid = true) { - const test = valid +function module(bytes, source, valid = true) { + let test = valid ? "Test that WebAssembly compilation succeeds" : "Test that WebAssembly compilation fails"; + test += ` (${source})`; const loc = new Error().stack.toString().replace("Error", ""); let buffer = binary(bytes); let validated = WebAssembly.validate(buffer); @@ -167,6 +168,7 @@ function module(bytes, valid = true) { uniqueTest(_ => { assert_true(valid, loc); }, test); + module.source = source; return module; }, error => { @@ -181,26 +183,27 @@ function module(bytes, valid = true) { return chain; } -function assert_invalid(bytes) { - module(bytes, EXPECT_INVALID); +function assert_invalid(bytes, source) { + module(bytes, source, EXPECT_INVALID); } const assert_malformed = assert_invalid; -function assert_invalid_custom(bytes) { - module(bytes); +function assert_invalid_custom(bytes, source) { + module(bytes, source); } const assert_malformed_custom = assert_invalid_custom; function instance(module, imports, valid = true) { - const test = valid + let test = valid ? "Test that WebAssembly instantiation succeeds" : "Test that WebAssembly instantiation fails"; const loc = new Error().stack.toString().replace("Error", ""); chain = Promise.all([module, imports, chain]) .then(values => { let imports = values[1] ? values[1] : registry; + test += ` (${values[0].source})`; return WebAssembly.instantiate(values[0], imports); }) .then( @@ -235,8 +238,8 @@ function call(instance, name, args) { }); } -function run(action) { - const test = "Run a WebAssembly test without special assertions"; +function run(action, source) { + const test = `Run a WebAssembly test without special assertions (${source})`; const loc = new Error().stack.toString().replace("Error", ""); chain = Promise.all([chain, action()]) .then( @@ -256,8 +259,8 @@ function run(action) { .catch(_ => {}); } -function assert_trap(action) { - const test = "Test that a WebAssembly code traps"; +function assert_trap(action, source) { + const test = `Test that a WebAssembly code traps (${source})`; const loc = new Error().stack.toString().replace("Error", ""); chain = Promise.all([chain, action()]) .then( @@ -279,8 +282,8 @@ function assert_trap(action) { .catch(_ => {}); } -function assert_return(action, ...expected) { - const test = "Test that a WebAssembly code returns a specific result"; +function assert_return(action, source, ...expected) { + const test = `Test that a WebAssembly code returns a specific result (${source})`; const loc = new Error().stack.toString().replace("Error", ""); chain = Promise.all([action(), chain]) .then( diff --git a/test/harness/sync_index.js b/test/harness/sync_index.js index 5c4549be2e..77f601f590 100644 --- a/test/harness/sync_index.js +++ b/test/harness/sync_index.js @@ -150,7 +150,7 @@ function binary(bytes) { /** * Returns a compiled module, or throws if there was an error at compilation. */ -function module(bytes, valid = true) { +function module(bytes, source, valid = true) { let buffer = binary(bytes); let validated; @@ -176,6 +176,7 @@ function module(bytes, valid = true) { let module; try { module = new WebAssembly.Module(buffer); + module.source = source; } catch(e) { if (valid) throw new Error('WebAssembly.Module ctor unexpectedly throws ${typeof e}: ${e}${e.stack}'); @@ -189,32 +190,32 @@ function uniqueTest(func, desc) { test(func, testNum() + desc); } -function assert_invalid(bytes) { +function assert_invalid(bytes, source) { uniqueTest(() => { try { - module(bytes, /* valid */ false); + module(bytes, source, /* valid */ false); throw new Error('did not fail'); } catch(e) { assert_true(e instanceof WebAssembly.CompileError, "expected invalid failure:"); } - }, "A wast module that should be invalid or malformed."); + }, `A wast module that should be invalid or malformed. (${source})`); } const assert_malformed = assert_invalid; -function assert_invalid_custom(bytes) { +function assert_invalid_custom(bytes, source) { uniqueTest(() => { try { - module(bytes, /* valid */ true); + module(bytes, source, /* valid */ true); } catch(e) { throw new Error('failed on custom section error'); } - }, "A wast module that should have an invalid or malformed custom section."); + }, `A wast module that should have an invalid or malformed custom section. (${source})`); } const assert_malformed_custom = assert_invalid_custom; -function instance(mod, imports = registry, valid = true) { +function instance(module, imports = registry, valid = true) { if (imports instanceof Result) { if (imports.isError()) return imports; @@ -225,7 +226,7 @@ function instance(mod, imports = registry, valid = true) { let i; try { - i = new WebAssembly.Instance(mod, imports); + i = new WebAssembly.Instance(module, imports); } catch(e) { err = e; } @@ -234,7 +235,7 @@ function instance(mod, imports = registry, valid = true) { uniqueTest(() => { let instantiated = err === null; assert_true(instantiated, err); - }, "module successfully instantiated"); + }, `module successfully instantiated (${module.source})`); } return err !== null ? ErrorResult(err) : ValueResult(i); @@ -285,7 +286,7 @@ function exports(instance) { return ValueResult({ module: instance.value.exports, spectest: registry.spectest }); } -function run(action) { +function run(action, source) { let result = action(); _assert(result instanceof Result); @@ -293,7 +294,7 @@ function run(action) { uniqueTest(() => { if (result.isError()) throw result.value; - }, "A wast test that runs without any special assertion."); + }, `A wast test that runs without any special assertion. (${source})`); } function assert_unlinkable(bytes) { @@ -324,7 +325,7 @@ function assert_uninstantiable(bytes) { }, "A wast module that is uninstantiable."); } -function assert_trap(action) { +function assert_trap(action, source) { let result = action(); _assert(result instanceof Result); @@ -335,7 +336,7 @@ function assert_trap(action) { let e = result.value; assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`); } - }, "A wast module that must trap at runtime."); + }, `A wast module that must trap at runtime. (${source})`); } let StackOverflow; @@ -355,7 +356,7 @@ function assert_exhaustion(action) { }, "A wast module that must exhaust the stack space."); } -function assert_return(action, ...expected) { +function assert_return(action, source, ...expected) { let result = action(); _assert(result instanceof Result); @@ -408,7 +409,7 @@ function assert_return(action, ...expected) { assert_equals(actual[i], expected[i]); } } - }, "A wast module that must return a particular value."); + }, `A wast module that must return a particular value. (${source})`); } function assert_return_nan(action) { From d5eb116911da634ee2ffb375351dc8a4623a98d2 Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Sat, 14 Jun 2025 00:59:25 +0000 Subject: [PATCH 2/4] update builtin template --- interpreter/script/js.ml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/interpreter/script/js.ml b/interpreter/script/js.ml index 24159ffe38..4e34964e88 100644 --- a/interpreter/script/js.ml +++ b/interpreter/script/js.ml @@ -53,7 +53,7 @@ function register(name, instance) { registry[name] = instance.exports; } -function module(bytes, valid = true) { +function module(bytes, source, valid = true) { let buffer = new ArrayBuffer(bytes.length); let view = new Uint8Array(buffer); for (let i = 0; i < bytes.length; ++i) { @@ -92,8 +92,8 @@ function run(action) { action(); } -function assert_malformed(bytes) { - try { module(bytes, false) } catch (e) { +function assert_malformed(bytes, source) { + try { module(bytes, source, false) } catch (e) { if (e instanceof WebAssembly.CompileError) return; } throw new Error("Wasm decoding failure expected"); @@ -103,8 +103,8 @@ function assert_malformed_custom(bytes) { return; } -function assert_invalid(bytes) { - try { module(bytes, false) } catch (e) { +function assert_invalid(bytes, source) { + try { module(bytes, source, false) } catch (e) { if (e instanceof WebAssembly.CompileError) return; } throw new Error("Wasm validation failure expected"); @@ -128,7 +128,7 @@ function assert_uninstantiable(mod) { throw new Error("Wasm trap expected"); } -function assert_trap(action) { +function assert_trap(action, source) { try { action() } catch (e) { if (e instanceof WebAssembly.RuntimeError) return; } @@ -150,7 +150,7 @@ function assert_exhaustion(action) { throw new Error("Wasm resource exhaustion expected"); } -function assert_return(action, ...expected) { +function assert_return(action, source, ...expected) { let actual = action(); if (actual === undefined) { actual = []; @@ -820,7 +820,7 @@ let of_command env cmd = let source_str = Filename.basename cmd.at.left.file ^ ":" ^ string_of_int cmd.at.left.line in let source_str_quoted = "\"" ^ source_str ^ "\"" in - let source_str_as_arg = ", " ^ source_str in + let source_str_as_arg = ", " ^ source_str_quoted in "\n// " ^ source_str ^ "\n" ^ match cmd.it with | Module (x_opt, def) -> From c88cfb3fe062933c54dd92b8344d16e6e39625ab Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Sat, 14 Jun 2025 01:19:40 +0000 Subject: [PATCH 3/4] clean up --- interpreter/script/js.ml | 35 ++++++++++++++++------------------- test/harness/async_index.js | 7 +++---- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/interpreter/script/js.ml b/interpreter/script/js.ml index 4e34964e88..a9c54d18b1 100644 --- a/interpreter/script/js.ml +++ b/interpreter/script/js.ml @@ -749,9 +749,7 @@ let rec of_definition def = let of_wrapper env x_opt name wrap_action wrap_assertion at = let x = of_inst_opt env x_opt in let bs = wrap name wrap_action wrap_assertion at in - let source_str_as_arg = ", \"(wrapper)\"" in(*", \"" ^ Filename.basename ass.at.left.file ^ - ":" ^ string_of_int ass.at.left.line ^ "\"" in *) - "call(instance(module(" ^ of_bytes bs ^ source_str_as_arg ^ "), " ^ + "call(instance(module(" ^ of_bytes bs ^ ", \"wrapper\"), " ^ "exports(" ^ x ^ ")), " ^ " \"run\", [])" let of_action env act = @@ -790,38 +788,37 @@ let of_assertion' env act source name args wrapper_opt = in run_name ^ "(() => " ^ act_wrapper (wrapper out) act.at ^ source ^ "); // " ^ js let of_assertion env ass = - let source_str = Filename.basename ass.at.left.file ^ + let source = Filename.basename ass.at.left.file ^ ":" ^ string_of_int ass.at.left.line in - let source_str_as_arg = ", \"" ^ source_str ^ "\"" in + let source_as_arg = ", \"" ^ source ^ "\"" in match ass.it with | AssertMalformed (def, _) -> - "assert_malformed(" ^ of_definition def ^ source_str_as_arg ^ ");" + "assert_malformed(" ^ of_definition def ^ source_as_arg ^ ");" | AssertMalformedCustom (def, _) -> - "assert_malformed_custom(" ^ of_definition def ^ source_str_as_arg ^ ");" + "assert_malformed_custom(" ^ of_definition def ^ source_as_arg ^ ");" | AssertInvalid (def, _) -> - "assert_invalid(" ^ of_definition def ^ source_str_as_arg ^ ");" + "assert_invalid(" ^ of_definition def ^ source_as_arg ^ ");" | AssertInvalidCustom (def, _) -> - "assert_invalid_custom(" ^ of_definition def ^ source_str_as_arg ^ ");" + "assert_invalid_custom(" ^ of_definition def ^ source_as_arg ^ ");" | AssertUnlinkable (x_opt, _) -> "assert_unlinkable(" ^ of_mod_opt env x_opt ^ ");" | AssertUninstantiable (x_opt, _) -> "assert_uninstantiable(" ^ of_mod_opt env x_opt ^ ");" | AssertReturn (act, ress) -> - of_assertion' env act source_str_as_arg "assert_return" (List.map of_result ress) + of_assertion' env act source_as_arg "assert_return" (List.map of_result ress) (Some (assert_return ress)) | AssertTrap (act, _) -> - of_assertion' env act source_str_as_arg "assert_trap" [] None + of_assertion' env act source_as_arg "assert_trap" [] None | AssertExhaustion (act, _) -> - of_assertion' env act source_str_as_arg "assert_exhaustion" [] None + of_assertion' env act source_as_arg "assert_exhaustion" [] None | AssertException act -> - of_assertion' env act source_str_as_arg "assert_exception" [] None + of_assertion' env act source_as_arg "assert_exception" [] None let of_command env cmd = - let source_str = Filename.basename cmd.at.left.file ^ + let source = Filename.basename cmd.at.left.file ^ ":" ^ string_of_int cmd.at.left.line in - let source_str_quoted = "\"" ^ source_str ^ "\"" in - let source_str_as_arg = ", " ^ source_str_quoted in - "\n// " ^ source_str ^ "\n" ^ + let source_as_arg = ", \"" ^ source ^ "\"" in + "\n// " ^ source ^ "\n" ^ match cmd.it with | Module (x_opt, def) -> let rec unquote def = @@ -831,7 +828,7 @@ let of_command env cmd = | Quoted (_, s) -> unquote (snd (Parse.Module.parse_string ~offset:s.at s.it)) in bind_mod env x_opt (unquote def); - "let " ^ current_mod env ^ " = module(" ^ of_definition def ^ ", " ^ source_str_quoted ^ ");\n" ^ + "let " ^ current_mod env ^ " = module(" ^ of_definition def ^ source_as_arg ^ ");\n" ^ (if x_opt = None then "" else "let " ^ of_mod_opt env x_opt ^ " = " ^ current_mod env ^ ";\n") | Instance (x1_opt, x2_opt) -> @@ -843,7 +840,7 @@ let of_command env cmd = | Register (name, x_opt) -> "register(" ^ of_name name ^ ", " ^ of_inst_opt env x_opt ^ ")\n" | Action act -> - of_assertion' env act source_str_as_arg "run" [] None ^ "\n" + of_assertion' env act source_as_arg "run" [] None ^ "\n" | Assertion ass -> of_assertion env ass ^ "\n" | Meta _ -> assert false diff --git a/test/harness/async_index.js b/test/harness/async_index.js index 78e7ae6926..7b4fcd1ae4 100644 --- a/test/harness/async_index.js +++ b/test/harness/async_index.js @@ -151,10 +151,9 @@ function binary(bytes) { * Returns a compiled module, or throws if there was an error at compilation. */ function module(bytes, source, valid = true) { - let test = valid - ? "Test that WebAssembly compilation succeeds" - : "Test that WebAssembly compilation fails"; - test += ` (${source})`; + const test = `${ valid ? "Test that WebAssembly compilation succeeds" : + "Test that WebAssembly compilation fails"} (${source})`; + const loc = new Error().stack.toString().replace("Error", ""); let buffer = binary(bytes); let validated = WebAssembly.validate(buffer); From 971324a421d2b1b48dd0c05f465ead724d71eb78 Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Mon, 16 Jun 2025 21:53:30 +0000 Subject: [PATCH 4/4] review comments --- interpreter/script/js.ml | 52 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/interpreter/script/js.ml b/interpreter/script/js.ml index a9c54d18b1..b0be4384b1 100644 --- a/interpreter/script/js.ml +++ b/interpreter/script/js.ml @@ -53,7 +53,7 @@ function register(name, instance) { registry[name] = instance.exports; } -function module(bytes, source, valid = true) { +function module(bytes, loc, valid = true) { let buffer = new ArrayBuffer(bytes.length); let view = new Uint8Array(buffer); for (let i = 0; i < bytes.length; ++i) { @@ -92,8 +92,8 @@ function run(action) { action(); } -function assert_malformed(bytes, source) { - try { module(bytes, source, false) } catch (e) { +function assert_malformed(bytes, loc) { + try { module(bytes, loc, false) } catch (e) { if (e instanceof WebAssembly.CompileError) return; } throw new Error("Wasm decoding failure expected"); @@ -103,8 +103,8 @@ function assert_malformed_custom(bytes) { return; } -function assert_invalid(bytes, source) { - try { module(bytes, source, false) } catch (e) { +function assert_invalid(bytes, loc) { + try { module(bytes, loc, false) } catch (e) { if (e instanceof WebAssembly.CompileError) return; } throw new Error("Wasm validation failure expected"); @@ -128,7 +128,7 @@ function assert_uninstantiable(mod) { throw new Error("Wasm trap expected"); } -function assert_trap(action, source) { +function assert_trap(action, loc) { try { action() } catch (e) { if (e instanceof WebAssembly.RuntimeError) return; } @@ -150,7 +150,7 @@ function assert_exhaustion(action) { throw new Error("Wasm resource exhaustion expected"); } -function assert_return(action, source, ...expected) { +function assert_return(action, loc, ...expected) { let actual = action(); if (actual === undefined) { actual = []; @@ -775,9 +775,9 @@ let of_action env act = | _ -> None ) -let of_assertion' env act source name args wrapper_opt = +let of_assertion' env act loc name args wrapper_opt = let act_js, act_wrapper_opt = of_action env act in - let js = name ^ "(() => " ^ act_js ^ source ^ String.concat ", " ("" :: args) ^ ")" in + let js = name ^ "(() => " ^ act_js ^ loc ^ String.concat ", " ("" :: args) ^ ")" in match act_wrapper_opt with | None -> js ^ ";" | Some (act_wrapper, out) -> @@ -785,40 +785,40 @@ let of_assertion' env act source name args wrapper_opt = match wrapper_opt with | None -> name, run | Some wrapper -> "run", wrapper - in run_name ^ "(() => " ^ act_wrapper (wrapper out) act.at ^ source ^ "); // " ^ js + in run_name ^ "(() => " ^ act_wrapper (wrapper out) act.at ^ loc ^ "); // " ^ js let of_assertion env ass = - let source = Filename.basename ass.at.left.file ^ + let loc = Filename.basename ass.at.left.file ^ ":" ^ string_of_int ass.at.left.line in - let source_as_arg = ", \"" ^ source ^ "\"" in + let loc_as_arg = ", \"" ^ String.escaped loc ^ "\"" in match ass.it with | AssertMalformed (def, _) -> - "assert_malformed(" ^ of_definition def ^ source_as_arg ^ ");" + "assert_malformed(" ^ of_definition def ^ loc_as_arg ^ ");" | AssertMalformedCustom (def, _) -> - "assert_malformed_custom(" ^ of_definition def ^ source_as_arg ^ ");" + "assert_malformed_custom(" ^ of_definition def ^ loc_as_arg ^ ");" | AssertInvalid (def, _) -> - "assert_invalid(" ^ of_definition def ^ source_as_arg ^ ");" + "assert_invalid(" ^ of_definition def ^ loc_as_arg ^ ");" | AssertInvalidCustom (def, _) -> - "assert_invalid_custom(" ^ of_definition def ^ source_as_arg ^ ");" + "assert_invalid_custom(" ^ of_definition def ^ loc_as_arg ^ ");" | AssertUnlinkable (x_opt, _) -> "assert_unlinkable(" ^ of_mod_opt env x_opt ^ ");" | AssertUninstantiable (x_opt, _) -> "assert_uninstantiable(" ^ of_mod_opt env x_opt ^ ");" | AssertReturn (act, ress) -> - of_assertion' env act source_as_arg "assert_return" (List.map of_result ress) + of_assertion' env act loc_as_arg "assert_return" (List.map of_result ress) (Some (assert_return ress)) | AssertTrap (act, _) -> - of_assertion' env act source_as_arg "assert_trap" [] None + of_assertion' env act loc_as_arg "assert_trap" [] None | AssertExhaustion (act, _) -> - of_assertion' env act source_as_arg "assert_exhaustion" [] None + of_assertion' env act loc_as_arg "assert_exhaustion" [] None | AssertException act -> - of_assertion' env act source_as_arg "assert_exception" [] None + of_assertion' env act loc_as_arg "assert_exception" [] None let of_command env cmd = - let source = Filename.basename cmd.at.left.file ^ - ":" ^ string_of_int cmd.at.left.line in - let source_as_arg = ", \"" ^ source ^ "\"" in - "\n// " ^ source ^ "\n" ^ + let loc = String.escaped (Filename.basename cmd.at.left.file ^ + ":" ^ string_of_int cmd.at.left.line) in + let loc_as_arg = ", \"" ^ loc ^ "\"" in + "\n// " ^ loc ^ "\n" ^ match cmd.it with | Module (x_opt, def) -> let rec unquote def = @@ -828,7 +828,7 @@ let of_command env cmd = | Quoted (_, s) -> unquote (snd (Parse.Module.parse_string ~offset:s.at s.it)) in bind_mod env x_opt (unquote def); - "let " ^ current_mod env ^ " = module(" ^ of_definition def ^ source_as_arg ^ ");\n" ^ + "let " ^ current_mod env ^ " = module(" ^ of_definition def ^ loc_as_arg ^ ");\n" ^ (if x_opt = None then "" else "let " ^ of_mod_opt env x_opt ^ " = " ^ current_mod env ^ ";\n") | Instance (x1_opt, x2_opt) -> @@ -840,7 +840,7 @@ let of_command env cmd = | Register (name, x_opt) -> "register(" ^ of_name name ^ ", " ^ of_inst_opt env x_opt ^ ")\n" | Action act -> - of_assertion' env act source_as_arg "run" [] None ^ "\n" + of_assertion' env act loc_as_arg "run" [] None ^ "\n" | Assertion ass -> of_assertion env ass ^ "\n" | Meta _ -> assert false