| // Copyright 2015 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: --expose-wasm --experimental-wasm-eh |
| |
| load("test/mjsunit/wasm/wasm-constants.js"); |
| load("test/mjsunit/wasm/wasm-module-builder.js"); |
| |
| // The following method doesn't attempt to catch an raised exception. |
| var test_throw = (function () { |
| var builder = new WasmModuleBuilder(); |
| |
| builder.addException(kSig_v_v); |
| |
| builder.addFunction("throw_if_param_not_zero", kSig_i_i) |
| .addBody([ |
| kExprGetLocal, 0, |
| kExprI32Const, 0, |
| kExprI32Ne, |
| kExprIf, kWasmStmt, |
| kExprThrow, 0, |
| kExprEnd, |
| kExprI32Const, 1 |
| ]).exportFunc(); |
| |
| return builder.instantiate(); |
| })(); |
| |
| // Check the test_throw exists. |
| assertFalse(test_throw === undefined); |
| assertFalse(test_throw === null); |
| assertFalse(test_throw === 0); |
| assertEquals("object", typeof test_throw.exports); |
| assertEquals("function", typeof test_throw.exports.throw_if_param_not_zero); |
| |
| // Test expected behavior of throws |
| assertEquals(1, test_throw.exports.throw_if_param_not_zero(0)); |
| assertWasmThrows(0, [], function() { test_throw.exports.throw_if_param_not_zero(10) }); |
| assertWasmThrows(0, [], function() { test_throw.exports.throw_if_param_not_zero(-1) }); |
| |
| // Now that we know throwing works, we test catching the exceptions we raise. |
| var test_catch = (function () { |
| var builder = new WasmModuleBuilder(); |
| |
| builder.addException(kSig_v_v); |
| builder.addFunction("simple_throw_catch_to_0_1", kSig_i_i) |
| .addBody([ |
| kExprTry, kWasmI32, |
| kExprGetLocal, 0, |
| kExprI32Eqz, |
| kExprIf, kWasmStmt, |
| kExprThrow, 0, |
| kExprEnd, |
| kExprI32Const, 1, |
| kExprCatch, 0, |
| kExprI32Const, 0, |
| kExprEnd |
| ]).exportFunc(); |
| |
| return builder.instantiate(); |
| })(); |
| |
| // Check the test_catch exists. |
| assertFalse(test_catch === undefined); |
| assertFalse(test_catch === null); |
| assertFalse(test_catch === 0); |
| assertEquals("object", typeof test_catch.exports); |
| assertEquals("function", typeof test_catch.exports.simple_throw_catch_to_0_1); |
| |
| // Test expected behavior of simple catch. |
| assertEquals(0, test_catch.exports.simple_throw_catch_to_0_1(0)); |
| assertEquals(1, test_catch.exports.simple_throw_catch_to_0_1(1)); |
| |
| // Test that we can distinguish which exception was thrown. |
| var test_catch_2 = (function () { |
| var builder = new WasmModuleBuilder(); |
| |
| builder.addException(kSig_v_v); |
| builder.addException(kSig_v_v); |
| builder.addException(kSig_v_v); |
| builder.addFunction("catch_different_exceptions", kSig_i_i) |
| .addBody([ |
| kExprTry, kWasmI32, |
| kExprTry, kWasmI32, |
| kExprGetLocal, 0, |
| kExprI32Eqz, |
| kExprIf, kWasmStmt, |
| kExprThrow, 0, |
| kExprElse, |
| kExprGetLocal, 0, |
| kExprI32Const, 1, |
| kExprI32Eq, |
| kExprIf, kWasmStmt, |
| kExprThrow, 1, |
| kExprElse, |
| kExprThrow, 2, |
| kExprEnd, |
| kExprEnd, |
| kExprI32Const, 2, |
| kExprCatch, 0, |
| kExprI32Const, 3, |
| kExprEnd, |
| kExprCatch, 1, |
| kExprI32Const, 4, |
| kExprEnd |
| ]).exportFunc(); |
| return builder.instantiate(); |
| })(); |
| |
| assertFalse(test_catch_2 === undefined); |
| assertFalse(test_catch_2 === null); |
| assertFalse(test_catch_2 === 0); |
| assertEquals("object", typeof test_catch_2.exports); |
| assertEquals("function", typeof test_catch_2.exports.catch_different_exceptions); |
| |
| assertEquals(3, test_catch_2.exports.catch_different_exceptions(0)); |
| assertEquals(4, test_catch_2.exports.catch_different_exceptions(1)); |
| assertWasmThrows(2, [], function() { test_catch_2.exports.catch_different_exceptions(2) }); |
| |
| // Test throwing an exception with multiple values. |
| var test_throw_1_2 = (function() { |
| var builder = new WasmModuleBuilder(); |
| builder.addException(kSig_v_ii); |
| builder.addFunction("throw_1_2", kSig_v_v) |
| .addBody([ |
| kExprI32Const, 1, |
| kExprI32Const, 2, |
| kExprThrow, 0, |
| ]).exportFunc(); |
| |
| return builder.instantiate(); |
| })(); |
| |
| assertFalse(test_throw_1_2 === undefined); |
| assertFalse(test_throw_1_2 === null); |
| assertFalse(test_throw_1_2 === 0); |
| assertEquals("object", typeof test_throw_1_2.exports); |
| assertEquals("function", typeof test_throw_1_2.exports.throw_1_2); |
| |
| assertWasmThrows(0, [0, 1, 0, 2], function() { test_throw_1_2.exports.throw_1_2(); }); |
| |
| // Test throwing/catching the i32 parameter value. |
| var test_throw_catch_param_i = (function () { |
| var builder = new WasmModuleBuilder(); |
| builder.addException(kSig_v_i); |
| builder.addFunction("throw_catch_param", kSig_i_i) |
| .addBody([ |
| kExprTry, kWasmI32, |
| kExprGetLocal, 0, |
| kExprThrow, 0, |
| kExprI32Const, 2, |
| kExprCatch, 0, |
| kExprReturn, |
| kExprEnd, |
| ]).exportFunc(); |
| |
| return builder.instantiate(); |
| })(); |
| |
| assertFalse(test_throw_catch_param_i === undefined); |
| assertFalse(test_throw_catch_param_i === null); |
| assertFalse(test_throw_catch_param_i === 0); |
| assertEquals("object", typeof test_throw_catch_param_i.exports); |
| assertEquals("function", |
| typeof test_throw_catch_param_i.exports.throw_catch_param); |
| |
| assertEquals(0, test_throw_catch_param_i.exports.throw_catch_param(0)); |
| assertEquals(1, test_throw_catch_param_i.exports.throw_catch_param(1)); |
| assertEquals(10, test_throw_catch_param_i.exports.throw_catch_param(10)); |
| |
| // Test the encoding of a thrown exception with an integer exception. |
| |
| var test_throw_param_i = (function () { |
| var builder = new WasmModuleBuilder(); |
| builder.addException(kSig_v_i); |
| builder.addFunction("throw_param", kSig_v_i) |
| .addBody([ |
| kExprGetLocal, 0, |
| kExprThrow, 0, |
| ]).exportFunc(); |
| |
| return builder.instantiate(); |
| })(); |
| |
| assertFalse(test_throw_param_i === undefined); |
| assertFalse(test_throw_param_i === null); |
| assertFalse(test_throw_param_i === 0); |
| assertEquals("object", typeof test_throw_param_i.exports); |
| assertEquals("function", |
| typeof test_throw_param_i.exports.throw_param); |
| |
| assertWasmThrows(0, [0, 5], function() { test_throw_param_i.exports.throw_param(5); }); |
| assertWasmThrows(0, [6, 31026], |
| function() { test_throw_param_i.exports.throw_param(424242); }); |
| |
| // Test throwing/catching the f32 parameter value. |
| var test_throw_catch_param_f = (function () { |
| var builder = new WasmModuleBuilder(); |
| builder.addException(kSig_v_f); |
| builder.addFunction("throw_catch_param", kSig_f_f) |
| .addBody([ |
| kExprTry, kWasmF32, |
| kExprGetLocal, 0, |
| kExprThrow, 0, |
| kExprF32Const, 0, 0, 0, 0, |
| kExprCatch, 0, |
| kExprReturn, |
| kExprEnd, |
| ]).exportFunc(); |
| |
| return builder.instantiate(); |
| })(); |
| |
| assertFalse(test_throw_catch_param_f === undefined); |
| assertFalse(test_throw_catch_param_f === null); |
| assertFalse(test_throw_catch_param_f === 0); |
| assertEquals("object", typeof test_throw_catch_param_f.exports); |
| assertEquals("function", |
| typeof test_throw_catch_param_f.exports.throw_catch_param); |
| |
| assertEquals(5.0, test_throw_catch_param_f.exports.throw_catch_param(5.0)); |
| assertEquals(10.5, test_throw_catch_param_f.exports.throw_catch_param(10.5)); |
| |
| // Test the encoding of a thrown exception with a float value. |
| |
| var test_throw_param_f = (function () { |
| var builder = new WasmModuleBuilder(); |
| builder.addException(kSig_v_f); |
| builder.addFunction("throw_param", kSig_v_f) |
| .addBody([ |
| kExprGetLocal, 0, |
| kExprThrow, 0, |
| ]).exportFunc(); |
| |
| return builder.instantiate(); |
| })(); |
| |
| assertFalse(test_throw_param_f === undefined); |
| assertFalse(test_throw_param_f === null); |
| assertFalse(test_throw_param_f === 0); |
| assertEquals("object", typeof test_throw_param_f.exports); |
| assertEquals("function", |
| typeof test_throw_param_f.exports.throw_param); |
| |
| assertWasmThrows(0, [16544, 0], |
| function() { test_throw_param_f.exports.throw_param(5.0); }); |
| assertWasmThrows(0, [16680, 0], |
| function() { test_throw_param_f.exports.throw_param(10.5); }); |
| |
| // Test throwing/catching an I64 value |
| var test_throw_catch_param_l = (function () { |
| var builder = new WasmModuleBuilder(); |
| builder.addException(kSig_v_l); |
| builder.addFunction("throw_catch_param", kSig_i_i) |
| .addBody([ |
| kExprGetLocal, 0, |
| kExprI64UConvertI32, |
| kExprSetLocal, 1, |
| kExprTry, kWasmI32, |
| kExprGetLocal, 1, |
| kExprThrow, 0, |
| kExprI32Const, 2, |
| kExprCatch, 0, |
| kExprGetLocal, 1, |
| kExprI64Eq, |
| kExprIf, kWasmI32, |
| kExprI32Const, 1, |
| kExprElse, |
| kExprI32Const, 0, |
| kExprEnd, |
| // TODO(kschimpf): Why is this return necessary? |
| kExprReturn, |
| kExprEnd, |
| ]).addLocals({i64_count: 1}).exportFunc(); |
| |
| return builder.instantiate(); |
| })(); |
| |
| assertFalse(test_throw_catch_param_l === undefined); |
| assertFalse(test_throw_catch_param_l === null); |
| assertFalse(test_throw_catch_param_l === 0); |
| assertEquals("object", typeof test_throw_catch_param_l.exports); |
| assertEquals("function", |
| typeof test_throw_catch_param_l.exports.throw_catch_param); |
| |
| assertEquals(1, test_throw_catch_param_l.exports.throw_catch_param(5)); |
| assertEquals(1, test_throw_catch_param_l.exports.throw_catch_param(0)); |
| assertEquals(1, test_throw_catch_param_l.exports.throw_catch_param(-1)); |
| |
| // Test the encoding of a thrown exception with an I64 value. |
| |
| var test_throw_param_l = (function () { |
| var builder = new WasmModuleBuilder(); |
| builder.addException(kSig_v_l); |
| builder.addFunction("throw_param", kSig_v_ii) |
| .addBody([ |
| kExprGetLocal, 0, |
| kExprI64UConvertI32, |
| kExprI64Const, 32, |
| kExprI64Shl, |
| kExprGetLocal, 1, |
| kExprI64UConvertI32, |
| kExprI64Ior, |
| kExprThrow, 0 |
| ]).exportFunc(); |
| |
| return builder.instantiate(); |
| })(); |
| |
| assertFalse(test_throw_param_l === undefined); |
| assertFalse(test_throw_param_l === null); |
| assertFalse(test_throw_param_l === 0); |
| assertEquals("object", typeof test_throw_param_l.exports); |
| assertEquals("function", |
| typeof test_throw_param_l.exports.throw_param); |
| |
| assertWasmThrows(0, [0, 10, 0, 5], |
| function() { test_throw_param_l.exports.throw_param(10, 5); }); |
| assertWasmThrows(0, [65535, 65535, 0, 13], |
| function() { test_throw_param_l.exports.throw_param(-1, 13); }); |
| |
| // Test throwing/catching the F64 parameter value |
| var test_throw_catch_param_d = (function () { |
| var builder = new WasmModuleBuilder(); |
| builder.addException(kSig_v_d); |
| builder.addFunction("throw_catch_param", kSig_d_d) |
| .addBody([ |
| kExprTry, kWasmF64, |
| kExprGetLocal, 0, |
| kExprThrow, 0, |
| kExprF64Const, 0, 0, 0, 0, 0, 0, 0, 0, |
| kExprCatch, 0, |
| kExprReturn, |
| kExprEnd, |
| ]).exportFunc(); |
| |
| return builder.instantiate(); |
| })(); |
| |
| assertFalse(test_throw_catch_param_d === undefined); |
| assertFalse(test_throw_catch_param_d === null); |
| assertFalse(test_throw_catch_param_d === 0); |
| assertEquals("object", typeof test_throw_catch_param_d.exports); |
| assertEquals("function", |
| typeof test_throw_catch_param_d.exports.throw_catch_param); |
| |
| assertEquals(5.0, test_throw_catch_param_d.exports.throw_catch_param(5.0)); |
| assertEquals(10.5, test_throw_catch_param_d.exports.throw_catch_param(10.5)); |
| |
| // Test the encoding of a thrown exception with an f64 value. |
| |
| var test_throw_param_d = (function () { |
| var builder = new WasmModuleBuilder(); |
| builder.addException(kSig_v_d); |
| builder.addFunction("throw_param", kSig_v_f) |
| .addBody([ |
| kExprGetLocal, 0, |
| kExprF64ConvertF32, |
| kExprThrow, 0 |
| ]).exportFunc(); |
| |
| return builder.instantiate(); |
| })(); |
| |
| assertFalse(test_throw_param_d === undefined); |
| assertFalse(test_throw_param_d === null); |
| assertFalse(test_throw_param_d === 0); |
| assertEquals("object", typeof test_throw_param_d.exports); |
| assertEquals("function", |
| typeof test_throw_param_d.exports.throw_param); |
| |
| assertWasmThrows(0, [16404, 0, 0, 0], |
| function() { test_throw_param_d.exports.throw_param(5.0); }); |
| assertWasmThrows(0, [16739, 4816, 0, 0], |
| function() { test_throw_param_d.exports.throw_param(10000000.5); }); |
| |
| /* TODO(kschimpf) Convert these tests to work for the proposed exceptions. |
| |
| // The following methods do not attempt to catch the exception they raise. |
| var test_throw = (function () { |
| var builder = new WasmModuleBuilder(); |
| |
| builder.addFunction("throw_expr_with_params", kSig_v_ddi) |
| .addBody([ |
| // p2 * (p0 + min(p0, p1))|0 - 20 |
| kExprGetLocal, 2, |
| kExprGetLocal, 0, |
| kExprGetLocal, 0, |
| kExprGetLocal, 1, |
| kExprF64Min, |
| kExprF64Add, |
| kExprI32SConvertF64, |
| kExprI32Mul, |
| kExprI32Const, 20, |
| kExprI32Sub, |
| kExprThrow, |
| ]) |
| .exportFunc() |
| |
| return builder.instantiate(); |
| })(); |
| |
| // Check the test_throw exists. |
| assertFalse(test_throw === undefined); |
| assertFalse(test_throw === null); |
| assertFalse(test_throw === 0); |
| assertEquals("object", typeof test_throw.exports); |
| assertEquals("function", typeof test_throw.exports.throw_expr_with_params); |
| |
| assertEquals(1, test_throw.exports.throw_param_if_not_zero(0)); |
| assertWasmThrows( |
| -8, function() { test_throw.exports.throw_expr_with_params(1.5, 2.5, 4); }); |
| assertWasmThrows( |
| 12, function() { test_throw.exports.throw_expr_with_params(5.7, 2.5, 4); }); |
| |
| // Now that we know throwing works, we test catching the exceptions we raise. |
| var test_catch = (function () { |
| var builder = new WasmModuleBuilder(); |
| |
| // Helper function for throwing from js. It is imported by the Wasm module |
| // as throw_i. |
| function throw_value(value) { |
| throw value; |
| } |
| var sig_index = builder.addType(kSig_v_i); |
| var kJSThrowI = builder.addImport("", "throw_i", sig_index); |
| |
| // Helper function that throws a string. Wasm should not catch it. |
| function throw_string() { |
| throw "use wasm;"; |
| } |
| sig_index = builder.addType(kSig_v_v); |
| var kJSThrowString = builder.addImport("", "throw_string", sig_index); |
| |
| // Helper function that throws undefined. Wasm should not catch it. |
| function throw_undefined() { |
| throw undefined; |
| } |
| var kJSThrowUndefined = builder.addImport("", "throw_undefined", sig_index); |
| |
| // Helper function that throws an fp. Wasm should not catch it. |
| function throw_fp() { |
| throw 10.5; |
| } |
| var kJSThrowFP = builder.addImport("", "throw_fp", sig_index); |
| |
| // Helper function that throws a large number. Wasm should not catch it. |
| function throw_large() { |
| throw 1e+28; |
| } |
| var kJSThrowLarge = builder.addImport("", "throw_large", sig_index); |
| |
| // Helper function for throwing from WebAssembly. |
| var kWasmThrowFunction = |
| builder.addFunction("throw", kSig_v_i) |
| .addBody([ |
| kExprGetLocal, 0, |
| kExprThrow |
| ]) |
| .index; |
| |
| // Scenario 1: Throw and catch appear on the same function. This should |
| // happen in case of inlining, for example. |
| builder.addFunction("same_scope", kSig_i_i) |
| .addBody([ |
| kExprTry, kWasmI32, |
| kExprGetLocal, 0, |
| kExprI32Const, 0, |
| kExprI32Ne, |
| kExprIf, kWasmStmt, |
| kExprGetLocal, 0, |
| kExprThrow, |
| kExprUnreachable, |
| kExprEnd, |
| kExprI32Const, 63, |
| kExprCatch, 1, |
| kExprGetLocal, 1, |
| kExprEnd |
| ]) |
| .addLocals({i32_count: 1}) |
| .exportFunc() |
| .index; |
| |
| builder.addFunction("same_scope_ignore", kSig_i_i) |
| .addBody([ |
| kExprTry, kWasmI32, |
| kExprGetLocal, 0, |
| kExprThrow, |
| kExprUnreachable, |
| kExprCatch, 1, |
| kExprGetLocal, 0, |
| kExprEnd, |
| ]) |
| .addLocals({i32_count: 1}) |
| .exportFunc(); |
| |
| builder.addFunction("same_scope_multiple", kSig_i_i) |
| // path = 0; |
| // |
| // try { |
| // try { |
| // try { |
| // if (p == 1) |
| // throw 1; |
| // path |= 2 |
| // } catch (v) { |
| // path |= v | 4; |
| // throw path; |
| // } |
| // if (p == 2) |
| // throw path|8; |
| // path |= 16; |
| // } catch (v) { |
| // path |= v | 32; |
| // throw path; |
| // } |
| // if (p == 3) |
| // throw path|64; |
| // path |= 128 |
| // } catch (v) { |
| // path |= v | 256; |
| // } |
| // |
| // return path; |
| // |
| // p == 1 -> path == 293 |
| // p == 2 -> path == 298 |
| // p == 3 -> path == 338 |
| // else -> path == 146 |
| .addBody([ |
| kExprTry, kWasmI32, |
| kExprTry, kWasmI32, |
| kExprTry, kWasmI32, |
| kExprGetLocal, 0, |
| kExprI32Const, 1, |
| kExprI32Eq, |
| kExprIf, kWasmStmt, |
| kExprI32Const, 1, |
| kExprThrow, |
| kExprUnreachable, |
| kExprEnd, |
| kExprI32Const, 2, |
| kExprCatch, 1, |
| kExprGetLocal, 1, |
| kExprI32Const, 4, |
| kExprI32Ior, |
| kExprThrow, |
| kExprUnreachable, |
| kExprEnd, |
| kExprTeeLocal, 2, |
| kExprGetLocal, 0, |
| kExprI32Const, 2, |
| kExprI32Eq, |
| kExprIf, kWasmStmt, |
| kExprGetLocal, 2, |
| kExprI32Const, 8, |
| kExprI32Ior, |
| kExprThrow, |
| kExprUnreachable, |
| kExprEnd, |
| kExprI32Const, 16, |
| kExprI32Ior, |
| kExprCatch, 1, |
| kExprGetLocal, 1, |
| kExprI32Const, 32, |
| kExprI32Ior, |
| kExprThrow, |
| kExprUnreachable, |
| kExprEnd, |
| kExprTeeLocal, 2, |
| kExprGetLocal, 0, |
| kExprI32Const, 3, |
| kExprI32Eq, |
| kExprIf, kWasmStmt, |
| kExprGetLocal, 2, |
| kExprI32Const, / *64=* / 192, 0, |
| kExprI32Ior, |
| kExprThrow, |
| kExprUnreachable, |
| kExprEnd, |
| kExprI32Const, / *128=* / 128, 1, |
| kExprI32Ior, |
| kExprCatch, 1, |
| kExprGetLocal, 1, |
| kExprI32Const, / *256=* / 128, 2, |
| kExprI32Ior, |
| kExprEnd, |
| ]) |
| .addLocals({i32_count: 2}) |
| .exportFunc(); |
| |
| // Scenario 2: Catches an exception raised from the direct callee. |
| var kFromDirectCallee = |
| builder.addFunction("from_direct_callee", kSig_i_i) |
| .addBody([ |
| kExprTry, kWasmI32, |
| kExprGetLocal, 0, |
| kExprCallFunction, kWasmThrowFunction, |
| kExprI32Const, / *-1=* / 127, |
| kExprCatch, 1, |
| kExprGetLocal, 1, |
| kExprEnd |
| ]) |
| .addLocals({i32_count: 1}) |
| .exportFunc() |
| .index; |
| |
| // Scenario 3: Catches an exception raised from an indirect callee. |
| var kFromIndirectCalleeHelper = kFromDirectCallee + 1; |
| builder.addFunction("from_indirect_callee_helper", kSig_v_ii) |
| .addBody([ |
| kExprGetLocal, 0, |
| kExprI32Const, 0, |
| kExprI32GtS, |
| kExprIf, kWasmStmt, |
| kExprGetLocal, 0, |
| kExprI32Const, 1, |
| kExprI32Sub, |
| kExprGetLocal, 1, |
| kExprI32Const, 1, |
| kExprI32Sub, |
| kExprCallFunction, kFromIndirectCalleeHelper, |
| kExprEnd, |
| kExprGetLocal, 1, |
| kExprCallFunction, kWasmThrowFunction, |
| ]); |
| |
| builder.addFunction("from_indirect_callee", kSig_i_i) |
| .addBody([ |
| kExprTry, kWasmI32, |
| kExprGetLocal, 0, |
| kExprI32Const, 0, |
| kExprCallFunction, kFromIndirectCalleeHelper, |
| kExprI32Const, / *-1=* / 127, |
| kExprCatch, 1, |
| kExprGetLocal, 1, |
| kExprEnd |
| ]) |
| .addLocals({i32_count: 1}) |
| .exportFunc(); |
| |
| // Scenario 4: Catches an exception raised in JS. |
| builder.addFunction("from_js", kSig_i_i) |
| .addBody([ |
| kExprTry, kWasmI32, |
| kExprGetLocal, 0, |
| kExprCallFunction, kJSThrowI, |
| kExprI32Const, / *-1=* / 127, |
| kExprCatch, 1, |
| kExprGetLocal, 1, |
| kExprEnd, |
| ]) |
| .addLocals({i32_count: 1}) |
| .exportFunc(); |
| |
| // Scenario 5: Does not catch an exception raised in JS if it is not a |
| // number. |
| builder.addFunction("string_from_js", kSig_v_v) |
| .addBody([ |
| kExprCallFunction, kJSThrowString |
| ]) |
| .exportFunc(); |
| |
| builder.addFunction("fp_from_js", kSig_v_v) |
| .addBody([ |
| kExprCallFunction, kJSThrowFP |
| ]) |
| .exportFunc(); |
| |
| builder.addFunction("large_from_js", kSig_v_v) |
| .addBody([ |
| kExprCallFunction, kJSThrowLarge |
| ]) |
| .exportFunc(); |
| |
| builder.addFunction("undefined_from_js", kSig_v_v) |
| .addBody([ |
| kExprCallFunction, kJSThrowUndefined |
| ]) |
| .exportFunc(); |
| |
| return builder.instantiate({"": { |
| throw_i: throw_value, |
| throw_string: throw_string, |
| throw_fp: throw_fp, |
| throw_large, throw_large, |
| throw_undefined: throw_undefined |
| }}); |
| })(); |
| |
| // Check the test_catch exists. |
| assertFalse(test_catch === undefined); |
| assertFalse(test_catch === null); |
| assertFalse(test_catch === 0); |
| assertEquals("object", typeof test_catch.exports); |
| assertEquals("function", typeof test_catch.exports.same_scope); |
| assertEquals("function", typeof test_catch.exports.same_scope_ignore); |
| assertEquals("function", typeof test_catch.exports.same_scope_multiple); |
| assertEquals("function", typeof test_catch.exports.from_direct_callee); |
| assertEquals("function", typeof test_catch.exports.from_indirect_callee); |
| assertEquals("function", typeof test_catch.exports.from_js); |
| assertEquals("function", typeof test_catch.exports.string_from_js); |
| |
| assertEquals(63, test_catch.exports.same_scope(0)); |
| assertEquals(1024, test_catch.exports.same_scope(1024)); |
| assertEquals(-3, test_catch.exports.same_scope(-3)); |
| assertEquals(-1, test_catch.exports.same_scope_ignore(-1)); |
| assertEquals(1, test_catch.exports.same_scope_ignore(1)); |
| assertEquals(0x7FFFFFFF, test_catch.exports.same_scope_ignore(0x7FFFFFFF)); |
| assertEquals(1024, test_catch.exports.same_scope_ignore(1024)); |
| assertEquals(-1, test_catch.exports.same_scope_ignore(-1)); |
| assertEquals(293, test_catch.exports.same_scope_multiple(1)); |
| assertEquals(298, test_catch.exports.same_scope_multiple(2)); |
| assertEquals(338, test_catch.exports.same_scope_multiple(3)); |
| assertEquals(146, test_catch.exports.same_scope_multiple(0)); |
| assertEquals(-10024, test_catch.exports.from_direct_callee(-10024)); |
| assertEquals(3334333, test_catch.exports.from_direct_callee(3334333)); |
| assertEquals(-1, test_catch.exports.from_direct_callee(0xFFFFFFFF)); |
| assertEquals(0x7FFFFFFF, test_catch.exports.from_direct_callee(0x7FFFFFFF)); |
| assertEquals(-10, test_catch.exports.from_indirect_callee(10)); |
| assertEquals(-77, test_catch.exports.from_indirect_callee(77)); |
| assertEquals(10, test_catch.exports.from_js(10)); |
| assertEquals(-10, test_catch.exports.from_js(-10)); |
| |
| assertThrowsEquals(test_catch.exports.string_from_js, "use wasm;"); |
| assertThrowsEquals(test_catch.exports.large_from_js, 1e+28); |
| assertThrowsEquals(test_catch.exports.undefined_from_js, undefined); |
| */ |