v8/test/mjsunit/wasm/exceptions-anyref.js
Michael Starzinger 5fbeb5c5bd [wasm] Support tables with exnref type entries.
This extends existing table support to be able to store 'exnref' in
addition to 'anyref' types. Tools can use this to maintain data
structures for exception packages.

R=ahaas@chromium.org
TEST=mjsunit/wasm/exceptions-anyref
BUG=v8:8091

Change-Id: Iccbcfdc328db81a366921bcdd98c2256f66e7fc8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781046
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64323}
2019-10-16 14:26:45 +00:00

185 lines
6.1 KiB
JavaScript

// 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");
load("test/mjsunit/wasm/exceptions-utils.js");
// 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([
kExprTry, kWasmAnyRef,
kExprLocalGet, 0,
kExprI32Eqz,
kExprIf, kWasmAnyRef,
kExprRefNull,
kExprThrow, except,
kExprElse,
kExprI32Const, 42,
kExprReturn,
kExprEnd,
kExprCatch,
kExprBrOnExn, 0, except,
kExprRethrow,
kExprEnd,
kExprRefIsNull,
kExprIf, kWasmI32,
kExprI32Const, 23,
kExprElse,
kExprUnreachable,
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([
kExprLocalGet, 0,
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,
kExprLocalGet, 0,
kExprThrow, except,
kExprCatch,
kExprBrOnExn, 0, except,
kExprRethrow,
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"));
})();
// 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,
kExprLocalGet, 0,
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.
(function TestThrowCatchExnRef() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let except = builder.addException(kSig_v_e);
builder.addFunction("throw_catch_param", kSig_e_e)
.addBody([
kExprTry, kWasmExnRef,
kExprLocalGet, 0,
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"));
})();
// 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));
})();