exceptions-anyref.js 6.14 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --experimental-wasm-eh --experimental-wasm-anyref --allow-natives-syntax

load("test/mjsunit/wasm/wasm-module-builder.js");
8
load("test/mjsunit/wasm/exceptions-utils.js");
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

// Test the encoding of a thrown exception with a null-ref value.
(function TestThrowRefNull() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let except = builder.addException(kSig_v_r);
  builder.addFunction("throw_null", kSig_v_v)
      .addBody([
        kExprRefNull,
        kExprThrow, except,
      ]).exportFunc();
  let instance = builder.instantiate();

  assertWasmThrows(instance, except, [null], () => instance.exports.throw_null());
})();

// Test throwing/catching the null-ref value.
(function TestThrowCatchRefNull() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let except = builder.addException(kSig_v_r);
  builder.addFunction("throw_catch_null", kSig_i_i)
      .addBody([
32
        kExprTry, kWasmAnyRef,
33
          kExprLocalGet, 0,
34
          kExprI32Eqz,
35
          kExprIf, kWasmAnyRef,
36 37 38 39
            kExprRefNull,
            kExprThrow, except,
          kExprElse,
            kExprI32Const, 42,
40
            kExprReturn,
41
          kExprEnd,
42 43 44 45 46 47 48 49 50
        kExprCatch,
          kExprBrOnExn, 0, except,
          kExprRethrow,
        kExprEnd,
        kExprRefIsNull,
        kExprIf, kWasmI32,
          kExprI32Const, 23,
        kExprElse,
          kExprUnreachable,
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
        kExprEnd,
      ]).exportFunc();
  let instance = builder.instantiate();

  assertEquals(23, instance.exports.throw_catch_null(0));
  assertEquals(42, instance.exports.throw_catch_null(1));
})();

// Test the encoding of a thrown exception with a reference type value.
(function TestThrowRefParam() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let except = builder.addException(kSig_v_r);
  builder.addFunction("throw_param", kSig_v_r)
      .addBody([
66
        kExprLocalGet, 0,
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
        kExprThrow, except,
      ]).exportFunc();
  let instance = builder.instantiate();
  let o = new Object();

  assertWasmThrows(instance, except, [o], () => instance.exports.throw_param(o));
  assertWasmThrows(instance, except, [1], () => instance.exports.throw_param(1));
  assertWasmThrows(instance, except, [2.3], () => instance.exports.throw_param(2.3));
  assertWasmThrows(instance, except, ["str"], () => instance.exports.throw_param("str"));
})();

// Test throwing/catching the reference type value.
(function TestThrowCatchRefParam() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let except = builder.addException(kSig_v_r);
  builder.addFunction("throw_catch_param", kSig_r_r)
      .addBody([
        kExprTry, kWasmAnyRef,
86
          kExprLocalGet, 0,
87
          kExprThrow, except,
88 89 90
        kExprCatch,
          kExprBrOnExn, 0, except,
          kExprRethrow,
91 92 93 94 95 96 97 98 99 100
        kExprEnd,
      ]).exportFunc();
  let instance = builder.instantiate();
  let o = new Object();

  assertEquals(o, instance.exports.throw_catch_param(o));
  assertEquals(1, instance.exports.throw_catch_param(1));
  assertEquals(2.3, instance.exports.throw_catch_param(2.3));
  assertEquals("str", instance.exports.throw_catch_param("str"));
})();
101 102 103 104 105 106 107 108 109 110

// Test throwing/catching a function reference type value.
(function TestThrowCatchAnyFunc() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let except = builder.addException(kSig_v_a);
  builder.addFunction("throw_catch_local", kSig_r_v)
      .addLocals({anyfunc_count: 1})
      .addBody([
        kExprTry, kWasmAnyFunc,
111
          kExprLocalGet, 0,
112 113 114 115 116 117 118 119 120 121 122 123
          kExprThrow, except,
        kExprCatch,
          kExprBrOnExn, 0, except,
          kExprRethrow,
        kExprEnd,
      ]).exportFunc();
  let instance = builder.instantiate();

  assertEquals(null, instance.exports.throw_catch_local());
})();

// Test throwing/catching an encapsulated exception type value.
124
(function TestThrowCatchExnRef() {
125 126 127 128 129
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let except = builder.addException(kSig_v_e);
  builder.addFunction("throw_catch_param", kSig_e_e)
      .addBody([
130
        kExprTry, kWasmExnRef,
131
          kExprLocalGet, 0,
132 133 134 135 136 137 138 139 140 141 142 143 144 145
          kExprThrow, except,
        kExprCatch,
          kExprBrOnExn, 0, except,
          kExprRethrow,
        kExprEnd,
      ]).exportFunc();
  let instance = builder.instantiate();
  let e = new Error("my encapsulated error");

  assertEquals(e, instance.exports.throw_catch_param(e));
  assertEquals(1, instance.exports.throw_catch_param(1));
  assertEquals(2.3, instance.exports.throw_catch_param(2.3));
  assertEquals("str", instance.exports.throw_catch_param("str"));
})();
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184

// Test storing and loading to/from an exception type table.
(function TestTableExnRef() {
  let kSig_e_i = makeSig([kWasmI32], [kWasmExnRef]);
  let kSig_v_ie = makeSig([kWasmI32, kWasmExnRef], []);
  let builder = new WasmModuleBuilder();
  let table = builder.addTable(kWasmExnRef, 2).exportAs("table");
  builder.addFunction("table_load", kSig_e_i)
      .addBody([
        kExprLocalGet, 0,
        kExprTableGet, table.index
      ]).exportFunc();
  builder.addFunction("table_store", kSig_v_ie)
      .addBody([
        kExprLocalGet, 0,
        kExprLocalGet, 1,
        kExprTableSet, table.index
      ]).exportFunc();
  let instance = builder.instantiate();
  let e0 = new Error("my encapsulated error");
  let e1 = new Error("my other encapsulated error");

  assertNull(instance.exports.table_load(0));
  assertNull(instance.exports.table_load(1));
  assertNull(instance.exports.table.get(0));
  assertNull(instance.exports.table.get(1));

  instance.exports.table_store(0, e0);
  assertSame(e0, instance.exports.table_load(0));
  assertNull(instance.exports.table_load(1));
  assertSame(e0, instance.exports.table.get(0));
  assertNull(instance.exports.table.get(1));

  instance.exports.table.set(1, e1);
  assertSame(e0, instance.exports.table_load(0));
  assertSame(e1, instance.exports.table_load(1));
  assertSame(e0, instance.exports.table.get(0));
  assertSame(e1, instance.exports.table.get(1));
})();