diff --git a/common.gypi b/common.gypi index dbd6bf9df814f8..c0a3d785a3dab3 100644 --- a/common.gypi +++ b/common.gypi @@ -40,7 +40,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.19', + 'v8_embedder_string': '-node.20', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/codegen/external-reference.h b/deps/v8/src/codegen/external-reference.h index eecaf7928c18b5..25121bcc2fc990 100644 --- a/deps/v8/src/codegen/external-reference.h +++ b/deps/v8/src/codegen/external-reference.h @@ -375,6 +375,8 @@ enum class IsolateFieldId : uint8_t; IF_WASM(V, wasm_WebAssemblyExceptionGetArg, \ "wasm::WebAssemblyExceptionGetArg") \ IF_WASM(V, wasm_WebAssemblyExceptionIs, "wasm::WebAssemblyExceptionIs") \ + IF_WASM(V, wasm_WebAssemblyExceptionGetStack, \ + "wasm::WebAssemblyExceptionGetStack") \ IF_WASM(V, wasm_WebAssemblyGlobal, "wasm::WebAssemblyGlobal") \ IF_WASM(V, wasm_WebAssemblyGlobalGetValue, \ "wasm::WebAssemblyGlobalGetValue") \ diff --git a/deps/v8/src/wasm/wasm-js.cc b/deps/v8/src/wasm/wasm-js.cc index 32c39a55c418c9..d8866284523f07 100644 --- a/deps/v8/src/wasm/wasm-js.cc +++ b/deps/v8/src/wasm/wasm-js.cc @@ -3119,6 +3119,15 @@ void WebAssemblyExceptionIsImpl( info.GetReturnValue().Set(tag_object->tag() == *tag); } +void WebAssemblyExceptionGetStackImpl( + const v8::FunctionCallbackInfo& info) { + WasmJSApiScope js_api_scope{info, "WebAssembly.Exception.stack()"}; + auto [isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower(); + EXTRACT_THIS(exception, WasmExceptionPackage); + + info.GetReturnValue().Set(v8::Undefined(isolate)); +} + void WebAssemblyGlobalGetValueCommon(WasmJSApiScope& js_api_scope) { auto [isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower(); auto& info = js_api_scope.callback_info(); // Needed by EXTRACT_THIS. @@ -3562,6 +3571,7 @@ void WasmJs::PrepareForSnapshot(Isolate* isolate) { { DirectHandle exception_constructor = InstallConstructorFunc( isolate, webassembly, "Exception", wasm::WebAssemblyException); + exception_constructor->shared()->set_length(2); SetDummyInstanceTemplate(isolate, exception_constructor); DirectHandle exception_proto = SetupConstructor( isolate, exception_constructor, WASM_EXCEPTION_PACKAGE_TYPE, @@ -3571,6 +3581,8 @@ void WasmJs::PrepareForSnapshot(Isolate* isolate) { wasm::WebAssemblyExceptionGetArg, 2); InstallFunc(isolate, exception_proto, "is", wasm::WebAssemblyExceptionIs, 1); + InstallGetter(isolate, exception_proto, "stack", + wasm::WebAssemblyExceptionGetStack); native_context->set_wasm_exception_constructor(*exception_constructor); DirectHandle initial_map(exception_constructor->initial_map(), diff --git a/deps/v8/src/wasm/wasm-js.h b/deps/v8/src/wasm/wasm-js.h index 3477abf1c4e809..901ba8c342af14 100644 --- a/deps/v8/src/wasm/wasm-js.h +++ b/deps/v8/src/wasm/wasm-js.h @@ -34,6 +34,7 @@ V8_EXPORT_PRIVATE std::unique_ptr StartStreamingForTesting( V(WebAssemblyCompile) \ V(WebAssemblyException) \ V(WebAssemblyExceptionGetArg) \ + V(WebAssemblyExceptionGetStack) \ V(WebAssemblyExceptionIs) \ V(WebAssemblyGlobal) \ V(WebAssemblyGlobalGetValue) \ diff --git a/deps/v8/test/mjsunit/wasm/exceptions-api.js b/deps/v8/test/mjsunit/wasm/exceptions-api.js index 25ba9c7e80ec27..9ceb2d506dfcbf 100644 --- a/deps/v8/test/mjsunit/wasm/exceptions-api.js +++ b/deps/v8/test/mjsunit/wasm/exceptions-api.js @@ -106,13 +106,19 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); print(arguments.callee.name); let tag = new WebAssembly.Tag({parameters: []}); let exn = new WebAssembly.Exception(tag, []); + assertTrue('stack' in exn); assertEquals(undefined, exn.stack); exn = new WebAssembly.Exception(tag, [], {traceStack: false}); + assertTrue('stack' in exn); assertEquals(undefined, exn.stack); exn = new WebAssembly.Exception(tag, [], {traceStack: true}); assertTrue(exn.stack.indexOf(arguments.callee.name) > 0); assertThrows(() => new WebAssembly.Exception(tag, [], 0), TypeError, /Argument 2 is not an object/); + // The stack getter may only be used with a receiver that is a + // WebAssembly.Exception. + let proto = WebAssembly.Exception.prototype; + assertThrows(() => proto.stack, TypeError); })(); (function TestCatchJSException() { @@ -319,3 +325,7 @@ function TestGetArgHelper(types_str, types, values) { // Don't catch with implicit wrapping. assertThrowsEquals(() => instance.exports.test(obj), obj); })(); + +(function TestExceptionConstructorLength() { + assertEquals(2, WebAssembly.Exception.length); +})(); diff --git a/deps/v8/test/wasm-js/wasm-js.status b/deps/v8/test/wasm-js/wasm-js.status index ec3d4289eba09a..c44b0d6dd2059c 100644 --- a/deps/v8/test/wasm-js/wasm-js.status +++ b/deps/v8/test/wasm-js/wasm-js.status @@ -42,6 +42,10 @@ 'wpt/table/type.tentative': [FAIL], 'wpt/tag/type.tentative': [FAIL], + # TODO(mliedtke): This requires synchronizing the spec-tests with their newest version. + 'wpt/exception/constructor.tentative': [FAIL], + 'exception/constructor.tentative': [FAIL], + # Broken test (forgot to define JS function 'nulls()'). 'table/grow-memory64': [FAIL], diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md index ebbffd5e53fe3b..6df926e09022b6 100644 --- a/test/fixtures/wpt/README.md +++ b/test/fixtures/wpt/README.md @@ -31,7 +31,7 @@ Last update: - url: https://github.com/web-platform-tests/wpt/tree/258f285de0/url - urlpattern: https://github.com/web-platform-tests/wpt/tree/f07c03cbed/urlpattern - user-timing: https://github.com/web-platform-tests/wpt/tree/5ae85bf826/user-timing -- wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/65a2134d50/wasm/jsapi +- wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/288c467d35/wasm/jsapi - wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi - web-locks: https://github.com/web-platform-tests/wpt/tree/10a122a6bc/web-locks - WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/2cb332d710/WebCryptoAPI diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index e3c707ac35cc28..99a68e512ead83 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -84,7 +84,7 @@ "path": "user-timing" }, "wasm/jsapi": { - "commit": "65a2134d50", + "commit": "288c467d350ec4b8e4fbc7f2ccb6119293186611", "path": "wasm/jsapi" }, "wasm/webapi": { diff --git a/test/fixtures/wpt/wasm/jsapi/esm-integration/resources/js-string-constants.wasm b/test/fixtures/wpt/wasm/jsapi/esm-integration/resources/js-string-constants.wasm new file mode 100644 index 00000000000000..4ba2d9e7c5811f Binary files /dev/null and b/test/fixtures/wpt/wasm/jsapi/esm-integration/resources/js-string-constants.wasm differ diff --git a/test/fixtures/wpt/wasm/jsapi/esm-integration/resources/js-string-constants.wat b/test/fixtures/wpt/wasm/jsapi/esm-integration/resources/js-string-constants.wat new file mode 100644 index 00000000000000..2de58bc19cdf12 --- /dev/null +++ b/test/fixtures/wpt/wasm/jsapi/esm-integration/resources/js-string-constants.wat @@ -0,0 +1,11 @@ +(module + (import "wasm:js/string-constants" "" (global $empty externref)) + (import "wasm:js/string-constants" "\00" (global $null_byte externref)) + (import "wasm:js/string-constants" "hello" (global $hello externref)) + (import "wasm:js/string-constants" "\f0\9f\98\80" (global $emoji externref)) + + (export "empty" (global $empty)) + (export "nullByte" (global $null_byte)) + (export "hello" (global $hello)) + (export "emoji" (global $emoji)) +) diff --git a/test/fixtures/wpt/wasm/jsapi/esm-integration/source-phase-string-builtins.tentative.any.js b/test/fixtures/wpt/wasm/jsapi/esm-integration/source-phase-string-builtins.tentative.any.js index e79b457dd464fc..bedb4d5b6a58bd 100644 --- a/test/fixtures/wpt/wasm/jsapi/esm-integration/source-phase-string-builtins.tentative.any.js +++ b/test/fixtures/wpt/wasm/jsapi/esm-integration/source-phase-string-builtins.tentative.any.js @@ -37,3 +37,4 @@ promise_test(async () => { assert_equals(imports.length, 0); }, "Source phase import should handle string builtin import reflection correctly"); + diff --git a/test/fixtures/wpt/wasm/jsapi/esm-integration/source-phase-string-constants.tentative.any.js b/test/fixtures/wpt/wasm/jsapi/esm-integration/source-phase-string-constants.tentative.any.js new file mode 100644 index 00000000000000..66ee89c5394281 --- /dev/null +++ b/test/fixtures/wpt/wasm/jsapi/esm-integration/source-phase-string-constants.tentative.any.js @@ -0,0 +1,32 @@ +// META: global=window,dedicatedworker,jsshell,shadowrealm + +promise_test(async () => { + const wasmModuleSource = await import.source("./resources/js-string-constants.wasm"); + + const instance = new WebAssembly.Instance(wasmModuleSource, {}); + + assert_equals(instance.exports.empty.value, ""); + assert_equals(instance.exports.nullByte.value, "\0"); + assert_equals(instance.exports.hello.value, "hello"); + assert_equals(instance.exports.emoji.value, "\u{1F600}"); +}, "String constants from wasm:js/string-constants should be supported in source phase imports"); + +promise_test(async () => { + const wasmModuleSource = await import.source("./resources/js-string-constants.wasm"); + + const exports = WebAssembly.Module.exports(wasmModuleSource); + const exportNames = exports.map((exp) => exp.name); + + assert_true(exportNames.includes("empty")); + assert_true(exportNames.includes("nullByte")); + assert_true(exportNames.includes("hello")); + assert_true(exportNames.includes("emoji")); +}, "Source phase import should properly expose string constants exports"); + +promise_test(async () => { + const wasmModuleSource = await import.source("./resources/js-string-constants.wasm"); + + const imports = WebAssembly.Module.imports(wasmModuleSource); + + assert_equals(imports.length, 0); +}, "Source phase import should handle string constants import reflection correctly"); diff --git a/test/fixtures/wpt/wasm/jsapi/esm-integration/string-builtins.tentative.any.js b/test/fixtures/wpt/wasm/jsapi/esm-integration/string-builtins.tentative.any.js index bac8fd92727437..f291c4ff53c453 100644 --- a/test/fixtures/wpt/wasm/jsapi/esm-integration/string-builtins.tentative.any.js +++ b/test/fixtures/wpt/wasm/jsapi/esm-integration/string-builtins.tentative.any.js @@ -10,3 +10,4 @@ promise_test(async () => { assert_equals(wasmModule.testString("hello"), 1); assert_equals(wasmModule.testString(42), 0); }, "String builtins should be supported in imports in ESM integration"); + diff --git a/test/fixtures/wpt/wasm/jsapi/esm-integration/string-constants.tentative.any.js b/test/fixtures/wpt/wasm/jsapi/esm-integration/string-constants.tentative.any.js new file mode 100644 index 00000000000000..8166bb4f721726 --- /dev/null +++ b/test/fixtures/wpt/wasm/jsapi/esm-integration/string-constants.tentative.any.js @@ -0,0 +1,10 @@ +// META: global=window,dedicatedworker,jsshell,shadowrealm + +promise_test(async () => { + const wasmModule = await import("./resources/js-string-constants.wasm"); + + assert_equals(wasmModule.empty, ""); + assert_equals(wasmModule.nullByte, "\0"); + assert_equals(wasmModule.hello, "hello"); + assert_equals(wasmModule.emoji, "\u{1F600}"); +}, "String constants from wasm:js/string-constants should be supported in ESM integration"); diff --git a/test/fixtures/wpt/wasm/jsapi/exception/basic.tentative.any.js b/test/fixtures/wpt/wasm/jsapi/exception/basic.tentative.any.js index 1b690ec463b36a..7bd8d3ff63ee79 100644 --- a/test/fixtures/wpt/wasm/jsapi/exception/basic.tentative.any.js +++ b/test/fixtures/wpt/wasm/jsapi/exception/basic.tentative.any.js @@ -4,7 +4,7 @@ function assert_throws_wasm(fn, message) { try { fn(); - assert_not_reached(`expected to throw with ${message}`); + assert_unreached(`expected to throw with ${message}`); } catch (e) { assert_true(e instanceof WebAssembly.Exception, `Error should be a WebAssembly.Exception with ${message}`); // According to the spec discussion, the current `WebAssembly.Exception` does not have `[[ErrorData]]` semantically. diff --git a/test/fixtures/wpt/wasm/jsapi/exception/constructor.tentative.any.js b/test/fixtures/wpt/wasm/jsapi/exception/constructor.tentative.any.js index a46d1816c351d2..a84218cb9ccb46 100644 --- a/test/fixtures/wpt/wasm/jsapi/exception/constructor.tentative.any.js +++ b/test/fixtures/wpt/wasm/jsapi/exception/constructor.tentative.any.js @@ -10,7 +10,7 @@ test(() => { }, "name"); test(() => { - assert_function_length(WebAssembly.Exception, 1, "WebAssembly.Exception"); + assert_function_length(WebAssembly.Exception, 2, "WebAssembly.Exception"); }, "length"); test(() => { diff --git a/test/fixtures/wpt/wasm/jsapi/js-string/basic.any.js b/test/fixtures/wpt/wasm/jsapi/js-string/basic.any.js index 174bab32eb171b..6b6dd04e0dec61 100644 --- a/test/fixtures/wpt/wasm/jsapi/js-string/basic.any.js +++ b/test/fixtures/wpt/wasm/jsapi/js-string/basic.any.js @@ -277,6 +277,19 @@ test(() => { a, a ), a !== null && !isString, WebAssembly.RuntimeError); + if (a !== null && !isString) { + assert_throws_if(() => assert_same_behavior( + builtinExports['equals'], + polyfillExports['equals'], + null, a + ), true, WebAssembly.RuntimeError); + assert_throws_if(() => assert_same_behavior( + builtinExports['equals'], + polyfillExports['equals'], + a, null + ), true, WebAssembly.RuntimeError); + } + assert_throws_if(() => assert_same_behavior( builtinExports['compare'], polyfillExports['compare'], diff --git a/test/fixtures/wpt/wasm/jsapi/module/moduleSource.tentative.any.js b/test/fixtures/wpt/wasm/jsapi/module/moduleSource.tentative.any.js index 8a94cdd48cd497..4652392aa7c128 100644 --- a/test/fixtures/wpt/wasm/jsapi/module/moduleSource.tentative.any.js +++ b/test/fixtures/wpt/wasm/jsapi/module/moduleSource.tentative.any.js @@ -31,5 +31,5 @@ test(() => { const toStringTag = Object.getOwnPropertyDescriptor(AbstractModuleSource.prototype, Symbol.toStringTag).get; assert_equals(toStringTag.call(module), "WebAssembly.Module"); - assert_throws_js(TypeError, () => toStringTag.call({})); + assert_equals(toStringTag.call({}), undefined); }, "AbstractModuleSourceProto toStringTag brand check"); \ No newline at end of file diff --git a/test/wpt/status/wasm/jsapi.json b/test/wpt/status/wasm/jsapi.json index b2d95388fea39a..6f2bf9f83a9c88 100644 --- a/test/wpt/status/wasm/jsapi.json +++ b/test/wpt/status/wasm/jsapi.json @@ -15,13 +15,6 @@ ] } }, - "module/moduleSource.tentative.any.js": { - "fail": { - "expected": [ - "AbstractModuleSourceProto toStringTag brand check" - ] - } - }, "exception/getArg.tentative.any.js": { "skip": "track - still tentative / unsupported" },