11cb0ef41Sopenharmony_cifunction assert_function_name(fn, name, description) {
21cb0ef41Sopenharmony_ci  const propdesc = Object.getOwnPropertyDescriptor(fn, "name");
31cb0ef41Sopenharmony_ci  assert_equals(typeof propdesc, "object", `${description} should have name property`);
41cb0ef41Sopenharmony_ci  assert_false(propdesc.writable, "writable", `${description} name should not be writable`);
51cb0ef41Sopenharmony_ci  assert_false(propdesc.enumerable, "enumerable", `${description} name should not be enumerable`);
61cb0ef41Sopenharmony_ci  assert_true(propdesc.configurable, "configurable", `${description} name should be configurable`);
71cb0ef41Sopenharmony_ci  assert_equals(propdesc.value, name, `${description} name should be ${name}`);
81cb0ef41Sopenharmony_ci}
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_cifunction assert_function_length(fn, length, description) {
111cb0ef41Sopenharmony_ci  const propdesc = Object.getOwnPropertyDescriptor(fn, "length");
121cb0ef41Sopenharmony_ci  assert_equals(typeof propdesc, "object", `${description} should have length property`);
131cb0ef41Sopenharmony_ci  assert_false(propdesc.writable, "writable", `${description} length should not be writable`);
141cb0ef41Sopenharmony_ci  assert_false(propdesc.enumerable, "enumerable", `${description} length should not be enumerable`);
151cb0ef41Sopenharmony_ci  assert_true(propdesc.configurable, "configurable", `${description} length should be configurable`);
161cb0ef41Sopenharmony_ci  assert_equals(propdesc.value, length, `${description} length should be ${length}`);
171cb0ef41Sopenharmony_ci}
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_cifunction assert_exported_function(fn, { name, length }, description) {
201cb0ef41Sopenharmony_ci  if (WebAssembly.Function === undefined) {
211cb0ef41Sopenharmony_ci    assert_equals(Object.getPrototypeOf(fn), Function.prototype,
221cb0ef41Sopenharmony_ci                  `${description}: prototype`);
231cb0ef41Sopenharmony_ci  } else {
241cb0ef41Sopenharmony_ci    assert_equals(Object.getPrototypeOf(fn), WebAssembly.Function.prototype,
251cb0ef41Sopenharmony_ci                  `${description}: prototype`);
261cb0ef41Sopenharmony_ci  }
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci  assert_function_name(fn, name, description);
291cb0ef41Sopenharmony_ci  assert_function_length(fn, length, description);
301cb0ef41Sopenharmony_ci}
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cifunction assert_Instance(instance, expected_exports) {
331cb0ef41Sopenharmony_ci  assert_equals(Object.getPrototypeOf(instance), WebAssembly.Instance.prototype,
341cb0ef41Sopenharmony_ci                "prototype");
351cb0ef41Sopenharmony_ci  assert_true(Object.isExtensible(instance), "extensible");
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  assert_equals(instance.exports, instance.exports, "exports should be idempotent");
381cb0ef41Sopenharmony_ci  const exports = instance.exports;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  assert_equals(Object.getPrototypeOf(exports), null, "exports prototype");
411cb0ef41Sopenharmony_ci  assert_false(Object.isExtensible(exports), "extensible exports");
421cb0ef41Sopenharmony_ci  assert_array_equals(Object.keys(exports), Object.keys(expected_exports), "matching export keys");
431cb0ef41Sopenharmony_ci  for (const [key, expected] of Object.entries(expected_exports)) {
441cb0ef41Sopenharmony_ci    const property = Object.getOwnPropertyDescriptor(exports, key);
451cb0ef41Sopenharmony_ci    assert_equals(typeof property, "object", `${key} should be present`);
461cb0ef41Sopenharmony_ci    assert_false(property.writable, `${key}: writable`);
471cb0ef41Sopenharmony_ci    assert_true(property.enumerable, `${key}: enumerable`);
481cb0ef41Sopenharmony_ci    assert_false(property.configurable, `${key}: configurable`);
491cb0ef41Sopenharmony_ci    const actual = property.value;
501cb0ef41Sopenharmony_ci    assert_true(Object.isExtensible(actual), `${key}: extensible`);
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci    switch (expected.kind) {
531cb0ef41Sopenharmony_ci    case "function":
541cb0ef41Sopenharmony_ci      assert_exported_function(actual, expected, `value of ${key}`);
551cb0ef41Sopenharmony_ci      break;
561cb0ef41Sopenharmony_ci    case "global":
571cb0ef41Sopenharmony_ci      assert_equals(Object.getPrototypeOf(actual), WebAssembly.Global.prototype,
581cb0ef41Sopenharmony_ci                    `value of ${key}: prototype`);
591cb0ef41Sopenharmony_ci      assert_equals(actual.value, expected.value, `value of ${key}: value`);
601cb0ef41Sopenharmony_ci      assert_equals(actual.valueOf(), expected.value, `value of ${key}: valueOf()`);
611cb0ef41Sopenharmony_ci      break;
621cb0ef41Sopenharmony_ci    case "memory":
631cb0ef41Sopenharmony_ci      assert_equals(Object.getPrototypeOf(actual), WebAssembly.Memory.prototype,
641cb0ef41Sopenharmony_ci                    `value of ${key}: prototype`);
651cb0ef41Sopenharmony_ci      assert_equals(Object.getPrototypeOf(actual.buffer), ArrayBuffer.prototype,
661cb0ef41Sopenharmony_ci                    `value of ${key}: prototype of buffer`);
671cb0ef41Sopenharmony_ci      assert_equals(actual.buffer.byteLength, 0x10000 * expected.size, `value of ${key}: size of buffer`);
681cb0ef41Sopenharmony_ci      const array = new Uint8Array(actual.buffer);
691cb0ef41Sopenharmony_ci      assert_equals(array[0], 0, `value of ${key}: first element of buffer`);
701cb0ef41Sopenharmony_ci      assert_equals(array[array.byteLength - 1], 0, `value of ${key}: last element of buffer`);
711cb0ef41Sopenharmony_ci      break;
721cb0ef41Sopenharmony_ci    case "table":
731cb0ef41Sopenharmony_ci      assert_equals(Object.getPrototypeOf(actual), WebAssembly.Table.prototype,
741cb0ef41Sopenharmony_ci                    `value of ${key}: prototype`);
751cb0ef41Sopenharmony_ci      assert_equals(actual.length, expected.length, `value of ${key}: length of table`);
761cb0ef41Sopenharmony_ci      break;
771cb0ef41Sopenharmony_ci    }
781cb0ef41Sopenharmony_ci  }
791cb0ef41Sopenharmony_ci}
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_cifunction assert_WebAssemblyInstantiatedSource(actual, expected_exports={}) {
821cb0ef41Sopenharmony_ci  assert_equals(Object.getPrototypeOf(actual), Object.prototype,
831cb0ef41Sopenharmony_ci                "Prototype");
841cb0ef41Sopenharmony_ci  assert_true(Object.isExtensible(actual), "Extensibility");
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  const module = Object.getOwnPropertyDescriptor(actual, "module");
871cb0ef41Sopenharmony_ci  assert_equals(typeof module, "object", "module: type of descriptor");
881cb0ef41Sopenharmony_ci  assert_true(module.writable, "module: writable");
891cb0ef41Sopenharmony_ci  assert_true(module.enumerable, "module: enumerable");
901cb0ef41Sopenharmony_ci  assert_true(module.configurable, "module: configurable");
911cb0ef41Sopenharmony_ci  assert_equals(Object.getPrototypeOf(module.value), WebAssembly.Module.prototype,
921cb0ef41Sopenharmony_ci                "module: prototype");
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci  const instance = Object.getOwnPropertyDescriptor(actual, "instance");
951cb0ef41Sopenharmony_ci  assert_equals(typeof instance, "object", "instance: type of descriptor");
961cb0ef41Sopenharmony_ci  assert_true(instance.writable, "instance: writable");
971cb0ef41Sopenharmony_ci  assert_true(instance.enumerable, "instance: enumerable");
981cb0ef41Sopenharmony_ci  assert_true(instance.configurable, "instance: configurable");
991cb0ef41Sopenharmony_ci  assert_Instance(instance.value, expected_exports);
1001cb0ef41Sopenharmony_ci}
101