| <!DOCTYPE html> |
| <meta charset="utf-8"> |
| <title>WebAssembly JS API: Default [[Prototype]] value is from NewTarget's Realm</title> |
| <link rel="help" href="https://heycam.github.io/webidl/#internally-create-a-new-object-implementing-the-interface"> |
| <link rel="help" href="https://tc39.es/ecma262/#sec-nativeerror"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="wasm-module-builder.js"></script> |
| <body> |
| <iframe id="constructor-iframe" hidden></iframe> |
| <iframe id="new-target-iframe" hidden></iframe> |
| <iframe id="other-iframe" hidden></iframe> |
| <script> |
| "use strict"; |
| |
| const constructorRealm = document.querySelector("#constructor-iframe").contentWindow; |
| const newTargetRealm = document.querySelector("#new-target-iframe").contentWindow; |
| const otherRealm = document.querySelector("#other-iframe").contentWindow; |
| |
| const emptyModuleBinary = new WasmModuleBuilder().toBuffer(); |
| const interfaces = [ |
| ["Module", emptyModuleBinary], |
| ["Instance", new WebAssembly.Module(emptyModuleBinary)], |
| ["Memory", {initial: 0}], |
| ["Table", {element: "anyfunc", initial: 0}], |
| ["Global", {value: "i32"}], |
| |
| // See step 2 of https://tc39.es/ecma262/#sec-nativeerror |
| ["CompileError"], |
| ["LinkError"], |
| ["RuntimeError"], |
| ]; |
| |
| const primitives = [ |
| undefined, |
| null, |
| false, |
| true, |
| 0, |
| -1, |
| "", |
| "str", |
| Symbol(), |
| ]; |
| |
| const getNewTargets = function* (realm) { |
| for (const primitive of primitives) { |
| const newTarget = new realm.Function(); |
| newTarget.prototype = primitive; |
| yield [newTarget, "cross-realm NewTarget with `" + format_value(primitive) + "` prototype"]; |
| } |
| |
| // GetFunctionRealm (https://tc39.es/ecma262/#sec-getfunctionrealm) coverage: |
| const bindOther = otherRealm.Function.prototype.bind; |
| const ProxyOther = otherRealm.Proxy; |
| |
| const bound = new realm.Function(); |
| bound.prototype = undefined; |
| yield [bindOther.call(bound), "bound cross-realm NewTarget with `undefined` prototype"]; |
| |
| const boundBound = new realm.Function(); |
| boundBound.prototype = null; |
| yield [bindOther.call(bindOther.call(boundBound)), "bound bound cross-realm NewTarget with `null` prototype"]; |
| |
| const boundProxy = new realm.Function(); |
| boundProxy.prototype = false; |
| yield [bindOther.call(new ProxyOther(boundProxy, {})), "bound Proxy of cross-realm NewTarget with `false` prototype"]; |
| |
| const proxy = new realm.Function(); |
| proxy.prototype = true; |
| yield [new ProxyOther(proxy, {}), "Proxy of cross-realm NewTarget with `true` prototype"]; |
| |
| const proxyProxy = new realm.Function(); |
| proxyProxy.prototype = -0; |
| yield [new ProxyOther(new ProxyOther(proxyProxy, {}), {}), "Proxy of Proxy of cross-realm NewTarget with `-0` prototype"]; |
| |
| const proxyBound = new realm.Function(); |
| proxyBound.prototype = NaN; |
| yield [new ProxyOther(bindOther.call(proxyBound), {}), "Proxy of bound cross-realm NewTarget with `NaN` prototype"]; |
| }; |
| |
| for (const [interfaceName, constructorArg] of interfaces) { |
| for (const [newTarget, testDescription] of getNewTargets(newTargetRealm)) { |
| test(() => { |
| const Constructor = constructorRealm.WebAssembly[interfaceName]; |
| const object = Reflect.construct(Constructor, [constructorArg], newTarget); |
| |
| const NewTargetConstructor = newTargetRealm.WebAssembly[interfaceName]; |
| assert_true(object instanceof NewTargetConstructor); |
| assert_equals(Object.getPrototypeOf(object), NewTargetConstructor.prototype); |
| }, `WebAssembly.${interfaceName}: ${testDescription}`); |
| } |
| } |
| </script> |
| </body> |