1function assert_function_name(fn, name, description) { 2 const propdesc = Object.getOwnPropertyDescriptor(fn, "name"); 3 assert_equals(typeof propdesc, "object", `${description} should have name property`); 4 assert_false(propdesc.writable, "writable", `${description} name should not be writable`); 5 assert_false(propdesc.enumerable, "enumerable", `${description} name should not be enumerable`); 6 assert_true(propdesc.configurable, "configurable", `${description} name should be configurable`); 7 assert_equals(propdesc.value, name, `${description} name should be ${name}`); 8} 9 10function assert_function_length(fn, length, description) { 11 const propdesc = Object.getOwnPropertyDescriptor(fn, "length"); 12 assert_equals(typeof propdesc, "object", `${description} should have length property`); 13 assert_false(propdesc.writable, "writable", `${description} length should not be writable`); 14 assert_false(propdesc.enumerable, "enumerable", `${description} length should not be enumerable`); 15 assert_true(propdesc.configurable, "configurable", `${description} length should be configurable`); 16 assert_equals(propdesc.value, length, `${description} length should be ${length}`); 17} 18 19function assert_exported_function(fn, { name, length }, description) { 20 if (WebAssembly.Function === undefined) { 21 assert_equals(Object.getPrototypeOf(fn), Function.prototype, 22 `${description}: prototype`); 23 } else { 24 assert_equals(Object.getPrototypeOf(fn), WebAssembly.Function.prototype, 25 `${description}: prototype`); 26 } 27 28 assert_function_name(fn, name, description); 29 assert_function_length(fn, length, description); 30} 31 32function assert_Instance(instance, expected_exports) { 33 assert_equals(Object.getPrototypeOf(instance), WebAssembly.Instance.prototype, 34 "prototype"); 35 assert_true(Object.isExtensible(instance), "extensible"); 36 37 assert_equals(instance.exports, instance.exports, "exports should be idempotent"); 38 const exports = instance.exports; 39 40 assert_equals(Object.getPrototypeOf(exports), null, "exports prototype"); 41 assert_false(Object.isExtensible(exports), "extensible exports"); 42 assert_array_equals(Object.keys(exports), Object.keys(expected_exports), "matching export keys"); 43 for (const [key, expected] of Object.entries(expected_exports)) { 44 const property = Object.getOwnPropertyDescriptor(exports, key); 45 assert_equals(typeof property, "object", `${key} should be present`); 46 assert_false(property.writable, `${key}: writable`); 47 assert_true(property.enumerable, `${key}: enumerable`); 48 assert_false(property.configurable, `${key}: configurable`); 49 const actual = property.value; 50 assert_true(Object.isExtensible(actual), `${key}: extensible`); 51 52 switch (expected.kind) { 53 case "function": 54 assert_exported_function(actual, expected, `value of ${key}`); 55 break; 56 case "global": 57 assert_equals(Object.getPrototypeOf(actual), WebAssembly.Global.prototype, 58 `value of ${key}: prototype`); 59 assert_equals(actual.value, expected.value, `value of ${key}: value`); 60 assert_equals(actual.valueOf(), expected.value, `value of ${key}: valueOf()`); 61 break; 62 case "memory": 63 assert_equals(Object.getPrototypeOf(actual), WebAssembly.Memory.prototype, 64 `value of ${key}: prototype`); 65 assert_equals(Object.getPrototypeOf(actual.buffer), ArrayBuffer.prototype, 66 `value of ${key}: prototype of buffer`); 67 assert_equals(actual.buffer.byteLength, 0x10000 * expected.size, `value of ${key}: size of buffer`); 68 const array = new Uint8Array(actual.buffer); 69 assert_equals(array[0], 0, `value of ${key}: first element of buffer`); 70 assert_equals(array[array.byteLength - 1], 0, `value of ${key}: last element of buffer`); 71 break; 72 case "table": 73 assert_equals(Object.getPrototypeOf(actual), WebAssembly.Table.prototype, 74 `value of ${key}: prototype`); 75 assert_equals(actual.length, expected.length, `value of ${key}: length of table`); 76 break; 77 } 78 } 79} 80 81function assert_WebAssemblyInstantiatedSource(actual, expected_exports={}) { 82 assert_equals(Object.getPrototypeOf(actual), Object.prototype, 83 "Prototype"); 84 assert_true(Object.isExtensible(actual), "Extensibility"); 85 86 const module = Object.getOwnPropertyDescriptor(actual, "module"); 87 assert_equals(typeof module, "object", "module: type of descriptor"); 88 assert_true(module.writable, "module: writable"); 89 assert_true(module.enumerable, "module: enumerable"); 90 assert_true(module.configurable, "module: configurable"); 91 assert_equals(Object.getPrototypeOf(module.value), WebAssembly.Module.prototype, 92 "module: prototype"); 93 94 const instance = Object.getOwnPropertyDescriptor(actual, "instance"); 95 assert_equals(typeof instance, "object", "instance: type of descriptor"); 96 assert_true(instance.writable, "instance: writable"); 97 assert_true(instance.enumerable, "instance: enumerable"); 98 assert_true(instance.configurable, "instance: configurable"); 99 assert_Instance(instance.value, expected_exports); 100} 101