1<!DOCTYPE html> 2<meta charset="utf-8"> 3<title>WebAssembly JS API: Default [[Prototype]] value is from NewTarget's Realm</title> 4<link rel="help" href="https://webidl.spec.whatwg.org/#internally-create-a-new-object-implementing-the-interface"> 5<link rel="help" href="https://tc39.es/ecma262/#sec-nativeerror"> 6<script src="/resources/testharness.js"></script> 7<script src="/resources/testharnessreport.js"></script> 8<script src="wasm-module-builder.js"></script> 9<body> 10<iframe id="constructor-iframe" hidden></iframe> 11<iframe id="new-target-iframe" hidden></iframe> 12<iframe id="other-iframe" hidden></iframe> 13<script> 14"use strict"; 15 16const constructorRealm = document.querySelector("#constructor-iframe").contentWindow; 17const newTargetRealm = document.querySelector("#new-target-iframe").contentWindow; 18const otherRealm = document.querySelector("#other-iframe").contentWindow; 19 20const emptyModuleBinary = new WasmModuleBuilder().toBuffer(); 21const interfaces = [ 22 ["Module", emptyModuleBinary], 23 ["Instance", new WebAssembly.Module(emptyModuleBinary)], 24 ["Memory", {initial: 0}], 25 ["Table", {element: "anyfunc", initial: 0}], 26 ["Global", {value: "i32"}], 27 28 // See step 2 of https://tc39.es/ecma262/#sec-nativeerror 29 ["CompileError"], 30 ["LinkError"], 31 ["RuntimeError"], 32]; 33 34const primitives = [ 35 undefined, 36 null, 37 false, 38 true, 39 0, 40 -1, 41 "", 42 "str", 43 Symbol(), 44]; 45 46const getNewTargets = function* (realm) { 47 for (const primitive of primitives) { 48 const newTarget = new realm.Function(); 49 newTarget.prototype = primitive; 50 yield [newTarget, "cross-realm NewTarget with `" + format_value(primitive) + "` prototype"]; 51 } 52 53 // GetFunctionRealm (https://tc39.es/ecma262/#sec-getfunctionrealm) coverage: 54 const bindOther = otherRealm.Function.prototype.bind; 55 const ProxyOther = otherRealm.Proxy; 56 57 const bound = new realm.Function(); 58 bound.prototype = undefined; 59 yield [bindOther.call(bound), "bound cross-realm NewTarget with `undefined` prototype"]; 60 61 const boundBound = new realm.Function(); 62 boundBound.prototype = null; 63 yield [bindOther.call(bindOther.call(boundBound)), "bound bound cross-realm NewTarget with `null` prototype"]; 64 65 const boundProxy = new realm.Function(); 66 boundProxy.prototype = false; 67 yield [bindOther.call(new ProxyOther(boundProxy, {})), "bound Proxy of cross-realm NewTarget with `false` prototype"]; 68 69 const proxy = new realm.Function(); 70 proxy.prototype = true; 71 yield [new ProxyOther(proxy, {}), "Proxy of cross-realm NewTarget with `true` prototype"]; 72 73 const proxyProxy = new realm.Function(); 74 proxyProxy.prototype = -0; 75 yield [new ProxyOther(new ProxyOther(proxyProxy, {}), {}), "Proxy of Proxy of cross-realm NewTarget with `-0` prototype"]; 76 77 const proxyBound = new realm.Function(); 78 proxyBound.prototype = NaN; 79 yield [new ProxyOther(bindOther.call(proxyBound), {}), "Proxy of bound cross-realm NewTarget with `NaN` prototype"]; 80}; 81 82for (const [interfaceName, constructorArg] of interfaces) { 83 for (const [newTarget, testDescription] of getNewTargets(newTargetRealm)) { 84 test(() => { 85 const Constructor = constructorRealm.WebAssembly[interfaceName]; 86 const object = Reflect.construct(Constructor, [constructorArg], newTarget); 87 88 const NewTargetConstructor = newTargetRealm.WebAssembly[interfaceName]; 89 assert_true(object instanceof NewTargetConstructor); 90 assert_equals(Object.getPrototypeOf(object), NewTargetConstructor.prototype); 91 }, `WebAssembly.${interfaceName}: ${testDescription}`); 92 } 93} 94</script> 95</body> 96