summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest/wasm')
-rw-r--r--deps/v8/test/cctest/wasm/test-gc.cc714
-rw-r--r--deps/v8/test/cctest/wasm/test-jump-table-assembler.cc8
-rw-r--r--deps/v8/test/cctest/wasm/test-liftoff-inspection.cc255
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc22
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-exceptions.cc318
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-memory64.cc44
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-module.cc35
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-simd-scalar-lowering.cc6
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-simd.cc234
-rw-r--r--deps/v8/test/cctest/wasm/test-streaming-compilation.cc22
-rw-r--r--deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc8
-rw-r--r--deps/v8/test/cctest/wasm/test-wasm-serialization.cc18
-rw-r--r--deps/v8/test/cctest/wasm/test-wasm-stack.cc6
-rw-r--r--deps/v8/test/cctest/wasm/wasm-run-utils.cc1
-rw-r--r--deps/v8/test/cctest/wasm/wasm-run-utils.h8
15 files changed, 1047 insertions, 652 deletions
diff --git a/deps/v8/test/cctest/wasm/test-gc.cc b/deps/v8/test/cctest/wasm/test-gc.cc
index 44d3b03076..dd1dfea0f1 100644
--- a/deps/v8/test/cctest/wasm/test-gc.cc
+++ b/deps/v8/test/cctest/wasm/test-gc.cc
@@ -204,7 +204,6 @@ ValueType optref(uint32_t type_index) {
WASM_COMPILED_EXEC_TEST(WasmBasicStruct) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte type_index =
tester.DefineStruct({F(kWasmI32, true), F(kWasmI32, true)});
@@ -277,7 +276,6 @@ WASM_COMPILED_EXEC_TEST(WasmBasicStruct) {
// struct refs types in globals and if-results.
WASM_COMPILED_EXEC_TEST(WasmRefAsNonNull) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte type_index =
tester.DefineStruct({F(kWasmI32, true), F(kWasmI32, true)});
ValueType kRefTypes[] = {ref(type_index)};
@@ -308,7 +306,6 @@ WASM_COMPILED_EXEC_TEST(WasmRefAsNonNull) {
WASM_COMPILED_EXEC_TEST(WasmBrOnNull) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte type_index =
tester.DefineStruct({F(kWasmI32, true), F(kWasmI32, true)});
ValueType kRefTypes[] = {ref(type_index)};
@@ -346,86 +343,77 @@ WASM_COMPILED_EXEC_TEST(WasmBrOnNull) {
WASM_COMPILED_EXEC_TEST(BrOnCast) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
+ ValueType kDataRefNull = ValueType::Ref(HeapType::kData, kNullable);
const byte type_index = tester.DefineStruct({F(kWasmI32, true)});
+ const byte other_type_index = tester.DefineStruct({F(kWasmF32, true)});
const byte rtt_index =
- tester.AddGlobal(ValueType::Rtt(type_index, 1), false,
+ tester.AddGlobal(ValueType::Rtt(type_index, 0), false,
WasmInitExpr::RttCanon(
static_cast<HeapType::Representation>(type_index)));
const byte kTestStruct = tester.DefineFunction(
- tester.sigs.i_v(), {kWasmI32, kWasmEqRef},
- {WASM_BLOCK(WASM_LOCAL_SET(0, WASM_I32V(111)),
- // Pipe a struct through a local so it's statically typed
- // as eqref.
- WASM_LOCAL_SET(
- 1, WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(1),
- WASM_GLOBAL_GET(rtt_index))),
- WASM_LOCAL_GET(1),
- // The struct is not an i31, so this branch isn't taken.
- WASM_BR_ON_CAST(0, WASM_RTT_CANON(kI31RefCode)),
- WASM_LOCAL_SET(0, WASM_I32V(222)), // Final result.
- // This branch is taken.
- WASM_BR_ON_CAST(0, WASM_GLOBAL_GET(rtt_index)),
- // Not executed due to the branch.
- WASM_DROP, WASM_LOCAL_SET(0, WASM_I32V(333))),
- WASM_LOCAL_GET(0), kExprEnd});
-
- const byte kTestI31 = tester.DefineFunction(
- tester.sigs.i_v(), {kWasmI32, kWasmEqRef},
- {WASM_BLOCK(WASM_LOCAL_SET(0, WASM_I32V(111)),
- // Pipe an i31ref through a local so it's statically typed
- // as eqref.
- WASM_LOCAL_SET(1, WASM_I31_NEW(WASM_I32V(42))),
- WASM_LOCAL_GET(1),
- // The i31 is not a struct, so this branch isn't taken.
- WASM_BR_ON_CAST(0, WASM_GLOBAL_GET(rtt_index)),
- WASM_LOCAL_SET(0, WASM_I32V(222)), // Final result.
- // This branch is taken.
- WASM_BR_ON_CAST(0, WASM_RTT_CANON(kI31RefCode)),
- // Not executed due to the branch.
- WASM_DROP, WASM_LOCAL_SET(0, WASM_I32V(333))),
- WASM_LOCAL_GET(0), kExprEnd});
+ tester.sigs.i_v(), {kWasmI32, kDataRefNull},
+ {WASM_BLOCK_R(ValueType::Ref(type_index, kNullable),
+ WASM_LOCAL_SET(0, WASM_I32V(111)),
+ // Pipe a struct through a local so it's statically typed
+ // as dataref.
+ WASM_LOCAL_SET(1, WASM_STRUCT_NEW_WITH_RTT(
+ other_type_index, WASM_F32(1.0),
+ WASM_RTT_CANON(other_type_index))),
+ WASM_LOCAL_GET(1),
+ // The type check fails, so this branch isn't taken.
+ WASM_BR_ON_CAST(0, WASM_GLOBAL_GET(rtt_index)), WASM_DROP,
+
+ WASM_LOCAL_SET(0, WASM_I32V(221)), // (Final result) - 1
+ WASM_LOCAL_SET(1, WASM_STRUCT_NEW_WITH_RTT(
+ type_index, WASM_I32V(1),
+ WASM_GLOBAL_GET(rtt_index))),
+ WASM_LOCAL_GET(1),
+ // This branch is taken.
+ WASM_BR_ON_CAST(0, WASM_GLOBAL_GET(rtt_index)),
+ WASM_GLOBAL_GET(rtt_index), WASM_GC_OP(kExprRefCast),
+
+ // Not executed due to the branch.
+ WASM_LOCAL_SET(0, WASM_I32V(333))),
+ WASM_GC_OP(kExprStructGet), type_index, 0, WASM_LOCAL_GET(0),
+ kExprI32Add, kExprEnd});
const byte kTestNull = tester.DefineFunction(
- tester.sigs.i_v(), {kWasmI32, kWasmEqRef},
- {WASM_BLOCK(WASM_LOCAL_SET(0, WASM_I32V(111)),
- WASM_LOCAL_GET(1), // Put a nullref onto the value stack.
- // Neither of these branches is taken for nullref.
- WASM_BR_ON_CAST(0, WASM_RTT_CANON(kI31RefCode)),
- WASM_LOCAL_SET(0, WASM_I32V(222)),
- WASM_BR_ON_CAST(0, WASM_GLOBAL_GET(rtt_index)), WASM_DROP,
- WASM_LOCAL_SET(0, WASM_I32V(333))), // Final result.
- WASM_LOCAL_GET(0), kExprEnd});
+ tester.sigs.i_v(), {kWasmI32, kDataRefNull},
+ {WASM_BLOCK_R(ValueType::Ref(type_index, kNullable),
+ WASM_LOCAL_SET(0, WASM_I32V(111)),
+ WASM_LOCAL_GET(1), // Put a nullref onto the value stack.
+ // Not taken for nullref.
+ WASM_BR_ON_CAST(0, WASM_GLOBAL_GET(rtt_index)),
+ WASM_RTT_CANON(type_index), WASM_GC_OP(kExprRefCast),
+
+ WASM_LOCAL_SET(0, WASM_I32V(222))), // Final result.
+ WASM_DROP, WASM_LOCAL_GET(0), kExprEnd});
const byte kTypedAfterBranch = tester.DefineFunction(
- tester.sigs.i_v(), {kWasmI32, kWasmEqRef},
+ tester.sigs.i_v(), {kWasmI32, kDataRefNull},
{WASM_LOCAL_SET(1, WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42),
WASM_GLOBAL_GET(rtt_index))),
- WASM_BLOCK(WASM_LOCAL_SET(
+ WASM_BLOCK_I(
+ // The inner block should take the early branch with a struct
+ // on the stack.
+ WASM_BLOCK_R(ValueType::Ref(type_index, kNonNullable),
+ WASM_LOCAL_GET(1),
+ WASM_BR_ON_CAST(0, WASM_GLOBAL_GET(rtt_index)),
+ // Returning 123 is the unreachable failure case.
+ WASM_I32V(123), WASM_BR(1)),
// The outer block catches the struct left behind by the inner block
// and reads its field.
- 0,
- WASM_STRUCT_GET(
- type_index, 0,
- // The inner block should take the early branch with a struct
- // on the stack.
- WASM_BLOCK_R(ValueType::Ref(type_index, kNonNullable),
- WASM_LOCAL_GET(1),
- WASM_BR_ON_CAST(0, WASM_GLOBAL_GET(rtt_index)),
- // Returning 123 is the unreachable failure case.
- WASM_LOCAL_SET(0, WASM_I32V(123)), WASM_BR(1))))),
- WASM_LOCAL_GET(0), kExprEnd});
+ WASM_GC_OP(kExprStructGet), type_index, 0),
+ kExprEnd});
tester.CompileModule();
tester.CheckResult(kTestStruct, 222);
- tester.CheckResult(kTestI31, 222);
- tester.CheckResult(kTestNull, 333);
+ tester.CheckResult(kTestNull, 222);
tester.CheckResult(kTypedAfterBranch, 42);
}
WASM_COMPILED_EXEC_TEST(WasmRefEq) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
byte type_index = tester.DefineStruct({F(kWasmI32, true), F(kWasmI32, true)});
ValueType kRefTypes[] = {ref(type_index)};
ValueType kOptRefType = optref(type_index);
@@ -465,7 +453,6 @@ WASM_COMPILED_EXEC_TEST(WasmRefEq) {
WASM_COMPILED_EXEC_TEST(WasmPackedStructU) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte type_index = tester.DefineStruct(
{F(kWasmI8, true), F(kWasmI16, true), F(kWasmI32, true)});
@@ -503,7 +490,6 @@ WASM_COMPILED_EXEC_TEST(WasmPackedStructU) {
WASM_COMPILED_EXEC_TEST(WasmPackedStructS) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte type_index = tester.DefineStruct(
{F(kWasmI8, true), F(kWasmI16, true), F(kWasmI32, true)});
@@ -621,7 +607,6 @@ TEST(WasmLetInstruction) {
WASM_COMPILED_EXEC_TEST(WasmBasicArray) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte type_index = tester.DefineArray(wasm::kWasmI32, true);
ValueType kRefTypes[] = {ref(type_index)};
@@ -697,7 +682,6 @@ WASM_COMPILED_EXEC_TEST(WasmBasicArray) {
WASM_COMPILED_EXEC_TEST(WasmPackedArrayU) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte array_index = tester.DefineArray(kWasmI8, true);
ValueType array_type = optref(array_index);
@@ -733,7 +717,6 @@ WASM_COMPILED_EXEC_TEST(WasmPackedArrayU) {
WASM_COMPILED_EXEC_TEST(WasmPackedArrayS) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte array_index = tester.DefineArray(kWasmI16, true);
ValueType array_type = optref(array_index);
@@ -769,7 +752,6 @@ WASM_COMPILED_EXEC_TEST(WasmPackedArrayS) {
WASM_COMPILED_EXEC_TEST(NewDefault) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte struct_type = tester.DefineStruct(
{F(wasm::kWasmI32, true), F(wasm::kWasmF64, true), F(optref(0), true)});
const byte array_type = tester.DefineArray(wasm::kWasmI32, true);
@@ -801,17 +783,18 @@ WASM_COMPILED_EXEC_TEST(NewDefault) {
tester.CheckResult(allocate_array, 0);
}
-TEST(BasicRTT) {
- WasmGCTester tester;
+WASM_COMPILED_EXEC_TEST(BasicRtt) {
+ WasmGCTester tester(execution_tier);
+
const byte type_index = tester.DefineStruct({F(wasm::kWasmI32, true)});
const byte subtype_index =
tester.DefineStruct({F(wasm::kWasmI32, true), F(wasm::kWasmI32, true)});
- ValueType kRttTypes[] = {ValueType::Rtt(type_index, 1)};
+
+ ValueType kRttTypes[] = {ValueType::Rtt(type_index, 0)};
FunctionSig sig_t_v(1, 0, kRttTypes);
- ValueType kRttSubtypes[] = {
- ValueType::Rtt(static_cast<HeapType>(subtype_index), 2)};
+ ValueType kRttSubtypes[] = {ValueType::Rtt(subtype_index, 1)};
FunctionSig sig_t2_v(1, 0, kRttSubtypes);
- ValueType kRttTypesDeeper[] = {ValueType::Rtt(type_index, 2)};
+ ValueType kRttTypesDeeper[] = {ValueType::Rtt(type_index, 1)};
FunctionSig sig_t3_v(1, 0, kRttTypesDeeper);
ValueType kRefTypes[] = {ref(type_index)};
FunctionSig sig_q_v(1, 0, kRefTypes);
@@ -821,43 +804,34 @@ TEST(BasicRTT) {
const byte kRttSub = tester.DefineFunction(
&sig_t2_v, {},
{WASM_RTT_SUB(subtype_index, WASM_RTT_CANON(type_index)), kExprEnd});
- const byte kRttSubGeneric = tester.DefineFunction(
- &sig_t3_v, {},
- {WASM_RTT_SUB(type_index, WASM_RTT_CANON(kEqRefCode)), kExprEnd});
const byte kStructWithRtt = tester.DefineFunction(
&sig_q_v, {},
{WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42),
WASM_RTT_CANON(type_index)),
kExprEnd});
+
const int kFieldIndex = 1;
- const int kStructIndexCode = 1; // Shifted in 'let' block.
- const int kRttIndexCode = 0; // Let-bound, hence first local.
+ const int kStructIndexCode = 0;
// This implements the following function:
// var local_struct: type0;
- // let (local_rtt = rtt.sub(rtt.canon(type0), type1) in {
- // local_struct = new type1 with rtt 'local_rtt';
- // return (ref.test local_struct local_rtt) +
- // ((ref.cast local_struct local_rtt)[field0]);
+ // local_struct = new type1 with rtt 'kRttSub()';
+ // return (ref.test local_struct kRttSub()) +
+ // ((ref.cast local_struct kRttSub())[field0]);
// }
// The expected return value is 1+42 = 43.
const byte kRefCast = tester.DefineFunction(
tester.sigs.i_v(), {optref(type_index)},
- {WASM_LET_1_I(
- WASM_RTT(2, subtype_index),
- WASM_RTT_SUB(subtype_index, WASM_RTT_CANON(type_index)),
- WASM_LOCAL_SET(kStructIndexCode,
- WASM_STRUCT_NEW_WITH_RTT(
- subtype_index, WASM_I32V(11), WASM_I32V(42),
- WASM_LOCAL_GET(kRttIndexCode))),
- WASM_I32_ADD(
- WASM_REF_TEST(type_index, subtype_index,
- WASM_LOCAL_GET(kStructIndexCode),
- WASM_LOCAL_GET(kRttIndexCode)),
- WASM_STRUCT_GET(subtype_index, kFieldIndex,
- WASM_REF_CAST(type_index, subtype_index,
- WASM_LOCAL_GET(kStructIndexCode),
- WASM_LOCAL_GET(kRttIndexCode)))),
- kExprEnd)});
+ {WASM_LOCAL_SET(
+ kStructIndexCode,
+ WASM_STRUCT_NEW_WITH_RTT(subtype_index, WASM_I32V(11), WASM_I32V(42),
+ WASM_CALL_FUNCTION0(kRttSub))),
+ WASM_I32_ADD(
+ WASM_REF_TEST(WASM_LOCAL_GET(kStructIndexCode),
+ WASM_CALL_FUNCTION0(kRttSub)),
+ WASM_STRUCT_GET(subtype_index, kFieldIndex,
+ WASM_REF_CAST(WASM_LOCAL_GET(kStructIndexCode),
+ WASM_CALL_FUNCTION0(kRttSub)))),
+ kExprEnd});
tester.CompileModule();
@@ -875,7 +849,6 @@ TEST(BasicRTT) {
tester.GetResultObject(kRttSub).ToHandleChecked();
CHECK(subref_result->IsMap());
Handle<Map> submap = Handle<Map>::cast(subref_result);
- CHECK_EQ(*map, submap->wasm_type_info().parent());
CHECK_EQ(reinterpret_cast<Address>(
tester.instance()->module()->struct_type(subtype_index)),
submap->wasm_type_info().foreign_address());
@@ -883,12 +856,6 @@ TEST(BasicRTT) {
tester.GetResultObject(kRttSub).ToHandleChecked();
CHECK(subref_result.is_identical_to(subref_result_canonicalized));
- Handle<Object> sub_generic_1 =
- tester.GetResultObject(kRttSubGeneric).ToHandleChecked();
- Handle<Object> sub_generic_2 =
- tester.GetResultObject(kRttSubGeneric).ToHandleChecked();
- CHECK(sub_generic_1.is_identical_to(sub_generic_2));
-
Handle<Object> s = tester.GetResultObject(kStructWithRtt).ToHandleChecked();
CHECK(s->IsWasmStruct());
CHECK_EQ(Handle<WasmStruct>::cast(s)->map(), *map);
@@ -896,84 +863,85 @@ TEST(BasicRTT) {
tester.CheckResult(kRefCast, 43);
}
-WASM_COMPILED_EXEC_TEST(AnyRefRtt) {
+WASM_EXEC_TEST(NoDepthRtt) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
-
- ValueType any_rtt_0_type = ValueType::Rtt(HeapType::kAny, 0);
- FunctionSig sig_any_canon(1, 0, &any_rtt_0_type);
- byte kAnyRttCanon = tester.DefineFunction(
- &sig_any_canon, {}, {WASM_RTT_CANON(kAnyRefCode), kExprEnd});
-
- ValueType any_rtt_1_type = ValueType::Rtt(HeapType::kAny, 1);
- FunctionSig sig_any_sub(1, 0, &any_rtt_1_type);
- byte kAnyRttSub = tester.DefineFunction(
- &sig_any_sub, {},
- {WASM_RTT_SUB(kAnyRefCode, WASM_RTT_CANON(kAnyRefCode)), kExprEnd});
-
- ValueType func_rtt_1_type = ValueType::Rtt(HeapType::kFunc, 1);
- FunctionSig sig_func_sub(1, 0, &func_rtt_1_type);
- byte kFuncRttSub = tester.DefineFunction(
- &sig_func_sub, {},
- {WASM_RTT_SUB(kFuncRefCode, WASM_RTT_CANON(kAnyRefCode)), kExprEnd});
-
- ValueType eq_rtt_1_type = ValueType::Rtt(HeapType::kEq, 1);
- FunctionSig sig_eq_sub(1, 0, &eq_rtt_1_type);
- byte kEqRttSub = tester.DefineFunction(
- &sig_eq_sub, {},
- {WASM_RTT_SUB(kEqRefCode, WASM_RTT_CANON(kAnyRefCode)), kExprEnd});
- const byte type_index = tester.DefineArray(kWasmI32, true);
- ValueType array_rtt_type = ValueType::Rtt(type_index, 1);
- FunctionSig sig_array_canon(1, 0, &array_rtt_type);
- byte kArrayRttCanon = tester.DefineFunction(
- &sig_array_canon, {}, {WASM_RTT_CANON(type_index), kExprEnd});
-
- byte kCheckArrayAgainstAny = tester.DefineFunction(
- tester.sigs.i_v(), {kWasmAnyRef},
- {WASM_LOCAL_SET(0, WASM_ARRAY_NEW_DEFAULT(type_index, WASM_I32V(5),
- WASM_RTT_CANON(type_index))),
- WASM_REF_TEST(kAnyRefCode, type_index, WASM_LOCAL_GET(0),
- WASM_RTT_CANON(type_index)),
+ const byte type_index = tester.DefineStruct({F(wasm::kWasmI32, true)});
+ const byte subtype_index =
+ tester.DefineStruct({F(wasm::kWasmI32, true), F(wasm::kWasmI32, true)});
+ const byte empty_struct_index = tester.DefineStruct({});
+
+ ValueType kRttSubtypeNoDepth = ValueType::Rtt(subtype_index);
+ FunctionSig sig_t2_v_nd(1, 0, &kRttSubtypeNoDepth);
+
+ const byte kRttSubtypeCanon = tester.DefineFunction(
+ &sig_t2_v_nd, {}, {WASM_RTT_CANON(subtype_index), kExprEnd});
+ const byte kRttSubtypeSub = tester.DefineFunction(
+ &sig_t2_v_nd, {},
+ {WASM_RTT_SUB(subtype_index, WASM_RTT_CANON(type_index)), kExprEnd});
+
+ const byte kTestCanon = tester.DefineFunction(
+ tester.sigs.i_v(), {optref(type_index)},
+ {WASM_LOCAL_SET(0, WASM_STRUCT_NEW_WITH_RTT(
+ subtype_index, WASM_I32V(11), WASM_I32V(42),
+ WASM_RTT_CANON(subtype_index))),
+ WASM_REF_TEST(WASM_LOCAL_GET(0), WASM_CALL_FUNCTION0(kRttSubtypeCanon)),
kExprEnd});
- byte kCheckAnyAgainstAny = tester.DefineFunction(
- tester.sigs.i_v(), {kWasmAnyRef},
- {WASM_LOCAL_SET(0, WASM_ARRAY_NEW_DEFAULT(type_index, WASM_I32V(5),
- WASM_RTT_CANON(type_index))),
- WASM_REF_TEST(kAnyRefCode, kAnyRefCode, WASM_LOCAL_GET(0),
- WASM_RTT_CANON(kAnyRefCode)),
+ const byte kTestSub = tester.DefineFunction(
+ tester.sigs.i_v(), {optref(type_index)},
+ {WASM_LOCAL_SET(
+ 0, WASM_STRUCT_NEW_WITH_RTT(
+ subtype_index, WASM_I32V(11), WASM_I32V(42),
+ WASM_RTT_SUB(subtype_index, WASM_RTT_CANON(type_index)))),
+ WASM_REF_TEST(WASM_LOCAL_GET(0), WASM_CALL_FUNCTION0(kRttSubtypeSub)),
kExprEnd});
- tester.CompileModule();
+ const byte kTestSubVsEmpty = tester.DefineFunction(
+ tester.sigs.i_v(), {optref(type_index)},
+ {WASM_LOCAL_SET(0, WASM_STRUCT_NEW_WITH_RTT(
+ subtype_index, WASM_I32V(11), WASM_I32V(42),
+ WASM_RTT_SUB(subtype_index,
+ WASM_RTT_CANON(empty_struct_index)))),
+ WASM_REF_TEST(WASM_LOCAL_GET(0), WASM_CALL_FUNCTION0(kRttSubtypeSub)),
+ kExprEnd});
- // Check (rtt.canon any).
- Handle<Object> result_any_canon =
- tester.GetResultObject(kAnyRttCanon).ToHandleChecked();
- CHECK(result_any_canon->IsMap());
- Handle<Map> any_map = Handle<Map>::cast(result_any_canon);
- CHECK_EQ(any_map->wasm_type_info().parent(),
- tester.isolate()->root(RootIndex::kNullMap));
- CHECK_EQ(any_map->wasm_type_info().supertypes().length(), 0);
-
- for (byte func_index : {kArrayRttCanon, kAnyRttSub, kFuncRttSub, kEqRttSub}) {
- Handle<Object> result =
- tester.GetResultObject(func_index).ToHandleChecked();
- CHECK(result->IsMap());
- Handle<Map> map = Handle<Map>::cast(result);
- // Its parent should be (rtt.canon any).
- CHECK_EQ(map->wasm_type_info().parent(), *any_map);
- CHECK_EQ(map->wasm_type_info().supertypes().get(0), *any_map);
- CHECK_EQ(map->wasm_type_info().supertypes().length(), 1);
- }
+ const byte kTestSubVsCanon = tester.DefineFunction(
+ tester.sigs.i_v(), {optref(type_index)},
+ {WASM_LOCAL_SET(0, WASM_STRUCT_NEW_WITH_RTT(
+ subtype_index, WASM_I32V(11), WASM_I32V(42),
+ WASM_RTT_CANON(subtype_index))),
+ WASM_REF_TEST(WASM_LOCAL_GET(0), WASM_CALL_FUNCTION0(kRttSubtypeSub)),
+ kExprEnd});
- tester.CheckResult(kCheckArrayAgainstAny, 1);
- tester.CheckResult(kCheckAnyAgainstAny, 1);
+ const byte kTestCanonVsSub = tester.DefineFunction(
+ tester.sigs.i_v(), {optref(type_index)},
+ {WASM_LOCAL_SET(
+ 0, WASM_STRUCT_NEW_WITH_RTT(
+ subtype_index, WASM_I32V(11), WASM_I32V(42),
+ WASM_RTT_SUB(subtype_index, WASM_RTT_CANON(type_index)))),
+ WASM_REF_TEST(WASM_LOCAL_GET(0), WASM_CALL_FUNCTION0(kRttSubtypeCanon)),
+ kExprEnd});
+
+ const byte kTestSuperVsSub = tester.DefineFunction(
+ tester.sigs.i_v(), {optref(type_index)},
+ {WASM_LOCAL_SET(0, WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42),
+ WASM_RTT_CANON(type_index))),
+ WASM_REF_TEST(WASM_LOCAL_GET(0), WASM_CALL_FUNCTION0(kRttSubtypeCanon)),
+ kExprEnd});
+
+ tester.CompileModule();
+
+ tester.CheckResult(kTestCanon, 1);
+ tester.CheckResult(kTestSub, 1);
+ tester.CheckResult(kTestSubVsEmpty, 0);
+ tester.CheckResult(kTestSubVsCanon, 0);
+ tester.CheckResult(kTestCanonVsSub, 0);
+ tester.CheckResult(kTestSuperVsSub, 0);
}
WASM_COMPILED_EXEC_TEST(ArrayNewMap) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte type_index = tester.DefineArray(kWasmI32, true);
@@ -985,7 +953,7 @@ WASM_COMPILED_EXEC_TEST(ArrayNewMap) {
WASM_RTT_CANON(type_index)),
kExprEnd});
- ValueType rtt_type = ValueType::Rtt(type_index, 1);
+ ValueType rtt_type = ValueType::Rtt(type_index, 0);
FunctionSig rtt_canon_sig(1, 0, &rtt_type);
const byte kRttCanon = tester.DefineFunction(
&rtt_canon_sig, {}, {WASM_RTT_CANON(type_index), kExprEnd});
@@ -1000,8 +968,8 @@ WASM_COMPILED_EXEC_TEST(ArrayNewMap) {
CHECK_EQ(Handle<WasmArray>::cast(result)->map(), *map);
}
-TEST(FunctionRefs) {
- WasmGCTester tester;
+WASM_COMPILED_EXEC_TEST(FunctionRefs) {
+ WasmGCTester tester(execution_tier);
const byte func_index =
tester.DefineFunction(tester.sigs.i_v(), {}, {WASM_I32V(42), kExprEnd});
const byte sig_index = 0;
@@ -1012,26 +980,18 @@ TEST(FunctionRefs) {
tester.AddGlobal(ValueType::Ref(sig_index, kNullable), false,
WasmInitExpr::RefFuncConst(func_index));
- ValueType func_type = ValueType::Ref(sig_index, kNonNullable);
+ ValueType func_type = ValueType::Ref(sig_index, kNullable);
FunctionSig sig_func(1, 0, &func_type);
- ValueType rtt1 = ValueType::Rtt(sig_index, 1);
- FunctionSig sig_rtt1(1, 0, &rtt1);
+ ValueType rtt0 = ValueType::Rtt(sig_index, 0);
+ FunctionSig sig_rtt0(1, 0, &rtt0);
const byte rtt_canon = tester.DefineFunction(
- &sig_rtt1, {}, {WASM_RTT_CANON(sig_index), kExprEnd});
-
- ValueType rtt2 = ValueType::Rtt(sig_index, 2);
- FunctionSig sig_rtt2(1, 0, &rtt2);
- const byte rtt_sub = tester.DefineFunction(
- &sig_rtt2, {},
- {WASM_RTT_SUB(sig_index, WASM_RTT_CANON(kFuncRefCode)), kExprEnd});
+ &sig_rtt0, {}, {WASM_RTT_CANON(sig_index), kExprEnd});
const byte cast = tester.DefineFunction(
&sig_func, {kWasmFuncRef},
{WASM_LOCAL_SET(0, WASM_REF_FUNC(func_index)),
- WASM_REF_CAST(kFuncRefCode, sig_index, WASM_LOCAL_GET(0),
- WASM_RTT_CANON(sig_index)),
- kExprEnd});
+ WASM_REF_CAST(WASM_LOCAL_GET(0), WASM_RTT_CANON(sig_index)), kExprEnd});
const byte cast_reference = tester.DefineFunction(
&sig_func, {}, {WASM_REF_FUNC(sig_index), kExprEnd});
@@ -1039,8 +999,19 @@ TEST(FunctionRefs) {
const byte test = tester.DefineFunction(
tester.sigs.i_v(), {kWasmFuncRef},
{WASM_LOCAL_SET(0, WASM_REF_FUNC(func_index)),
- WASM_REF_TEST(kFuncRefCode, other_sig_index, WASM_LOCAL_GET(0),
- WASM_RTT_CANON(other_sig_index)),
+ WASM_REF_TEST(WASM_LOCAL_GET(0), WASM_RTT_CANON(sig_index)), kExprEnd});
+
+ const byte test_fail_1 = tester.DefineFunction(
+ tester.sigs.i_v(), {kWasmFuncRef},
+ {WASM_LOCAL_SET(0, WASM_REF_FUNC(func_index)),
+ WASM_REF_TEST(WASM_LOCAL_GET(0), WASM_RTT_CANON(other_sig_index)),
+ kExprEnd});
+
+ const byte test_fail_2 = tester.DefineFunction(
+ tester.sigs.i_v(), {kWasmFuncRef},
+ {WASM_LOCAL_SET(0, WASM_REF_FUNC(func_index)),
+ WASM_REF_TEST(WASM_LOCAL_GET(0),
+ WASM_RTT_SUB(sig_index, WASM_RTT_CANON(sig_index))),
kExprEnd});
tester.CompileModule();
@@ -1051,11 +1022,6 @@ TEST(FunctionRefs) {
Handle<Map> map_canon = Handle<Map>::cast(result_canon);
CHECK(map_canon->IsJSFunctionMap());
- Handle<Object> result_sub = tester.GetResultObject(rtt_sub).ToHandleChecked();
- CHECK(result_sub->IsMap());
- Handle<Map> map_sub = Handle<Map>::cast(result_sub);
- CHECK(map_sub->IsJSFunctionMap());
-
Handle<Object> result_cast = tester.GetResultObject(cast).ToHandleChecked();
CHECK(result_cast->IsJSFunction());
Handle<JSFunction> cast_function = Handle<JSFunction>::cast(result_cast);
@@ -1069,11 +1035,13 @@ TEST(FunctionRefs) {
CHECK_EQ(cast_function->code().raw_instruction_start(),
cast_function_reference->code().raw_instruction_start());
- tester.CheckResult(test, 0);
+ tester.CheckResult(test, 1);
+ tester.CheckResult(test_fail_1, 0);
+ tester.CheckResult(test_fail_2, 0);
}
-TEST(CallRef) {
- WasmGCTester tester;
+WASM_COMPILED_EXEC_TEST(CallRef) {
+ WasmGCTester tester(execution_tier);
byte callee = tester.DefineFunction(
tester.sigs.i_ii(), {},
{WASM_I32_ADD(WASM_LOCAL_GET(0), WASM_LOCAL_GET(1)), kExprEnd});
@@ -1093,29 +1061,154 @@ TEST(CallRef) {
WASM_COMPILED_EXEC_TEST(RefTestCastNull) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
byte type_index = tester.DefineStruct({F(wasm::kWasmI32, true)});
const byte kRefTestNull = tester.DefineFunction(
tester.sigs.i_v(), {},
- {WASM_REF_TEST(type_index, type_index, WASM_REF_NULL(type_index),
- WASM_RTT_CANON(type_index)),
+ {WASM_REF_TEST(WASM_REF_NULL(type_index), WASM_RTT_CANON(type_index)),
kExprEnd});
const byte kRefCastNull = tester.DefineFunction(
- tester.sigs.i_i(), // Argument and return value ignored
- {},
- {WASM_REF_CAST(type_index, type_index, WASM_REF_NULL(type_index),
- WASM_RTT_CANON(type_index)),
- kExprDrop, WASM_I32V(0), kExprEnd});
+ tester.sigs.i_v(), {},
+ {WASM_REF_IS_NULL(WASM_REF_CAST(WASM_REF_NULL(type_index),
+ WASM_RTT_CANON(type_index))),
+ kExprEnd});
tester.CompileModule();
tester.CheckResult(kRefTestNull, 0);
- tester.CheckHasThrown(kRefCastNull, 0);
+ tester.CheckResult(kRefCastNull, 1);
+}
+
+WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) {
+ WasmGCTester tester(execution_tier);
+
+ byte array_index = tester.DefineArray(kWasmI32, true);
+ byte function_index =
+ tester.DefineFunction(tester.sigs.v_v(), {}, {kExprEnd});
+ byte sig_index = 1;
+
+ // This is just so func_index counts as "declared".
+ tester.AddGlobal(ValueType::Ref(sig_index, kNullable), false,
+ WasmInitExpr::RefFuncConst(function_index));
+
+ byte kDataCheckNull = tester.DefineFunction(
+ tester.sigs.i_v(), {},
+ {WASM_REF_IS_DATA(WASM_REF_NULL(kAnyRefCode)), kExprEnd});
+ byte kFuncCheckNull = tester.DefineFunction(
+ tester.sigs.i_v(), {},
+ {WASM_REF_IS_FUNC(WASM_REF_NULL(kAnyRefCode)), kExprEnd});
+ byte kI31CheckNull = tester.DefineFunction(
+ tester.sigs.i_v(), {},
+ {WASM_REF_IS_I31(WASM_REF_NULL(kAnyRefCode)), kExprEnd});
+
+ byte kDataCastNull =
+ tester.DefineFunction(tester.sigs.i_v(), {},
+ {WASM_REF_AS_DATA(WASM_REF_NULL(kAnyRefCode)),
+ WASM_DROP, WASM_I32V(1), kExprEnd});
+ byte kFuncCastNull =
+ tester.DefineFunction(tester.sigs.i_v(), {},
+ {WASM_REF_AS_FUNC(WASM_REF_NULL(kAnyRefCode)),
+ WASM_DROP, WASM_I32V(1), kExprEnd});
+ byte kI31CastNull =
+ tester.DefineFunction(tester.sigs.i_v(), {},
+ {WASM_REF_AS_I31(WASM_REF_NULL(kAnyRefCode)),
+ WASM_DROP, WASM_I32V(1), kExprEnd});
+
+#define TYPE_CHECK(type, value) \
+ tester.DefineFunction(tester.sigs.i_v(), {kWasmAnyRef}, \
+ {WASM_LOCAL_SET(0, WASM_SEQ(value)), \
+ WASM_REF_IS_##type(WASM_LOCAL_GET(0)), kExprEnd})
+
+ byte kDataCheckSuccess =
+ TYPE_CHECK(DATA, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10),
+ WASM_RTT_CANON(array_index)));
+ byte kDataCheckFailure = TYPE_CHECK(DATA, WASM_I31_NEW(WASM_I32V(42)));
+ byte kFuncCheckSuccess = TYPE_CHECK(FUNC, WASM_REF_FUNC(function_index));
+ byte kFuncCheckFailure =
+ TYPE_CHECK(FUNC, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10),
+ WASM_RTT_CANON(array_index)));
+ byte kI31CheckSuccess = TYPE_CHECK(I31, WASM_I31_NEW(WASM_I32V(42)));
+ byte kI31CheckFailure =
+ TYPE_CHECK(I31, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10),
+ WASM_RTT_CANON(array_index)));
+#undef TYPE_CHECK
+
+#define TYPE_CAST(type, value) \
+ tester.DefineFunction(tester.sigs.i_v(), {kWasmAnyRef}, \
+ {WASM_LOCAL_SET(0, WASM_SEQ(value)), \
+ WASM_REF_AS_##type(WASM_LOCAL_GET(0)), WASM_DROP, \
+ WASM_I32V(1), kExprEnd})
+
+ byte kDataCastSuccess =
+ TYPE_CAST(DATA, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10),
+ WASM_RTT_CANON(array_index)));
+ byte kDataCastFailure = TYPE_CAST(DATA, WASM_I31_NEW(WASM_I32V(42)));
+ byte kFuncCastSuccess = TYPE_CAST(FUNC, WASM_REF_FUNC(function_index));
+ byte kFuncCastFailure =
+ TYPE_CAST(FUNC, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10),
+ WASM_RTT_CANON(array_index)));
+ byte kI31CastSuccess = TYPE_CAST(I31, WASM_I31_NEW(WASM_I32V(42)));
+ byte kI31CastFailure =
+ TYPE_CAST(I31, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10),
+ WASM_RTT_CANON(array_index)));
+#undef TYPE_CAST
+
+// If the branch is not taken, we return 0. If it is taken, then the respective
+// type check should succeed, and we return 1.
+#define BR_ON(TYPE, type, value) \
+ tester.DefineFunction( \
+ tester.sigs.i_v(), {kWasmAnyRef}, \
+ {WASM_LOCAL_SET(0, WASM_SEQ(value)), \
+ WASM_REF_IS_##TYPE(WASM_BLOCK_R( \
+ kWasm##type##Ref, WASM_BR_ON_##TYPE(0, WASM_LOCAL_GET(0)), \
+ WASM_RETURN(WASM_I32V(0)))), \
+ kExprEnd})
+
+ byte kBrOnDataTaken =
+ BR_ON(DATA, Data,
+ WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10),
+ WASM_RTT_CANON(array_index)));
+ byte kBrOnDataNotTaken = BR_ON(DATA, Data, WASM_REF_FUNC(function_index));
+ byte kBrOnFuncTaken = BR_ON(FUNC, Func, WASM_REF_FUNC(function_index));
+ byte kBrOnFuncNotTaken = BR_ON(FUNC, Func, WASM_I31_NEW(WASM_I32V(42)));
+ byte kBrOnI31Taken = BR_ON(I31, I31, WASM_I31_NEW(WASM_I32V(42)));
+ byte kBrOnI31NotTaken =
+ BR_ON(I31, I31,
+ WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10),
+ WASM_RTT_CANON(array_index)));
+#undef BR_ON
+
+ tester.CompileModule();
+
+ tester.CheckResult(kDataCheckNull, 0);
+ tester.CheckHasThrown(kDataCastNull);
+ tester.CheckResult(kDataCheckSuccess, 1);
+ tester.CheckResult(kDataCheckFailure, 0);
+ tester.CheckResult(kDataCastSuccess, 1);
+ tester.CheckHasThrown(kDataCastFailure);
+ tester.CheckResult(kBrOnDataTaken, 1);
+ tester.CheckResult(kBrOnDataNotTaken, 0);
+
+ tester.CheckResult(kFuncCheckNull, 0);
+ tester.CheckHasThrown(kFuncCastNull);
+ tester.CheckResult(kFuncCheckSuccess, 1);
+ tester.CheckResult(kFuncCheckFailure, 0);
+ tester.CheckResult(kFuncCastSuccess, 1);
+ tester.CheckHasThrown(kFuncCastFailure);
+ tester.CheckResult(kBrOnFuncTaken, 1);
+ tester.CheckResult(kBrOnFuncNotTaken, 0);
+
+ tester.CheckResult(kI31CheckNull, 0);
+ tester.CheckHasThrown(kI31CastNull);
+ tester.CheckResult(kI31CheckSuccess, 1);
+ tester.CheckResult(kI31CheckFailure, 0);
+ tester.CheckResult(kI31CastSuccess, 1);
+ tester.CheckHasThrown(kI31CastFailure);
+ tester.CheckResult(kBrOnI31Taken, 1);
+ tester.CheckResult(kBrOnI31NotTaken, 0);
}
WASM_COMPILED_EXEC_TEST(BasicI31) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte kSigned = tester.DefineFunction(
tester.sigs.i_i(), {},
{WASM_I31_GET_S(WASM_I31_NEW(WASM_LOCAL_GET(0))), kExprEnd});
@@ -1133,89 +1226,30 @@ WASM_COMPILED_EXEC_TEST(BasicI31) {
tester.CheckResult(kUnsigned, 0x7FFFFFFF, 0x7FFFFFFF);
}
-WASM_COMPILED_EXEC_TEST(I31Casts) {
- WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
- const byte struct_type = tester.DefineStruct({F(wasm::kWasmI32, true)});
- const byte i31_rtt =
- tester.AddGlobal(ValueType::Rtt(HeapType::kI31, 1), false,
- WasmInitExpr::RttCanon(HeapType::kI31));
- const byte struct_rtt =
- tester.AddGlobal(ValueType::Rtt(struct_type, 1), false,
- WasmInitExpr::RttCanon(
- static_cast<HeapType::Representation>(struct_type)));
- // Adds the result of a successful typecheck to the untagged value, i.e.
- // should return 1 + 42 = 43.
- const byte kTestAndCastSuccess = tester.DefineFunction(
- tester.sigs.i_v(), {kWasmEqRef},
- {WASM_LOCAL_SET(0, WASM_I31_NEW(WASM_I32V(42))),
- WASM_I32_ADD(WASM_REF_TEST(kEqRefCode, kI31RefCode, WASM_LOCAL_GET(0),
- WASM_GLOBAL_GET(i31_rtt)),
- WASM_I31_GET_S(WASM_REF_CAST(kEqRefCode, kI31RefCode,
- WASM_LOCAL_GET(0),
- WASM_GLOBAL_GET(i31_rtt)))),
- kExprEnd});
- // Adds the results of two unsuccessful type checks (an i31ref is not a
- // struct, nor the other way round).
- const byte kTestFalse = tester.DefineFunction(
- tester.sigs.i_v(), {},
- {WASM_I32_ADD(
- WASM_REF_TEST(kEqRefCode, kI31RefCode,
- WASM_STRUCT_NEW_WITH_RTT(struct_type, WASM_I32V(42),
- WASM_GLOBAL_GET(struct_rtt)),
- WASM_GLOBAL_GET(i31_rtt)),
- WASM_REF_TEST(kEqRefCode, struct_type, WASM_I31_NEW(WASM_I32V(23)),
- WASM_GLOBAL_GET(struct_rtt))),
- kExprEnd});
- // Tries to cast an i31ref to a struct, which should trap.
- const byte kCastI31ToStruct = tester.DefineFunction(
- tester.sigs.i_i(), // Argument and return value ignored
- {},
- {WASM_STRUCT_GET(
- struct_type, 0,
- WASM_REF_CAST(kEqRefCode, struct_type, WASM_I31_NEW(WASM_I32V(42)),
- WASM_GLOBAL_GET(struct_rtt))),
- kExprEnd});
- // Tries to cast a struct to i31ref, which should trap.
- const byte kCastStructToI31 = tester.DefineFunction(
- tester.sigs.i_i(), // Argument and return value ignored
- {},
- {WASM_I31_GET_S(
- WASM_REF_CAST(kEqRefCode, kI31RefCode,
- WASM_STRUCT_NEW_WITH_RTT(struct_type, WASM_I32V(42),
- WASM_GLOBAL_GET(struct_rtt)),
- WASM_GLOBAL_GET(i31_rtt))),
- kExprEnd});
- tester.CompileModule();
- tester.CheckResult(kTestAndCastSuccess, 43);
- tester.CheckResult(kTestFalse, 0);
- tester.CheckHasThrown(kCastI31ToStruct, 0);
- tester.CheckHasThrown(kCastStructToI31, 0);
-}
-
// This flushed out a few bugs, so it serves as a regression test. It can also
// be modified (made to run longer) to measure performance of casts.
WASM_COMPILED_EXEC_TEST(CastsBenchmark) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte SuperType = tester.DefineStruct({F(wasm::kWasmI32, true)});
const byte SubType =
tester.DefineStruct({F(wasm::kWasmI32, true), F(wasm::kWasmI32, true)});
- const byte ListType = tester.DefineArray(wasm::kWasmEqRef, true);
+
+ ValueType kDataRefNull = ValueType::Ref(HeapType::kData, kNullable);
+ const byte ListType = tester.DefineArray(kDataRefNull, true);
const byte List =
tester.AddGlobal(ValueType::Ref(ListType, kNullable), true,
WasmInitExpr::RefNullConst(
static_cast<HeapType::Representation>(ListType)));
const byte RttSuper = tester.AddGlobal(
- ValueType::Rtt(SuperType, 1), false,
+ ValueType::Rtt(SuperType, 0), false,
WasmInitExpr::RttCanon(static_cast<HeapType::Representation>(SuperType)));
const byte RttSub = tester.AddGlobal(
- ValueType::Rtt(SubType, 2), false,
+ ValueType::Rtt(SubType, 1), false,
WasmInitExpr::RttSub(static_cast<HeapType::Representation>(SubType),
WasmInitExpr::GlobalGet(RttSuper)));
const byte RttList = tester.AddGlobal(
- ValueType::Rtt(ListType, 1), false,
+ ValueType::Rtt(ListType, 0), false,
WasmInitExpr::RttCanon(static_cast<HeapType::Representation>(ListType)));
const uint32_t kListLength = 1024;
@@ -1273,7 +1307,6 @@ WASM_COMPILED_EXEC_TEST(CastsBenchmark) {
WASM_STRUCT_GET(
SuperType, 0,
WASM_REF_CAST(
- kEqRefCode, SuperType,
WASM_ARRAY_GET(
ListType, WASM_LOCAL_GET(list),
WASM_I32_AND(WASM_LOCAL_GET(i),
@@ -1296,7 +1329,6 @@ WASM_COMPILED_EXEC_TEST(CastsBenchmark) {
WASM_COMPILED_EXEC_TEST(GlobalInitReferencingGlobal) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
const byte from = tester.AddGlobal(kWasmI32, false, WasmInitExpr(42));
const byte to =
tester.AddGlobal(kWasmI32, false, WasmInitExpr::GlobalGet(from));
@@ -1311,7 +1343,6 @@ WASM_COMPILED_EXEC_TEST(GlobalInitReferencingGlobal) {
WASM_COMPILED_EXEC_TEST(IndirectNullSetManually) {
WasmGCTester tester(execution_tier);
- FLAG_experimental_liftoff_extern_ref = true;
byte sig_index = tester.DefineSignature(tester.sigs.i_i());
tester.DefineTable(ValueType::Ref(sig_index, kNullable), 1, 1);
byte func_index = tester.DefineFunction(
@@ -1325,74 +1356,71 @@ WASM_COMPILED_EXEC_TEST(IndirectNullSetManually) {
tester.CheckHasThrown(func_index, 42);
}
-TEST(JsAccess) {
- for (ValueType supertype : {kWasmEqRef, kWasmAnyRef}) {
- WasmGCTester tester;
- const byte type_index = tester.DefineStruct({F(wasm::kWasmI32, true)});
- ValueType kRefType = ref(type_index);
- ValueType kSupertypeToI[] = {kWasmI32, supertype};
- FunctionSig sig_t_v(1, 0, &kRefType);
- FunctionSig sig_super_v(1, 0, &supertype);
- FunctionSig sig_i_super(1, 1, kSupertypeToI);
-
- tester.DefineExportedFunction(
- "disallowed", &sig_t_v,
- {WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42),
- WASM_RTT_CANON(type_index)),
- kExprEnd});
- // Same code, different signature.
- tester.DefineExportedFunction(
- "producer", &sig_super_v,
- {WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42),
- WASM_RTT_CANON(type_index)),
- kExprEnd});
- tester.DefineExportedFunction(
- "consumer", &sig_i_super,
- {WASM_STRUCT_GET(
- type_index, 0,
- WASM_REF_CAST(supertype.value_type_code(), type_index,
- WASM_LOCAL_GET(0), WASM_RTT_CANON(type_index))),
- kExprEnd});
-
- tester.CompileModule();
- Isolate* isolate = tester.isolate();
- TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
- MaybeHandle<Object> maybe_result =
- tester.CallExportedFunction("disallowed", 0, nullptr);
- CHECK(maybe_result.is_null());
- CHECK(try_catch.HasCaught());
- try_catch.Reset();
- isolate->clear_pending_exception();
-
- maybe_result = tester.CallExportedFunction("producer", 0, nullptr);
- if (maybe_result.is_null()) {
- FATAL("Calling 'producer' failed: %s",
- *v8::String::Utf8Value(reinterpret_cast<v8::Isolate*>(isolate),
- try_catch.Message()->Get()));
- }
- {
- Handle<Object> args[] = {maybe_result.ToHandleChecked()};
- maybe_result = tester.CallExportedFunction("consumer", 1, args);
- }
- if (maybe_result.is_null()) {
- FATAL("Calling 'consumer' failed: %s",
- *v8::String::Utf8Value(reinterpret_cast<v8::Isolate*>(isolate),
- try_catch.Message()->Get()));
- }
- Handle<Object> result = maybe_result.ToHandleChecked();
- CHECK(result->IsSmi());
- CHECK_EQ(42, Smi::cast(*result).value());
- // Calling {consumer} with any other object (e.g. the Smi we just got as
- // {result}) should trap.
- {
- Handle<Object> args[] = {result};
- maybe_result = tester.CallExportedFunction("consumer", 1, args);
- }
- CHECK(maybe_result.is_null());
- CHECK(try_catch.HasCaught());
- try_catch.Reset();
- isolate->clear_pending_exception();
+WASM_COMPILED_EXEC_TEST(JsAccess) {
+ WasmGCTester tester(execution_tier);
+ const byte type_index = tester.DefineStruct({F(wasm::kWasmI32, true)});
+ ValueType kRefType = ref(type_index);
+ ValueType kSupertypeToI[] = {kWasmI32, kWasmDataRef};
+ FunctionSig sig_t_v(1, 0, &kRefType);
+ FunctionSig sig_super_v(1, 0, &kWasmDataRef);
+ FunctionSig sig_i_super(1, 1, kSupertypeToI);
+
+ tester.DefineExportedFunction(
+ "disallowed", &sig_t_v,
+ {WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42),
+ WASM_RTT_CANON(type_index)),
+ kExprEnd});
+ // Same code, different signature.
+ tester.DefineExportedFunction(
+ "producer", &sig_super_v,
+ {WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42),
+ WASM_RTT_CANON(type_index)),
+ kExprEnd});
+ tester.DefineExportedFunction(
+ "consumer", &sig_i_super,
+ {WASM_STRUCT_GET(
+ type_index, 0,
+ WASM_REF_CAST(WASM_LOCAL_GET(0), WASM_RTT_CANON(type_index))),
+ kExprEnd});
+
+ tester.CompileModule();
+ Isolate* isolate = tester.isolate();
+ TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
+ MaybeHandle<Object> maybe_result =
+ tester.CallExportedFunction("disallowed", 0, nullptr);
+ CHECK(maybe_result.is_null());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+ isolate->clear_pending_exception();
+
+ maybe_result = tester.CallExportedFunction("producer", 0, nullptr);
+ if (maybe_result.is_null()) {
+ FATAL("Calling 'producer' failed: %s",
+ *v8::String::Utf8Value(reinterpret_cast<v8::Isolate*>(isolate),
+ try_catch.Message()->Get()));
+ }
+ {
+ Handle<Object> args[] = {maybe_result.ToHandleChecked()};
+ maybe_result = tester.CallExportedFunction("consumer", 1, args);
+ }
+ if (maybe_result.is_null()) {
+ FATAL("Calling 'consumer' failed: %s",
+ *v8::String::Utf8Value(reinterpret_cast<v8::Isolate*>(isolate),
+ try_catch.Message()->Get()));
+ }
+ Handle<Object> result = maybe_result.ToHandleChecked();
+ CHECK(result->IsSmi());
+ CHECK_EQ(42, Smi::cast(*result).value());
+ // Calling {consumer} with any other object (e.g. the Smi we just got as
+ // {result}) should trap.
+ {
+ Handle<Object> args[] = {result};
+ maybe_result = tester.CallExportedFunction("consumer", 1, args);
}
+ CHECK(maybe_result.is_null());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+ isolate->clear_pending_exception();
}
} // namespace test_gc
diff --git a/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc b/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc
index 6b888511d9..bfe88180d1 100644
--- a/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc
+++ b/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc
@@ -144,6 +144,11 @@ void CompileJumpTableThunk(Address thunk, Address jump_target) {
__ lw(scratch, MemOperand(scratch, 0));
__ Branch(&exit, ne, scratch, Operand(zero_reg));
__ Jump(jump_target, RelocInfo::NONE);
+#elif V8_TARGET_ARCH_RISCV64
+ __ li(scratch, Operand(stop_bit_address, RelocInfo::NONE));
+ __ Lw(scratch, MemOperand(scratch, 0));
+ __ Branch(&exit, ne, scratch, Operand(zero_reg));
+ __ Jump(jump_target, RelocInfo::NONE);
#else
#error Unsupported architecture
#endif
@@ -232,7 +237,8 @@ TEST(JumpTablePatchingStress) {
constexpr int kNumberOfPatcherThreads = 3;
STATIC_ASSERT(kAssemblerBufferSize >= kJumpTableSize);
- auto buffer = AllocateAssemblerBuffer(kAssemblerBufferSize);
+ auto buffer = AllocateAssemblerBuffer(kAssemblerBufferSize, nullptr,
+ VirtualMemory::kMapAsJittable);
byte* thunk_slot_buffer = buffer->start() + kBufferSlotStartOffset;
std::bitset<kAvailableBufferSlots> used_thunk_slots;
diff --git a/deps/v8/test/cctest/wasm/test-liftoff-inspection.cc b/deps/v8/test/cctest/wasm/test-liftoff-inspection.cc
index c3444b9ae6..f5847d1fb1 100644
--- a/deps/v8/test/cctest/wasm/test-liftoff-inspection.cc
+++ b/deps/v8/test/cctest/wasm/test-liftoff-inspection.cc
@@ -20,15 +20,16 @@ class LiftoffCompileEnvironment {
: isolate_(CcTest::InitIsolateOnce()),
handle_scope_(isolate_),
zone_(isolate_->allocator(), ZONE_NAME),
- module_builder_(&zone_, nullptr, TestExecutionTier::kLiftoff,
- kRuntimeExceptionSupport, kNoLowerSimd) {
+ wasm_runner_(nullptr, TestExecutionTier::kLiftoff, 0,
+ kRuntimeExceptionSupport, kNoLowerSimd) {
// Add a table of length 1, for indirect calls.
- module_builder_.AddIndirectFunctionTable(nullptr, 1);
+ wasm_runner_.builder().AddIndirectFunctionTable(nullptr, 1);
+ // Set tiered down such that we generate debugging code.
+ wasm_runner_.builder().SetTieredDown();
}
struct TestFunction {
- OwnedVector<uint8_t> body_bytes;
- WasmFunction* function;
+ WasmCode* code;
FunctionBody body;
};
@@ -39,17 +40,15 @@ class LiftoffCompileEnvironment {
auto test_func = AddFunction(return_types, param_types, raw_function_bytes);
// Now compile the function with Liftoff two times.
- CompilationEnv env = module_builder_.CreateCompilationEnv();
+ CompilationEnv env = wasm_runner_.builder().CreateCompilationEnv();
WasmFeatures detected1;
WasmFeatures detected2;
- WasmCompilationResult result1 =
- ExecuteLiftoffCompilation(isolate_->allocator(), &env, test_func.body,
- test_func.function->func_index, kNoDebugging,
- isolate_->counters(), &detected1);
- WasmCompilationResult result2 =
- ExecuteLiftoffCompilation(isolate_->allocator(), &env, test_func.body,
- test_func.function->func_index, kNoDebugging,
- isolate_->counters(), &detected2);
+ WasmCompilationResult result1 = ExecuteLiftoffCompilation(
+ isolate_->allocator(), &env, test_func.body, test_func.code->index(),
+ kNoDebugging, isolate_->counters(), &detected1);
+ WasmCompilationResult result2 = ExecuteLiftoffCompilation(
+ isolate_->allocator(), &env, test_func.body, test_func.code->index(),
+ kNoDebugging, isolate_->counters(), &detected2);
CHECK(result1.succeeded());
CHECK(result2.succeeded());
@@ -70,20 +69,20 @@ class LiftoffCompileEnvironment {
std::vector<int> breakpoints = {}) {
auto test_func = AddFunction(return_types, param_types, raw_function_bytes);
- CompilationEnv env = module_builder_.CreateCompilationEnv();
+ CompilationEnv env = wasm_runner_.builder().CreateCompilationEnv();
WasmFeatures detected;
std::unique_ptr<DebugSideTable> debug_side_table_via_compilation;
- ExecuteLiftoffCompilation(CcTest::i_isolate()->allocator(), &env,
- test_func.body, 0, kForDebugging, nullptr,
- &detected, VectorOf(breakpoints),
- &debug_side_table_via_compilation);
+ auto result = ExecuteLiftoffCompilation(
+ CcTest::i_isolate()->allocator(), &env, test_func.body, 0,
+ kForDebugging, nullptr, &detected, VectorOf(breakpoints),
+ &debug_side_table_via_compilation);
+ CHECK(result.succeeded());
// If there are no breakpoint, then {ExecuteLiftoffCompilation} should
// provide the same debug side table.
if (breakpoints.empty()) {
std::unique_ptr<DebugSideTable> debug_side_table =
- GenerateLiftoffDebugSideTable(CcTest::i_isolate()->allocator(), &env,
- test_func.body, 0);
+ GenerateLiftoffDebugSideTable(test_func.code);
CheckTableEquals(*debug_side_table, *debug_side_table_via_compilation);
}
@@ -94,6 +93,7 @@ class LiftoffCompileEnvironment {
static void CheckTableEquals(const DebugSideTable& a,
const DebugSideTable& b) {
CHECK_EQ(a.num_locals(), b.num_locals());
+ CHECK_EQ(a.entries().size(), b.entries().size());
CHECK(std::equal(a.entries().begin(), a.entries().end(),
b.entries().begin(), b.entries().end(),
&CheckEntryEquals));
@@ -102,42 +102,11 @@ class LiftoffCompileEnvironment {
static bool CheckEntryEquals(const DebugSideTable::Entry& a,
const DebugSideTable::Entry& b) {
CHECK_EQ(a.pc_offset(), b.pc_offset());
- CHECK(std::equal(a.values().begin(), a.values().end(), b.values().begin(),
- b.values().end(), &CheckValueEquals));
+ CHECK_EQ(a.stack_height(), b.stack_height());
+ CHECK_EQ(a.changed_values(), b.changed_values());
return true;
}
- static bool CheckValueEquals(const DebugSideTable::Entry::Value& a,
- const DebugSideTable::Entry::Value& b) {
- CHECK_EQ(a.type, b.type);
- CHECK_EQ(a.kind, b.kind);
- switch (a.kind) {
- case DebugSideTable::Entry::kConstant:
- CHECK_EQ(a.i32_const, b.i32_const);
- break;
- case DebugSideTable::Entry::kRegister:
- CHECK_EQ(a.reg_code, b.reg_code);
- break;
- case DebugSideTable::Entry::kStack:
- CHECK_EQ(a.stack_offset, b.stack_offset);
- break;
- }
- return true;
- }
-
- OwnedVector<uint8_t> GenerateFunctionBody(
- std::initializer_list<uint8_t> raw_function_bytes) {
- // Build the function bytes by prepending the locals decl and appending an
- // "end" opcode.
- OwnedVector<uint8_t> function_bytes =
- OwnedVector<uint8_t>::New(raw_function_bytes.size() + 2);
- function_bytes[0] = WASM_NO_LOCALS;
- std::copy(raw_function_bytes.begin(), raw_function_bytes.end(),
- &function_bytes[1]);
- function_bytes[raw_function_bytes.size() + 1] = WASM_END;
- return function_bytes;
- }
-
FunctionSig* AddSig(std::initializer_list<ValueType> return_types,
std::initializer_list<ValueType> param_types) {
ValueType* storage =
@@ -147,66 +116,81 @@ class LiftoffCompileEnvironment {
storage + return_types.size());
FunctionSig* sig = zone_.New<FunctionSig>(return_types.size(),
param_types.size(), storage);
- module_builder_.AddSignature(sig);
return sig;
}
TestFunction AddFunction(std::initializer_list<ValueType> return_types,
std::initializer_list<ValueType> param_types,
- std::initializer_list<uint8_t> raw_function_bytes) {
- OwnedVector<uint8_t> function_bytes =
- GenerateFunctionBody(raw_function_bytes);
+ std::initializer_list<uint8_t> function_bytes) {
FunctionSig* sig = AddSig(return_types, param_types);
- int func_index =
- module_builder_.AddFunction(sig, "f", TestingModuleBuilder::kWasm);
- WasmFunction* function = module_builder_.GetFunctionAt(func_index);
- function->code = {module_builder_.AddBytes(function_bytes.as_vector()),
- static_cast<uint32_t>(function_bytes.size())};
- FunctionBody body{function->sig, 0, function_bytes.begin(),
- function_bytes.end()};
- return {std::move(function_bytes), function, body};
+ // Compile the function so we can get the WasmCode* which is later used to
+ // generate the debug side table lazily.
+ auto& func_compiler = wasm_runner_.NewFunction(sig, "f");
+ func_compiler.Build(function_bytes.begin(), function_bytes.end());
+
+ WasmCode* code =
+ wasm_runner_.builder().GetFunctionCode(func_compiler.function_index());
+
+ // Get the wire bytes created by the function compiler (including locals
+ // declaration and the trailing "end" opcode).
+ NativeModule* native_module = code->native_module();
+ auto* function = &native_module->module()->functions[code->index()];
+ Vector<const uint8_t> function_wire_bytes =
+ native_module->wire_bytes().SubVector(function->code.offset(),
+ function->code.end_offset());
+
+ FunctionBody body{sig, 0, function_wire_bytes.begin(),
+ function_wire_bytes.end()};
+ return {code, body};
}
Isolate* isolate_;
HandleScope handle_scope_;
Zone zone_;
- TestingModuleBuilder module_builder_;
+ // wasm_runner_ is used to build actual code objects needed to request lazy
+ // generation of debug side tables.
+ WasmRunnerBase wasm_runner_;
+ WasmCodeRefScope code_ref_scope_;
};
struct DebugSideTableEntry {
- std::vector<DebugSideTable::Entry::Value> values;
+ int stack_height;
+ std::vector<DebugSideTable::Entry::Value> changed_values;
// Construct via vector or implicitly via initializer list.
- explicit DebugSideTableEntry(std::vector<DebugSideTable::Entry::Value> values)
- : values(std::move(values)) {}
+ DebugSideTableEntry(int stack_height,
+ std::vector<DebugSideTable::Entry::Value> changed_values)
+ : stack_height(stack_height), changed_values(std::move(changed_values)) {}
+
DebugSideTableEntry(
- std::initializer_list<DebugSideTable::Entry::Value> values)
- : values(values) {}
+ int stack_height,
+ std::initializer_list<DebugSideTable::Entry::Value> changed_values)
+ : stack_height(stack_height), changed_values(changed_values) {}
bool operator==(const DebugSideTableEntry& other) const {
- if (values.size() != other.values.size()) return false;
- for (size_t i = 0; i < values.size(); ++i) {
- if (values[i].type != other.values[i].type) return false;
- if (values[i].kind != other.values[i].kind) return false;
- // Stack offsets and register codes are platform dependent, so only check
- // constants here.
- if (values[i].kind == DebugSideTable::Entry::kConstant &&
- values[i].i32_const != other.values[i].i32_const) {
- return false;
- }
- }
- return true;
+ return stack_height == other.stack_height &&
+ std::equal(changed_values.begin(), changed_values.end(),
+ other.changed_values.begin(), other.changed_values.end(),
+ CheckValueEquals);
+ }
+
+ // Check for equality, but ignore exact register and stack offset.
+ static bool CheckValueEquals(const DebugSideTable::Entry::Value& a,
+ const DebugSideTable::Entry::Value& b) {
+ return a.index == b.index && a.kind == b.kind && a.kind == b.kind &&
+ (a.storage != DebugSideTable::Entry::kConstant ||
+ a.i32_const == b.i32_const);
}
};
// Debug builds will print the vector of DebugSideTableEntry.
#ifdef DEBUG
std::ostream& operator<<(std::ostream& out, const DebugSideTableEntry& entry) {
- out << "{";
+ out << "stack height " << entry.stack_height << ", changed: {";
const char* comma = "";
- for (auto& v : entry.values) {
- out << comma << v.type.name() << " ";
- switch (v.kind) {
+ for (auto& v : entry.changed_values) {
+ out << comma << v.index << ":" << name(v.kind) << " ";
+ switch (v.storage) {
case DebugSideTable::Entry::kConstant:
out << "const:" << v.i32_const;
break;
@@ -229,23 +213,27 @@ std::ostream& operator<<(std::ostream& out,
#endif // DEBUG
// Named constructors to make the tests more readable.
-DebugSideTable::Entry::Value Constant(ValueType type, int32_t constant) {
+DebugSideTable::Entry::Value Constant(int index, ValueKind kind,
+ int32_t constant) {
DebugSideTable::Entry::Value value;
- value.type = type;
- value.kind = DebugSideTable::Entry::kConstant;
+ value.index = index;
+ value.kind = kind;
+ value.storage = DebugSideTable::Entry::kConstant;
value.i32_const = constant;
return value;
}
-DebugSideTable::Entry::Value Register(ValueType type) {
+DebugSideTable::Entry::Value Register(int index, ValueKind kind) {
DebugSideTable::Entry::Value value;
- value.type = type;
- value.kind = DebugSideTable::Entry::kRegister;
+ value.index = index;
+ value.kind = kind;
+ value.storage = DebugSideTable::Entry::kRegister;
return value;
}
-DebugSideTable::Entry::Value Stack(ValueType type) {
+DebugSideTable::Entry::Value Stack(int index, ValueKind kind) {
DebugSideTable::Entry::Value value;
- value.type = type;
- value.kind = DebugSideTable::Entry::kStack;
+ value.index = index;
+ value.kind = kind;
+ value.storage = DebugSideTable::Entry::kStack;
return value;
}
@@ -253,10 +241,10 @@ void CheckDebugSideTable(std::vector<DebugSideTableEntry> expected_entries,
const wasm::DebugSideTable* debug_side_table) {
std::vector<DebugSideTableEntry> entries;
for (auto& entry : debug_side_table->entries()) {
- auto values = entry.values();
- entries.push_back(
- DebugSideTableEntry{std::vector<DebugSideTable::Entry::Value>{
- values.begin(), values.end()}});
+ entries.emplace_back(
+ entry.stack_height(),
+ std::vector<DebugSideTable::Entry::Value>{
+ entry.changed_values().begin(), entry.changed_values().end()});
}
CHECK_EQ(expected_entries, entries);
}
@@ -308,9 +296,9 @@ TEST(Liftoff_debug_side_table_simple) {
CheckDebugSideTable(
{
// function entry, locals in registers.
- {Register(kWasmI32), Register(kWasmI32)},
- // OOL stack check, locals spilled, stack empty.
- {Stack(kWasmI32), Stack(kWasmI32)},
+ {2, {Register(0, kI32), Register(1, kI32)}},
+ // OOL stack check, locals spilled, stack still empty.
+ {2, {Stack(0, kI32), Stack(1, kI32)}},
},
debug_side_table.get());
}
@@ -324,11 +312,11 @@ TEST(Liftoff_debug_side_table_call) {
CheckDebugSideTable(
{
// function entry, local in register.
- {Register(kWasmI32)},
+ {1, {Register(0, kI32)}},
// call, local spilled, stack empty.
- {Stack(kWasmI32)},
- // OOL stack check, local spilled, stack empty.
- {Stack(kWasmI32)},
+ {1, {Stack(0, kI32)}},
+ // OOL stack check, local spilled as before, stack empty.
+ {1, {}},
},
debug_side_table.get());
}
@@ -344,11 +332,11 @@ TEST(Liftoff_debug_side_table_call_const) {
CheckDebugSideTable(
{
// function entry, local in register.
- {Register(kWasmI32)},
+ {1, {Register(0, kI32)}},
// call, local is kConst.
- {Constant(kWasmI32, kConst)},
+ {1, {Constant(0, kI32, kConst)}},
// OOL stack check, local spilled.
- {Stack(kWasmI32)},
+ {1, {Stack(0, kI32)}},
},
debug_side_table.get());
}
@@ -363,15 +351,15 @@ TEST(Liftoff_debug_side_table_indirect_call) {
CheckDebugSideTable(
{
// function entry, local in register.
- {Register(kWasmI32)},
+ {1, {Register(0, kI32)}},
// indirect call, local spilled, stack empty.
- {Stack(kWasmI32)},
- // OOL stack check, local spilled, stack empty.
- {Stack(kWasmI32)},
- // OOL trap (invalid index), local spilled, stack has {kConst}.
- {Stack(kWasmI32), Constant(kWasmI32, kConst)},
- // OOL trap (sig mismatch), local spilled, stack has {kConst}.
- {Stack(kWasmI32), Constant(kWasmI32, kConst)},
+ {1, {Stack(0, kI32)}},
+ // OOL stack check, local still spilled.
+ {1, {}},
+ // OOL trap (invalid index), local still spilled, stack has {kConst}.
+ {2, {Constant(1, kI32, kConst)}},
+ // OOL trap (sig mismatch), stack unmodified.
+ {2, {}},
},
debug_side_table.get());
}
@@ -385,11 +373,11 @@ TEST(Liftoff_debug_side_table_loop) {
CheckDebugSideTable(
{
// function entry, local in register.
- {Register(kWasmI32)},
+ {1, {Register(0, kI32)}},
// OOL stack check, local spilled, stack empty.
- {Stack(kWasmI32)},
- // OOL loop stack check, local spilled, stack has {kConst}.
- {Stack(kWasmI32), Constant(kWasmI32, kConst)},
+ {1, {Stack(0, kI32)}},
+ // OOL loop stack check, local still spilled, stack has {kConst}.
+ {2, {Constant(1, kI32, kConst)}},
},
debug_side_table.get());
}
@@ -402,13 +390,13 @@ TEST(Liftoff_debug_side_table_trap) {
CheckDebugSideTable(
{
// function entry, locals in registers.
- {Register(kWasmI32), Register(kWasmI32)},
+ {2, {Register(0, kI32), Register(1, kI32)}},
// OOL stack check, local spilled, stack empty.
- {Stack(kWasmI32), Stack(kWasmI32)},
- // OOL trap (div by zero), locals spilled, stack empty.
- {Stack(kWasmI32), Stack(kWasmI32)},
- // OOL trap (result unrepresentable), locals spilled, stack empty.
- {Stack(kWasmI32), Stack(kWasmI32)},
+ {2, {Stack(0, kI32), Stack(1, kI32)}},
+ // OOL trap (div by zero), stack as before.
+ {2, {}},
+ // OOL trap (unrepresentable), stack as before.
+ {2, {}},
},
debug_side_table.get());
}
@@ -426,12 +414,11 @@ TEST(Liftoff_breakpoint_simple) {
CheckDebugSideTable(
{
// First break point, locals in registers.
- {Register(kWasmI32), Register(kWasmI32)},
- // Second break point, locals and two stack values in registers.
- {Register(kWasmI32), Register(kWasmI32), Register(kWasmI32),
- Register(kWasmI32)},
+ {2, {Register(0, kI32), Register(1, kI32)}},
+ // Second break point, locals unchanged, two register stack values.
+ {4, {Register(2, kI32), Register(3, kI32)}},
// OOL stack check, locals spilled, stack empty.
- {Stack(kWasmI32), Stack(kWasmI32)},
+ {2, {Stack(0, kI32), Stack(1, kI32)}},
},
debug_side_table.get());
}
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc b/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc
index 9b391dd0d0..b00f0714c2 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc
@@ -46,7 +46,6 @@ void CheckMemoryEqualsFollowedByZeroes(TestingModuleBuilder* builder,
} // namespace
WASM_EXEC_TEST(MemoryInit) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
r.builder().AddMemory(kWasmPageSize);
const byte data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
@@ -83,7 +82,6 @@ WASM_EXEC_TEST(MemoryInit) {
}
WASM_EXEC_TEST(MemoryInitOutOfBoundsData) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
r.builder().AddMemory(kWasmPageSize);
const byte data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
@@ -105,7 +103,6 @@ WASM_EXEC_TEST(MemoryInitOutOfBoundsData) {
}
WASM_EXEC_TEST(MemoryInitOutOfBounds) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
r.builder().AddMemory(kWasmPageSize);
const byte data[kWasmPageSize] = {};
@@ -137,7 +134,6 @@ WASM_EXEC_TEST(MemoryInitOutOfBounds) {
}
WASM_EXEC_TEST(MemoryCopy) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
byte* mem = r.builder().AddMemory(kWasmPageSize);
BUILD(
@@ -166,7 +162,6 @@ WASM_EXEC_TEST(MemoryCopy) {
}
WASM_EXEC_TEST(MemoryCopyOverlapping) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
byte* mem = r.builder().AddMemory(kWasmPageSize);
BUILD(
@@ -189,7 +184,6 @@ WASM_EXEC_TEST(MemoryCopyOverlapping) {
}
WASM_EXEC_TEST(MemoryCopyOutOfBoundsData) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
byte* mem = r.builder().AddMemory(kWasmPageSize);
BUILD(
@@ -218,7 +212,6 @@ WASM_EXEC_TEST(MemoryCopyOutOfBoundsData) {
}
WASM_EXEC_TEST(MemoryCopyOutOfBounds) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
r.builder().AddMemory(kWasmPageSize);
BUILD(
@@ -248,7 +241,6 @@ WASM_EXEC_TEST(MemoryCopyOutOfBounds) {
}
WASM_EXEC_TEST(MemoryFill) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
r.builder().AddMemory(kWasmPageSize);
BUILD(
@@ -272,7 +264,6 @@ WASM_EXEC_TEST(MemoryFill) {
}
WASM_EXEC_TEST(MemoryFillValueWrapsToByte) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
r.builder().AddMemory(kWasmPageSize);
BUILD(
@@ -286,7 +277,6 @@ WASM_EXEC_TEST(MemoryFillValueWrapsToByte) {
}
WASM_EXEC_TEST(MemoryFillOutOfBoundsData) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
r.builder().AddMemory(kWasmPageSize);
BUILD(
@@ -299,7 +289,6 @@ WASM_EXEC_TEST(MemoryFillOutOfBoundsData) {
}
WASM_EXEC_TEST(MemoryFillOutOfBounds) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
r.builder().AddMemory(kWasmPageSize);
BUILD(
@@ -322,7 +311,6 @@ WASM_EXEC_TEST(MemoryFillOutOfBounds) {
}
WASM_EXEC_TEST(DataDropTwice) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t> r(execution_tier);
r.builder().AddMemory(kWasmPageSize);
const byte data[] = {0};
@@ -334,7 +322,6 @@ WASM_EXEC_TEST(DataDropTwice) {
}
WASM_EXEC_TEST(DataDropThenMemoryInit) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t> r(execution_tier);
r.builder().AddMemory(kWasmPageSize);
const byte data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
@@ -348,7 +335,6 @@ WASM_EXEC_TEST(DataDropThenMemoryInit) {
void TestTableCopyInbounds(TestExecutionTier execution_tier, int table_dst,
int table_src) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
const uint32_t kTableSize = 5;
// Add 10 function tables, even though we only test one table.
@@ -411,7 +397,6 @@ void CheckTableCall(Isolate* isolate, Handle<WasmTableObject> table,
} // namespace
void TestTableInitElems(TestExecutionTier execution_tier, int table_index) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
Isolate* isolate = CcTest::InitIsolateOnce();
HandleScope scope(isolate);
TestSignatures sigs;
@@ -489,7 +474,6 @@ WASM_COMPILED_EXEC_TEST(TableInitElems9) {
}
void TestTableInitOob(TestExecutionTier execution_tier, int table_index) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
Isolate* isolate = CcTest::InitIsolateOnce();
HandleScope scope(isolate);
TestSignatures sigs;
@@ -569,7 +553,6 @@ WASM_COMPILED_EXEC_TEST(TableInitOob9) {
void TestTableCopyElems(TestExecutionTier execution_tier, int table_dst,
int table_src) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
Isolate* isolate = CcTest::InitIsolateOnce();
HandleScope scope(isolate);
TestSignatures sigs;
@@ -651,7 +634,6 @@ WASM_COMPILED_EXEC_TEST(TableCopyElemsFrom6To6) {
void TestTableCopyCalls(TestExecutionTier execution_tier, int table_dst,
int table_src) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
Isolate* isolate = CcTest::InitIsolateOnce();
HandleScope scope(isolate);
TestSignatures sigs;
@@ -726,7 +708,6 @@ WASM_COMPILED_EXEC_TEST(TableCopyCallsTo6From6) {
void TestTableCopyOobWrites(TestExecutionTier execution_tier, int table_dst,
int table_src) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
Isolate* isolate = CcTest::InitIsolateOnce();
HandleScope scope(isolate);
TestSignatures sigs;
@@ -802,7 +783,6 @@ WASM_COMPILED_EXEC_TEST(TableCopyOobWritesFrom6To6) {
void TestTableCopyOob1(TestExecutionTier execution_tier, int table_dst,
int table_src) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_tier);
const uint32_t kTableSize = 5;
@@ -860,7 +840,6 @@ WASM_COMPILED_EXEC_TEST(TableCopyOob1From6To6) {
}
WASM_COMPILED_EXEC_TEST(ElemDropTwice) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t> r(execution_tier);
r.builder().AddIndirectFunctionTable(nullptr, 1);
r.builder().AddPassiveElementSegment({});
@@ -871,7 +850,6 @@ WASM_COMPILED_EXEC_TEST(ElemDropTwice) {
}
WASM_COMPILED_EXEC_TEST(ElemDropThenTableInit) {
- EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t> r(execution_tier);
r.builder().AddIndirectFunctionTable(nullptr, 1);
r.builder().AddPassiveElementSegment({});
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-exceptions.cc b/deps/v8/test/cctest/wasm/test-run-wasm-exceptions.cc
index 83b446cc49..e55547911b 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-exceptions.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-exceptions.cc
@@ -12,7 +12,7 @@ namespace internal {
namespace wasm {
namespace test_run_wasm_exceptions {
-WASM_COMPILED_EXEC_TEST(TryCatchThrow) {
+WASM_EXEC_TEST(TryCatchThrow) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
WasmRunner<uint32_t, uint32_t> r(execution_tier);
@@ -27,12 +27,265 @@ WASM_COMPILED_EXEC_TEST(TryCatchThrow) {
WASM_THROW(except))),
WASM_STMTS(WASM_I32V(kResult0)), except));
- // Need to call through JS to allow for creation of stack traces.
- r.CheckCallViaJS(kResult0, 0);
- r.CheckCallViaJS(kResult1, 1);
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ r.CheckCallViaJS(kResult0, 0);
+ r.CheckCallViaJS(kResult1, 1);
+ } else {
+ CHECK_EQ(kResult0, r.CallInterpreter(0));
+ CHECK_EQ(kResult1, r.CallInterpreter(1));
+ }
+}
+
+WASM_EXEC_TEST(TryCatchThrowWithValue) {
+ TestSignatures sigs;
+ EXPERIMENTAL_FLAG_SCOPE(eh);
+ WasmRunner<uint32_t, uint32_t> r(execution_tier);
+ uint32_t except = r.builder().AddException(sigs.v_i());
+ constexpr uint32_t kResult0 = 23;
+ constexpr uint32_t kResult1 = 42;
+
+ // Build the main test function.
+ BUILD(r, WASM_TRY_CATCH_T(
+ kWasmI32,
+ WASM_STMTS(WASM_I32V(kResult1),
+ WASM_IF(WASM_I32_EQZ(WASM_LOCAL_GET(0)),
+ WASM_I32V(kResult0), WASM_THROW(except))),
+ WASM_STMTS(kExprNop), except));
+
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ r.CheckCallViaJS(kResult0, 0);
+ r.CheckCallViaJS(kResult1, 1);
+ } else {
+ CHECK_EQ(kResult0, r.CallInterpreter(0));
+ CHECK_EQ(kResult1, r.CallInterpreter(1));
+ }
+}
+
+WASM_EXEC_TEST(TryMultiCatchThrow) {
+ TestSignatures sigs;
+ EXPERIMENTAL_FLAG_SCOPE(eh);
+ WasmRunner<uint32_t, uint32_t> r(execution_tier);
+ uint32_t except1 = r.builder().AddException(sigs.v_v());
+ uint32_t except2 = r.builder().AddException(sigs.v_v());
+ constexpr uint32_t kResult0 = 23;
+ constexpr uint32_t kResult1 = 42;
+ constexpr uint32_t kResult2 = 51;
+
+ // Build the main test function.
+ BUILD(
+ r, kExprTry, static_cast<byte>((kWasmI32).value_type_code()),
+ WASM_STMTS(WASM_I32V(kResult2),
+ WASM_IF(WASM_I32_EQZ(WASM_LOCAL_GET(0)), WASM_THROW(except1)),
+ WASM_IF(WASM_I32_EQ(WASM_LOCAL_GET(0), WASM_I32V(1)),
+ WASM_THROW(except2))),
+ kExprCatch, except1, WASM_STMTS(WASM_I32V(kResult0)), kExprCatch, except2,
+ WASM_STMTS(WASM_I32V(kResult1)), kExprEnd);
+
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ r.CheckCallViaJS(kResult0, 0);
+ r.CheckCallViaJS(kResult1, 1);
+ r.CheckCallViaJS(kResult2, 2);
+ } else {
+ CHECK_EQ(kResult0, r.CallInterpreter(0));
+ CHECK_EQ(kResult1, r.CallInterpreter(1));
+ CHECK_EQ(kResult2, r.CallInterpreter(2));
+ }
+}
+
+WASM_EXEC_TEST(TryCatchAllThrow) {
+ TestSignatures sigs;
+ EXPERIMENTAL_FLAG_SCOPE(eh);
+ WasmRunner<uint32_t, uint32_t> r(execution_tier);
+ uint32_t except1 = r.builder().AddException(sigs.v_v());
+ uint32_t except2 = r.builder().AddException(sigs.v_v());
+ constexpr uint32_t kResult0 = 23;
+ constexpr uint32_t kResult1 = 42;
+ constexpr uint32_t kResult2 = 51;
+
+ // Build the main test function.
+ BUILD(
+ r, kExprTry, static_cast<byte>((kWasmI32).value_type_code()),
+ WASM_STMTS(WASM_I32V(kResult2),
+ WASM_IF(WASM_I32_EQZ(WASM_LOCAL_GET(0)), WASM_THROW(except1)),
+ WASM_IF(WASM_I32_EQ(WASM_LOCAL_GET(0), WASM_I32V(1)),
+ WASM_THROW(except2))),
+ kExprCatch, except1, WASM_STMTS(WASM_I32V(kResult0)), kExprCatchAll,
+ WASM_STMTS(WASM_I32V(kResult1)), kExprEnd);
+
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ r.CheckCallViaJS(kResult0, 0);
+ r.CheckCallViaJS(kResult1, 1);
+ r.CheckCallViaJS(kResult2, 2);
+ } else {
+ CHECK_EQ(kResult0, r.CallInterpreter(0));
+ CHECK_EQ(kResult1, r.CallInterpreter(1));
+ CHECK_EQ(kResult2, r.CallInterpreter(2));
+ }
+}
+
+WASM_EXEC_TEST(TryImplicitRethrow) {
+ TestSignatures sigs;
+ EXPERIMENTAL_FLAG_SCOPE(eh);
+ WasmRunner<uint32_t, uint32_t> r(execution_tier);
+ uint32_t except1 = r.builder().AddException(sigs.v_v());
+ uint32_t except2 = r.builder().AddException(sigs.v_v());
+ constexpr uint32_t kResult0 = 23;
+ constexpr uint32_t kResult1 = 42;
+ constexpr uint32_t kResult2 = 51;
+
+ // Build the main test function.
+ BUILD(r,
+ WASM_TRY_CATCH_T(
+ kWasmI32,
+ WASM_TRY_CATCH_T(kWasmI32,
+ WASM_STMTS(WASM_I32V(kResult1),
+ WASM_IF(WASM_I32_EQZ(WASM_LOCAL_GET(0)),
+ WASM_THROW(except2))),
+ WASM_STMTS(WASM_I32V(kResult2)), except1),
+ WASM_I32V(kResult0), except2));
+
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ r.CheckCallViaJS(kResult0, 0);
+ r.CheckCallViaJS(kResult1, 1);
+ } else {
+ CHECK_EQ(kResult0, r.CallInterpreter(0));
+ CHECK_EQ(kResult1, r.CallInterpreter(1));
+ }
+}
+
+WASM_EXEC_TEST(TryDelegate) {
+ TestSignatures sigs;
+ EXPERIMENTAL_FLAG_SCOPE(eh);
+ WasmRunner<uint32_t, uint32_t> r(execution_tier);
+ uint32_t except = r.builder().AddException(sigs.v_v());
+ constexpr uint32_t kResult0 = 23;
+ constexpr uint32_t kResult1 = 42;
+
+ // Build the main test function.
+ BUILD(r,
+ WASM_TRY_CATCH_T(kWasmI32,
+ WASM_TRY_DELEGATE_T(
+ kWasmI32,
+ WASM_STMTS(WASM_I32V(kResult1),
+ WASM_IF(WASM_I32_EQZ(WASM_LOCAL_GET(0)),
+ WASM_THROW(except))),
+ 0),
+ WASM_I32V(kResult0), except));
+
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ r.CheckCallViaJS(kResult0, 0);
+ r.CheckCallViaJS(kResult1, 1);
+ } else {
+ CHECK_EQ(kResult0, r.CallInterpreter(0));
+ CHECK_EQ(kResult1, r.CallInterpreter(1));
+ }
}
-WASM_COMPILED_EXEC_TEST(TryCatchCallDirect) {
+WASM_EXEC_TEST(TryUnwind) {
+ TestSignatures sigs;
+ EXPERIMENTAL_FLAG_SCOPE(eh);
+ WasmRunner<uint32_t, uint32_t> r(execution_tier);
+ uint32_t except = r.builder().AddException(sigs.v_v());
+ constexpr uint32_t kResult0 = 23;
+ constexpr uint32_t kResult1 = 42;
+
+ // Build the main test function.
+ BUILD(r, WASM_TRY_CATCH_T(
+ kWasmI32,
+ WASM_TRY_UNWIND_T(
+ kWasmI32,
+ WASM_TRY_DELEGATE_T(
+ kWasmI32,
+ WASM_STMTS(WASM_I32V(kResult1),
+ WASM_IF(WASM_I32_EQZ(WASM_LOCAL_GET(0)),
+ WASM_THROW(except))),
+ 0),
+ kExprNop),
+ WASM_I32V(kResult0), except));
+
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ r.CheckCallViaJS(kResult0, 0);
+ r.CheckCallViaJS(kResult1, 1);
+ } else {
+ CHECK_EQ(kResult0, r.CallInterpreter(0));
+ CHECK_EQ(kResult1, r.CallInterpreter(1));
+ }
+}
+
+WASM_EXEC_TEST(TryCatchRethrow) {
+ TestSignatures sigs;
+ EXPERIMENTAL_FLAG_SCOPE(eh);
+ WasmRunner<uint32_t, uint32_t> r(execution_tier);
+ uint32_t except1 = r.builder().AddException(sigs.v_v());
+ uint32_t except2 = r.builder().AddException(sigs.v_v());
+ constexpr uint32_t kResult0 = 23;
+ constexpr uint32_t kResult1 = 42;
+ constexpr uint32_t kUnreachable = 51;
+
+ // Build the main test function.
+ BUILD(r,
+ WASM_TRY_CATCH_CATCH_T(
+ kWasmI32,
+ WASM_TRY_CATCH_T(
+ kWasmI32, WASM_THROW(except2),
+ WASM_TRY_CATCH_T(
+ kWasmI32, WASM_THROW(except1),
+ WASM_STMTS(WASM_I32V(kUnreachable),
+ WASM_IF_ELSE(WASM_I32_EQZ(WASM_LOCAL_GET(0)),
+ WASM_RETHROW(1), WASM_RETHROW(2))),
+ except1),
+ except2),
+ except1, WASM_I32V(kResult0), except2, WASM_I32V(kResult1)));
+
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ r.CheckCallViaJS(kResult0, 0);
+ r.CheckCallViaJS(kResult1, 1);
+ } else {
+ CHECK_EQ(kResult0, r.CallInterpreter(0));
+ CHECK_EQ(kResult1, r.CallInterpreter(1));
+ }
+}
+
+WASM_EXEC_TEST(TryDelegateToCaller) {
+ TestSignatures sigs;
+ EXPERIMENTAL_FLAG_SCOPE(eh);
+ WasmRunner<uint32_t, uint32_t> r(execution_tier);
+ uint32_t except = r.builder().AddException(sigs.v_v());
+ constexpr uint32_t kResult0 = 23;
+ constexpr uint32_t kResult1 = 42;
+
+ // Build the main test function.
+ BUILD(r,
+ WASM_TRY_CATCH_T(kWasmI32,
+ WASM_TRY_DELEGATE_T(
+ kWasmI32,
+ WASM_STMTS(WASM_I32V(kResult1),
+ WASM_IF(WASM_I32_EQZ(WASM_LOCAL_GET(0)),
+ WASM_THROW(except))),
+ 1),
+ WASM_I32V(kResult0), except));
+
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ constexpr int64_t trap = 0xDEADBEEF;
+ r.CheckCallViaJS(trap, 0);
+ r.CheckCallViaJS(kResult1, 1);
+ } else {
+ constexpr int stopped = 0;
+ CHECK_EQ(stopped, r.CallInterpreter(0));
+ CHECK_EQ(kResult1, r.CallInterpreter(1));
+ }
+}
+
+WASM_EXEC_TEST(TryCatchCallDirect) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
WasmRunner<uint32_t, uint32_t> r(execution_tier);
@@ -55,12 +308,17 @@ WASM_COMPILED_EXEC_TEST(TryCatchCallDirect) {
WASM_DROP))),
WASM_STMTS(WASM_I32V(kResult0)), except));
- // Need to call through JS to allow for creation of stack traces.
- r.CheckCallViaJS(kResult0, 0);
- r.CheckCallViaJS(kResult1, 1);
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ r.CheckCallViaJS(kResult0, 0);
+ r.CheckCallViaJS(kResult1, 1);
+ } else {
+ CHECK_EQ(kResult0, r.CallInterpreter(0));
+ CHECK_EQ(kResult1, r.CallInterpreter(1));
+ }
}
-WASM_COMPILED_EXEC_TEST(TryCatchCallIndirect) {
+WASM_EXEC_TEST(TryCatchCallIndirect) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
WasmRunner<uint32_t, uint32_t> r(execution_tier);
@@ -92,9 +350,14 @@ WASM_COMPILED_EXEC_TEST(TryCatchCallIndirect) {
WASM_DROP))),
WASM_STMTS(WASM_I32V(kResult0)), except));
- // Need to call through JS to allow for creation of stack traces.
- r.CheckCallViaJS(kResult0, 0);
- r.CheckCallViaJS(kResult1, 1);
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ r.CheckCallViaJS(kResult0, 0);
+ r.CheckCallViaJS(kResult1, 1);
+ } else {
+ CHECK_EQ(kResult0, r.CallInterpreter(0));
+ CHECK_EQ(kResult1, r.CallInterpreter(1));
+ }
}
WASM_COMPILED_EXEC_TEST(TryCatchCallExternal) {
@@ -152,32 +415,51 @@ void TestTrapNotCaught(byte* code, size_t code_size,
WASM_DROP),
WASM_STMTS(WASM_I32V(kResultCaught))));
- // Need to call through JS to allow for creation of stack traces.
- r.CheckCallViaJSTraps();
+ if (execution_tier != TestExecutionTier::kInterpreter) {
+ // Need to call through JS to allow for creation of stack traces.
+ r.CheckCallViaJSTraps();
+ } else {
+ r.CallInterpreter();
+ }
}
} // namespace
-WASM_COMPILED_EXEC_TEST(TryCatchTrapUnreachable) {
+WASM_EXEC_TEST(TryCatchTrapUnreachable) {
byte code[] = {WASM_UNREACHABLE};
TestTrapNotCaught(code, arraysize(code), execution_tier);
}
-WASM_COMPILED_EXEC_TEST(TryCatchTrapMemOutOfBounds) {
+WASM_EXEC_TEST(TryCatchTrapMemOutOfBounds) {
byte code[] = {WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V_1(-1))};
TestTrapNotCaught(code, arraysize(code), execution_tier);
}
-WASM_COMPILED_EXEC_TEST(TryCatchTrapDivByZero) {
+WASM_EXEC_TEST(TryCatchTrapDivByZero) {
byte code[] = {WASM_I32_DIVS(WASM_LOCAL_GET(0), WASM_I32V_1(0))};
TestTrapNotCaught(code, arraysize(code), execution_tier);
}
-WASM_COMPILED_EXEC_TEST(TryCatchTrapRemByZero) {
+WASM_EXEC_TEST(TryCatchTrapRemByZero) {
byte code[] = {WASM_I32_REMS(WASM_LOCAL_GET(0), WASM_I32V_1(0))};
TestTrapNotCaught(code, arraysize(code), execution_tier);
}
+TEST(Regress1180457) {
+ TestSignatures sigs;
+ EXPERIMENTAL_FLAG_SCOPE(eh);
+ WasmRunner<uint32_t> r(TestExecutionTier::kInterpreter);
+ constexpr uint32_t kResult0 = 23;
+ constexpr uint32_t kUnreachable = 42;
+ BUILD(r, WASM_TRY_CATCH_ALL_T(
+ kWasmI32,
+ WASM_TRY_DELEGATE_T(
+ kWasmI32, WASM_STMTS(WASM_I32V(kResult0), WASM_BR(0)), 0),
+ WASM_I32V(kUnreachable)));
+
+ CHECK_EQ(kResult0, r.CallInterpreter());
+}
+
} // namespace test_run_wasm_exceptions
} // namespace wasm
} // namespace internal
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-memory64.cc b/deps/v8/test/cctest/wasm/test-run-wasm-memory64.cc
index 1dcccca67f..71bb77f6ad 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-memory64.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-memory64.cc
@@ -7,6 +7,7 @@
#include "test/cctest/wasm/wasm-run-utils.h"
#include "test/common/wasm/test-signatures.h"
#include "test/common/wasm/wasm-macro-gen.h"
+#include "test/common/wasm/wasm-module-runner.h"
namespace v8 {
namespace internal {
@@ -54,6 +55,49 @@ WASM_EXEC_TEST(Load) {
// TODO(clemensb): Test atomic instructions.
+WASM_EXEC_TEST(InitExpression) {
+ EXPERIMENTAL_FLAG_SCOPE(memory64);
+ Isolate* isolate = CcTest::InitIsolateOnce();
+ HandleScope scope(isolate);
+
+ ErrorThrower thrower(isolate, "TestMemory64InitExpression");
+
+ const byte data[] = {
+ WASM_MODULE_HEADER, //
+ SECTION(Memory, //
+ ENTRY_COUNT(1), //
+ kMemory64WithMaximum, // type
+ 1, // initial size
+ 2), // maximum size
+ SECTION(Data, //
+ ENTRY_COUNT(1), //
+ 0, // linear memory index
+ WASM_I64V_3(0xFFFF), kExprEnd, // destination offset
+ U32V_1(1), // source size
+ 'c') // data bytes
+ };
+
+ testing::CompileAndInstantiateForTesting(
+ isolate, &thrower, ModuleWireBytes(data, data + arraysize(data)));
+ if (thrower.error()) {
+ thrower.Reify()->Print();
+ FATAL("compile or instantiate error");
+ }
+}
+
+WASM_EXEC_TEST(MemorySize) {
+ // TODO(clemensb): Implement memory64 in the interpreter.
+ if (execution_tier == TestExecutionTier::kInterpreter) return;
+
+ Memory64Runner<uint64_t> r(execution_tier);
+ constexpr int kNumPages = 13;
+ r.builder().AddMemoryElems<uint8_t>(kNumPages * kWasmPageSize);
+
+ BUILD(r, WASM_MEMORY_SIZE);
+
+ CHECK_EQ(kNumPages, r.Call());
+}
+
} // namespace wasm
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
index 9a6e85f431..a9f5dd6b26 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
@@ -904,41 +904,6 @@ TEST(EmptyMemoryEmptyDataSegment) {
Cleanup();
}
-TEST(MemoryWithOOBEmptyDataSegment) {
- {
- FlagScope<bool> no_bulk_memory(
- &v8::internal::FLAG_experimental_wasm_bulk_memory, false);
- Isolate* isolate = CcTest::InitIsolateOnce();
- HandleScope scope(isolate);
- testing::SetupIsolateForWasmModule(isolate);
-
- ErrorThrower thrower(isolate, "Run_WasmModule_InitDataAtTheUpperLimit");
-
- const byte data[] = {
- WASM_MODULE_HEADER, // --
- kMemorySectionCode, // --
- U32V_1(4), // section size
- ENTRY_COUNT(1), // --
- kWithMaximum, // --
- 1, // initial size
- 1, // maximum size
- kDataSectionCode, // --
- U32V_1(9), // section size
- ENTRY_COUNT(1), // --
- 0, // linear memory index
- WASM_I32V_4(0x2468ACE), // destination offset
- kExprEnd,
- U32V_1(0), // source size
- };
-
- CompileAndInstantiateForTesting(
- isolate, &thrower, ModuleWireBytes(data, data + arraysize(data)));
- // It should not be possible to instantiate this module.
- CHECK(thrower.error());
- }
- Cleanup();
-}
-
#undef EMIT_CODE_WITH_END
} // namespace test_run_wasm_module
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-simd-scalar-lowering.cc b/deps/v8/test/cctest/wasm/test-run-wasm-simd-scalar-lowering.cc
index 11db27f72c..4c5309aae5 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-simd-scalar-lowering.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-simd-scalar-lowering.cc
@@ -224,7 +224,7 @@ WASM_SIMD_TEST(AnyTrue_DifferentShapes) {
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
BUILD(r, WASM_SIMD_I32x4_SPLAT(WASM_LOCAL_GET(0)),
- WASM_SIMD_OP(kExprV8x16AnyTrue));
+ WASM_SIMD_OP(kExprV128AnyTrue));
CHECK_EQ(0, r.Call(0x00000000));
}
@@ -233,7 +233,7 @@ WASM_SIMD_TEST(AnyTrue_DifferentShapes) {
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
BUILD(r, WASM_SIMD_I32x4_SPLAT(WASM_LOCAL_GET(0)),
- WASM_SIMD_OP(kExprV16x8AnyTrue));
+ WASM_SIMD_OP(kExprV128AnyTrue));
CHECK_EQ(1, r.Call(0x000000FF));
}
@@ -243,7 +243,7 @@ WASM_SIMD_TEST(AnyTrue_DifferentShapes) {
WasmRunner<int32_t, float> r(execution_tier, lower_simd);
BUILD(r, WASM_SIMD_F32x4_SPLAT(WASM_LOCAL_GET(0)),
- WASM_SIMD_OP(kExprV8x16AnyTrue));
+ WASM_SIMD_OP(kExprV128AnyTrue));
CHECK_EQ(0, r.Call(0x00000000));
}
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
index c6be948954..fa9299f27b 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
@@ -17,6 +17,7 @@
#include "src/base/macros.h"
#include "src/base/memory.h"
#include "src/base/overflowing-math.h"
+#include "src/base/safe_conversions.h"
#include "src/base/utils/random-number-generator.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/cpu-features.h"
@@ -800,26 +801,22 @@ WASM_SIMD_TEST_NO_LOWERING(I8x16SignSelect) {
}
WASM_SIMD_TEST_NO_LOWERING(I16x8SignSelect) {
- std::array<int16_t, kSimd128Size / 2> selection = {0x8000, 0, -1, 0,
- 0x8000, 0, -1, 0};
- std::array<int8_t, kSimd128Size> mask;
- memcpy(mask.data(), selection.data(), kSimd128Size);
+ std::array<int8_t, kSimd128Size> mask = {0, 0x80, 0, 0, -1, -1, 0, 0,
+ 0, 0x80, 0, 0, -1, -1, 0, 0};
RunSignSelect<int16_t>(execution_tier, lower_simd, kExprI16x8SignSelect,
kExprI16x8Splat, mask);
}
WASM_SIMD_TEST_NO_LOWERING(I32x4SignSelect) {
- std::array<int32_t, kSimd128Size / 4> selection = {0x80000000, 0, -1, 0};
- std::array<int8_t, kSimd128Size> mask;
- memcpy(mask.data(), selection.data(), kSimd128Size);
+ std::array<int8_t, kSimd128Size> mask = {0, 0, 0, 0x80, 0, 0, 0, 0,
+ -1, -1, -1, -1, 0, 0, 0, 0};
RunSignSelect<int32_t>(execution_tier, lower_simd, kExprI32x4SignSelect,
kExprI32x4Splat, mask);
}
WASM_SIMD_TEST_NO_LOWERING(I64x2SignSelect) {
- std::array<int64_t, kSimd128Size / 8> selection = {0x8000000000000000, 0};
- std::array<int8_t, kSimd128Size> mask;
- memcpy(mask.data(), selection.data(), kSimd128Size);
+ std::array<int8_t, kSimd128Size> mask = {0, 0, 0, 0, 0, 0, 0, 0x80,
+ 0, 0, 0, 0, 0, 0, 0, 0};
RunSignSelect<int64_t>(execution_tier, lower_simd, kExprI64x2SignSelect,
kExprI64x2Splat, mask);
}
@@ -954,6 +951,10 @@ WASM_SIMD_TEST(I64x2Neg) {
base::NegateWithWraparound);
}
+WASM_SIMD_TEST_NO_LOWERING(I64x2Abs) {
+ RunI64x2UnOpTest(execution_tier, lower_simd, kExprI64x2Abs, std::abs);
+}
+
void RunI64x2ShiftOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, Int64ShiftOp expected_op) {
// Intentionally shift by 64, should be no-op.
@@ -1003,7 +1004,6 @@ WASM_SIMD_TEST(I64x2ShrU) {
void RunI64x2BinOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, Int64BinOp expected_op) {
- FLAG_SCOPE(wasm_simd_post_mvp);
WasmRunner<int32_t, int64_t, int64_t> r(execution_tier, lower_simd);
// Global to hold output.
int64_t* g = r.builder().AddGlobal<int64_t>(kWasmS128);
@@ -1038,15 +1038,29 @@ WASM_SIMD_TEST(I64x2Sub) {
base::SubWithWraparound);
}
-#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_S390X || \
- V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS64 || \
- V8_TARGET_ARCH_MIPS
WASM_SIMD_TEST_NO_LOWERING(I64x2Eq) {
RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2Eq, Equal);
}
-#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_S390X ||
- // V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS64 ||
- // V8_TARGET_ARCH_MIPS
+
+WASM_SIMD_TEST_NO_LOWERING(I64x2Ne) {
+ RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2Ne, NotEqual);
+}
+
+WASM_SIMD_TEST_NO_LOWERING(I64x2LtS) {
+ RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2LtS, Less);
+}
+
+WASM_SIMD_TEST_NO_LOWERING(I64x2LeS) {
+ RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2LeS, LessEqual);
+}
+
+WASM_SIMD_TEST_NO_LOWERING(I64x2GtS) {
+ RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2GtS, Greater);
+}
+
+WASM_SIMD_TEST_NO_LOWERING(I64x2GeS) {
+ RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2GeS, GreaterEqual);
+}
WASM_SIMD_TEST(F64x2Splat) {
WasmRunner<int32_t, double> r(execution_tier, lower_simd);
@@ -1282,6 +1296,115 @@ WASM_SIMD_TEST(F64x2NearestInt) {
true);
}
+template <typename SrcType>
+void RunF64x2ConvertLowI32x4Test(TestExecutionTier execution_tier,
+ LowerSimd lower_simd, WasmOpcode opcode) {
+ WasmRunner<int32_t, SrcType> r(execution_tier, lower_simd);
+ double* g = r.builder().template AddGlobal<double>(kWasmS128);
+ // TODO(zhin): set top lanes to 0 to assert conversion happens on low lanes.
+ BUILD(
+ r,
+ WASM_GLOBAL_SET(
+ 0, WASM_SIMD_UNOP(opcode, WASM_SIMD_I32x4_SPLAT(WASM_LOCAL_GET(0)))),
+ WASM_ONE);
+
+ for (SrcType x : compiler::ValueHelper::GetVector<SrcType>()) {
+ r.Call(x);
+ double expected = static_cast<double>(x);
+ for (int i = 0; i < 2; i++) {
+ double actual = ReadLittleEndianValue<double>(&g[i]);
+ CheckDoubleResult(x, x, expected, actual, true);
+ }
+ }
+}
+
+WASM_SIMD_TEST_NO_LOWERING(F64x2ConvertLowI32x4S) {
+ RunF64x2ConvertLowI32x4Test<int32_t>(execution_tier, lower_simd,
+ kExprF64x2ConvertLowI32x4S);
+}
+
+WASM_SIMD_TEST_NO_LOWERING(F64x2ConvertLowI32x4U) {
+ RunF64x2ConvertLowI32x4Test<uint32_t>(execution_tier, lower_simd,
+ kExprF64x2ConvertLowI32x4U);
+}
+
+template <typename SrcType>
+void RunI32x4TruncSatF64x2Test(TestExecutionTier execution_tier,
+ LowerSimd lower_simd, WasmOpcode opcode) {
+ WasmRunner<int32_t, double> r(execution_tier, lower_simd);
+ SrcType* g = r.builder().AddGlobal<SrcType>(kWasmS128);
+ BUILD(
+ r,
+ WASM_GLOBAL_SET(
+ 0, WASM_SIMD_UNOP(opcode, WASM_SIMD_F64x2_SPLAT(WASM_LOCAL_GET(0)))),
+ WASM_ONE);
+
+ FOR_FLOAT64_INPUTS(x) {
+ r.Call(x);
+ SrcType expected = base::saturated_cast<SrcType>(x);
+ for (int i = 0; i < 2; i++) {
+ SrcType actual = ReadLittleEndianValue<SrcType>(&g[i]);
+ CHECK_EQ(expected, actual);
+ }
+ // Top lanes are zero-ed.
+ for (int i = 2; i < 4; i++) {
+ CHECK_EQ(0, ReadLittleEndianValue<SrcType>(&g[i]));
+ }
+ }
+}
+
+WASM_SIMD_TEST_NO_LOWERING(I32x4TruncSatF64x2SZero) {
+ RunI32x4TruncSatF64x2Test<int32_t>(execution_tier, lower_simd,
+ kExprI32x4TruncSatF64x2SZero);
+}
+
+WASM_SIMD_TEST_NO_LOWERING(I32x4TruncSatF64x2UZero) {
+ RunI32x4TruncSatF64x2Test<uint32_t>(execution_tier, lower_simd,
+ kExprI32x4TruncSatF64x2UZero);
+}
+
+WASM_SIMD_TEST_NO_LOWERING(F32x4DemoteF64x2Zero) {
+ WasmRunner<int32_t, double> r(execution_tier, lower_simd);
+ float* g = r.builder().AddGlobal<float>(kWasmS128);
+ BUILD(r,
+ WASM_GLOBAL_SET(
+ 0, WASM_SIMD_UNOP(kExprF32x4DemoteF64x2Zero,
+ WASM_SIMD_F64x2_SPLAT(WASM_LOCAL_GET(0)))),
+ WASM_ONE);
+
+ FOR_FLOAT64_INPUTS(x) {
+ r.Call(x);
+ float expected = DoubleToFloat32(x);
+ for (int i = 0; i < 2; i++) {
+ float actual = ReadLittleEndianValue<float>(&g[i]);
+ CheckFloatResult(x, x, expected, actual, true);
+ }
+ for (int i = 2; i < 4; i++) {
+ float actual = ReadLittleEndianValue<float>(&g[i]);
+ CheckFloatResult(x, x, 0, actual, true);
+ }
+ }
+}
+
+WASM_SIMD_TEST_NO_LOWERING(F64x2PromoteLowF32x4) {
+ WasmRunner<int32_t, float> r(execution_tier, lower_simd);
+ double* g = r.builder().AddGlobal<double>(kWasmS128);
+ BUILD(r,
+ WASM_GLOBAL_SET(
+ 0, WASM_SIMD_UNOP(kExprF64x2PromoteLowF32x4,
+ WASM_SIMD_F32x4_SPLAT(WASM_LOCAL_GET(0)))),
+ WASM_ONE);
+
+ FOR_FLOAT32_INPUTS(x) {
+ r.Call(x);
+ double expected = static_cast<double>(x);
+ for (int i = 0; i < 2; i++) {
+ double actual = ReadLittleEndianValue<double>(&g[i]);
+ CheckDoubleResult(x, x, expected, actual, true);
+ }
+ }
+}
+
void RunF64x2BinOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, DoubleBinOp expected_op) {
WasmRunner<int32_t, double, double> r(execution_tier, lower_simd);
@@ -1804,18 +1927,14 @@ WASM_SIMD_TEST(I32x4ConvertI16x8) {
}
}
-// TODO(v8:10972) Prototyping i64x2 convert from i32x4.
// Tests both signed and unsigned conversion from I32x4 (unpacking).
-#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || \
- V8_TARGET_ARCH_ARM
WASM_SIMD_TEST_NO_LOWERING(I64x2ConvertI32x4) {
- FLAG_SCOPE(wasm_simd_post_mvp);
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
// Create four output vectors to hold signed and unsigned results.
int64_t* g0 = r.builder().AddGlobal<int64_t>(kWasmS128);
int64_t* g1 = r.builder().AddGlobal<int64_t>(kWasmS128);
- int64_t* g2 = r.builder().AddGlobal<int64_t>(kWasmS128);
- int64_t* g3 = r.builder().AddGlobal<int64_t>(kWasmS128);
+ uint64_t* g2 = r.builder().AddGlobal<uint64_t>(kWasmS128);
+ uint64_t* g3 = r.builder().AddGlobal<uint64_t>(kWasmS128);
// Build fn to splat test value, perform conversions, and write the results.
byte value = 0;
byte temp1 = r.AllocateLocal(kWasmS128);
@@ -1833,17 +1952,16 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2ConvertI32x4) {
FOR_INT32_INPUTS(x) {
r.Call(x);
int64_t expected_signed = static_cast<int64_t>(x);
- int64_t expected_unsigned = static_cast<int64_t>(static_cast<uint32_t>(x));
+ uint64_t expected_unsigned =
+ static_cast<uint64_t>(static_cast<uint32_t>(x));
for (int i = 0; i < 2; i++) {
CHECK_EQ(expected_signed, ReadLittleEndianValue<int64_t>(&g0[i]));
CHECK_EQ(expected_signed, ReadLittleEndianValue<int64_t>(&g1[i]));
- CHECK_EQ(expected_unsigned, ReadLittleEndianValue<int64_t>(&g2[i]));
- CHECK_EQ(expected_unsigned, ReadLittleEndianValue<int64_t>(&g3[i]));
+ CHECK_EQ(expected_unsigned, ReadLittleEndianValue<uint64_t>(&g2[i]));
+ CHECK_EQ(expected_unsigned, ReadLittleEndianValue<uint64_t>(&g3[i]));
}
}
}
-#endif // V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 ||
- // V8_TARGET_ARCH_ARM
void RunI32x4UnOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, Int32UnOp expected_op) {
@@ -1880,14 +1998,10 @@ WASM_SIMD_TEST(S128Not) {
[](int32_t x) { return ~x; });
}
-#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || \
- V8_TARGET_ARCH_IA32
-// TODO(v8:11086) Prototype i32x4.extadd_pairwise_i16x8_{s,u}
template <typename Narrow, typename Wide>
void RunExtAddPairwiseTest(TestExecutionTier execution_tier,
LowerSimd lower_simd, WasmOpcode ext_add_pairwise,
WasmOpcode splat) {
- FLAG_SCOPE(wasm_simd_post_mvp);
constexpr int num_lanes = kSimd128Size / sizeof(Wide);
WasmRunner<int32_t, Narrow> r(execution_tier, lower_simd);
Wide* g = r.builder().template AddGlobal<Wide>(kWasmS128);
@@ -1930,8 +2044,6 @@ WASM_SIMD_TEST_NO_LOWERING(I16x8ExtAddPairwiseI8x16U) {
kExprI16x8ExtAddPairwiseI8x16U,
kExprI8x16Splat);
}
-#endif // V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 ||
- // V8_TARGET_ARCH_IA32
void RunI32x4BinOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, Int32BinOp expected_op) {
@@ -2157,8 +2269,8 @@ WASM_SIMD_TEST(I16x8ConvertI32x4) {
FOR_INT32_INPUTS(x) {
r.Call(x);
- int16_t expected_signed = Saturate<int16_t>(x);
- int16_t expected_unsigned = Saturate<uint16_t>(x);
+ int16_t expected_signed = base::saturated_cast<int16_t>(x);
+ int16_t expected_unsigned = base::saturated_cast<uint16_t>(x);
for (int i = 0; i < 8; i++) {
CHECK_EQ(expected_signed, ReadLittleEndianValue<int16_t>(&g0[i]));
CHECK_EQ(expected_unsigned, ReadLittleEndianValue<int16_t>(&g1[i]));
@@ -2325,7 +2437,6 @@ WASM_SIMD_TEST(I16x8RoundingAverageU) {
}
WASM_SIMD_TEST_NO_LOWERING(I16x8Q15MulRSatS) {
- FLAG_SCOPE(wasm_simd_post_mvp);
RunI16x8BinOpTest<int16_t>(execution_tier, lower_simd, kExprI16x8Q15MulRSatS,
SaturateRoundingQMul<int16_t>);
}
@@ -2542,10 +2653,7 @@ WASM_SIMD_TEST(I8x16Abs) {
RunI8x16UnOpTest(execution_tier, lower_simd, kExprI8x16Abs, Abs);
}
-#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
-// TODO(v8:11002) Prototype i8x16.popcnt.
WASM_SIMD_TEST_NO_LOWERING(I8x16Popcnt) {
- FLAG_SCOPE(wasm_simd_post_mvp);
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
// Global to hold output.
int8_t* g = r.builder().AddGlobal<int8_t>(kWasmS128);
@@ -2565,14 +2673,13 @@ WASM_SIMD_TEST_NO_LOWERING(I8x16Popcnt) {
}
}
}
-#endif // V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
// Tests both signed and unsigned conversion from I16x8 (packing).
WASM_SIMD_TEST(I8x16ConvertI16x8) {
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
// Create output vectors to hold signed and unsigned results.
- int8_t* g0 = r.builder().AddGlobal<int8_t>(kWasmS128);
- int8_t* g1 = r.builder().AddGlobal<int8_t>(kWasmS128);
+ int8_t* g_s = r.builder().AddGlobal<int8_t>(kWasmS128);
+ uint8_t* g_u = r.builder().AddGlobal<uint8_t>(kWasmS128);
// Build fn to splat test value, perform conversions, and write the results.
byte value = 0;
byte temp1 = r.AllocateLocal(kWasmS128);
@@ -2587,11 +2694,11 @@ WASM_SIMD_TEST(I8x16ConvertI16x8) {
FOR_INT16_INPUTS(x) {
r.Call(x);
- int8_t expected_signed = Saturate<int8_t>(x);
- int8_t expected_unsigned = Saturate<uint8_t>(x);
+ int8_t expected_signed = base::saturated_cast<int8_t>(x);
+ uint8_t expected_unsigned = base::saturated_cast<uint8_t>(x);
for (int i = 0; i < 16; i++) {
- CHECK_EQ(expected_signed, ReadLittleEndianValue<int8_t>(&g0[i]));
- CHECK_EQ(expected_unsigned, ReadLittleEndianValue<int8_t>(&g1[i]));
+ CHECK_EQ(expected_signed, ReadLittleEndianValue<int8_t>(&g_s[i]));
+ CHECK_EQ(expected_unsigned, ReadLittleEndianValue<uint8_t>(&g_u[i]));
}
}
}
@@ -3271,14 +3378,14 @@ WASM_SIMD_TEST(S8x16MultiShuffleFuzz) {
byte reduced = r.AllocateLocal(kWasmI32); \
BUILD(r, WASM_LOCAL_SET(zero, WASM_SIMD_I##format##_SPLAT(int_type(0))), \
WASM_LOCAL_SET( \
- reduced, WASM_SIMD_UNOP(kExprV##format##AnyTrue, \
+ reduced, WASM_SIMD_UNOP(kExprV128AnyTrue, \
WASM_SIMD_BINOP(kExprI##format##Eq, \
WASM_LOCAL_GET(zero), \
WASM_LOCAL_GET(zero)))), \
WASM_IF(WASM_I32_EQ(WASM_LOCAL_GET(reduced), WASM_ZERO), \
WASM_RETURN1(WASM_ZERO)), \
WASM_LOCAL_SET( \
- reduced, WASM_SIMD_UNOP(kExprV##format##AnyTrue, \
+ reduced, WASM_SIMD_UNOP(kExprV128AnyTrue, \
WASM_SIMD_BINOP(kExprI##format##Ne, \
WASM_LOCAL_GET(zero), \
WASM_LOCAL_GET(zero)))), \
@@ -3302,14 +3409,14 @@ WASM_SIMD_TEST(S8x16MultiShuffleFuzz) {
WASM_SIMD_I##format##_REPLACE_LANE( \
lanes - 1, WASM_LOCAL_GET(zero), int_type(1))), \
WASM_LOCAL_SET( \
- reduced, WASM_SIMD_UNOP(kExprV##format##AnyTrue, \
+ reduced, WASM_SIMD_UNOP(kExprV128AnyTrue, \
WASM_SIMD_BINOP(kExprI##format##Eq, \
WASM_LOCAL_GET(one_one), \
WASM_LOCAL_GET(zero)))), \
WASM_IF(WASM_I32_EQ(WASM_LOCAL_GET(reduced), WASM_ZERO), \
WASM_RETURN1(WASM_ZERO)), \
WASM_LOCAL_SET( \
- reduced, WASM_SIMD_UNOP(kExprV##format##AnyTrue, \
+ reduced, WASM_SIMD_UNOP(kExprV128AnyTrue, \
WASM_SIMD_BINOP(kExprI##format##Ne, \
WASM_LOCAL_GET(one_one), \
WASM_LOCAL_GET(zero)))), \
@@ -3333,6 +3440,7 @@ WASM_SIMD_TEST(S8x16MultiShuffleFuzz) {
CHECK_EQ(1, r.Call()); \
}
+WASM_SIMD_BOOL_REDUCTION_TEST(64x2, 2, WASM_I64V)
WASM_SIMD_BOOL_REDUCTION_TEST(32x4, 4, WASM_I32V)
WASM_SIMD_BOOL_REDUCTION_TEST(16x8, 8, WASM_I32V)
WASM_SIMD_BOOL_REDUCTION_TEST(8x16, 16, WASM_I32V)
@@ -3590,7 +3698,7 @@ WASM_SIMD_TEST(SimdF32x4SetGlobal) {
CHECK_EQ(GetScalar(global, 3), 65.0f);
}
-#if V8_TARGET_ARCH_ARM64
+#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32
// TODO(v8:11168): Prototyping prefetch.
WASM_SIMD_TEST(SimdPrefetch) {
FLAG_SCOPE(wasm_simd_post_mvp);
@@ -3642,7 +3750,7 @@ WASM_SIMD_TEST(SimdPrefetch) {
}
}
}
-#endif // V8_TARGET_ARCH_ARM64
+#endif // V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32
WASM_SIMD_TEST(SimdLoadStoreLoad) {
WasmRunner<int32_t> r(execution_tier, lower_simd);
@@ -3995,13 +4103,9 @@ WASM_SIMD_TEST(S128Load64Zero) {
RunLoadZeroTest<int64_t>(execution_tier, lower_simd, kExprS128Load64Zero);
}
-#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 || \
- V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_MIPS64
-// TODO(v8:10975): Prototyping load lane and store lane.
template <typename T>
void RunLoadLaneTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode load_op, WasmOpcode splat_op) {
- FLAG_SCOPE(wasm_simd_post_mvp);
WasmOpcode const_op =
splat_op == kExprI64x2Splat ? kExprI64Const : kExprI32Const;
@@ -4100,12 +4204,6 @@ WASM_SIMD_TEST_NO_LOWERING(S128Load64Lane) {
template <typename T>
void RunStoreLaneTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode store_op, WasmOpcode splat_op) {
- FLAG_SCOPE(wasm_simd_post_mvp);
- if (execution_tier == TestExecutionTier::kLiftoff) {
- // Not yet implemented.
- return;
- }
-
constexpr int lanes = kSimd128Size / sizeof(T);
constexpr int mem_index = 16; // Store to mem index 16 (bytes).
constexpr int splat_value = 33;
@@ -4196,9 +4294,6 @@ WASM_SIMD_TEST_NO_LOWERING(S128Store64Lane) {
kExprI64x2Splat);
}
-#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 ||
- // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_MIPS64
-
#define WASM_SIMD_ANYTRUE_TEST(format, lanes, max, param_type) \
WASM_SIMD_TEST(S##format##AnyTrue) { \
FLAG_SCOPE(wasm_simd_post_mvp); \
@@ -4208,7 +4303,7 @@ WASM_SIMD_TEST_NO_LOWERING(S128Store64Lane) {
BUILD( \
r, \
WASM_LOCAL_SET(simd, WASM_SIMD_I##format##_SPLAT(WASM_LOCAL_GET(0))), \
- WASM_SIMD_UNOP(kExprV##format##AnyTrue, WASM_LOCAL_GET(simd))); \
+ WASM_SIMD_UNOP(kExprV128AnyTrue, WASM_LOCAL_GET(simd))); \
CHECK_EQ(1, r.Call(max)); \
CHECK_EQ(1, r.Call(5)); \
CHECK_EQ(0, r.Call(0)); \
@@ -4220,11 +4315,11 @@ WASM_SIMD_ANYTRUE_TEST(8x16, 16, 0xff, int32_t)
// Special any true test cases that splats a -0.0 double into a i64x2.
// This is specifically to ensure that our implementation correct handles that
// 0.0 and -0.0 will be different in an anytrue (IEEE753 says they are equals).
-WASM_SIMD_TEST(V32x4AnytrueWithNegativeZero) {
+WASM_SIMD_TEST(V128AnytrueWithNegativeZero) {
WasmRunner<int32_t, int64_t> r(execution_tier, lower_simd);
byte simd = r.AllocateLocal(kWasmS128);
BUILD(r, WASM_LOCAL_SET(simd, WASM_SIMD_I64x2_SPLAT(WASM_LOCAL_GET(0))),
- WASM_SIMD_UNOP(kExprV32x4AnyTrue, WASM_LOCAL_GET(simd)));
+ WASM_SIMD_UNOP(kExprV128AnyTrue, WASM_LOCAL_GET(simd)));
CHECK_EQ(1, r.Call(0x8000000000000000));
CHECK_EQ(0, r.Call(0x0000000000000000));
}
@@ -4243,6 +4338,7 @@ WASM_SIMD_TEST(V32x4AnytrueWithNegativeZero) {
CHECK_EQ(1, r.Call(0x1)); \
CHECK_EQ(0, r.Call(0)); \
}
+WASM_SIMD_ALLTRUE_TEST(64x2, 2, 0xffffffffffffffff, int64_t)
WASM_SIMD_ALLTRUE_TEST(32x4, 4, 0xffffffff, int32_t)
WASM_SIMD_ALLTRUE_TEST(16x8, 8, 0xffff, int32_t)
WASM_SIMD_ALLTRUE_TEST(8x16, 16, 0xff, int32_t)
diff --git a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
index 863256818a..92ad205070 100644
--- a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
+++ b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
@@ -1372,6 +1372,28 @@ STREAM_TEST(TestProfilingMidStreaming) {
cpu_profiler->Dispose();
}
+STREAM_TEST(TierDownWithError) {
+ // https://crbug.com/1160031
+ StreamTester tester(isolate);
+ Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ Zone* zone = tester.zone();
+
+ ZoneBuffer buffer(zone);
+ {
+ TestSignatures sigs;
+ WasmModuleBuilder builder(zone);
+ // Type error at i32.add.
+ builder.AddFunction(sigs.v_v())->Emit(kExprI32Add);
+ builder.WriteTo(&buffer);
+ }
+
+ i_isolate->wasm_engine()->TierDownAllModulesPerIsolate(i_isolate);
+
+ tester.OnBytesReceived(buffer.begin(), buffer.size());
+ tester.FinishStream();
+ tester.RunCompilerTasks();
+}
+
#undef STREAM_TEST
} // namespace wasm
diff --git a/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc
index 2d7b4024d7..156bfb55ac 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc
@@ -179,16 +179,16 @@ struct WasmValWrapper {
#ifdef DEBUG
std::ostream& operator<<(std::ostream& out, const WasmValWrapper& wrapper) {
switch (wrapper.val.type().kind()) {
- case ValueType::kI32:
+ case kI32:
out << "i32: " << wrapper.val.to<int32_t>();
break;
- case ValueType::kI64:
+ case kI64:
out << "i64: " << wrapper.val.to<int64_t>();
break;
- case ValueType::kF32:
+ case kF32:
out << "f32: " << wrapper.val.to<float>();
break;
- case ValueType::kF64:
+ case kF64:
out << "f64: " << wrapper.val.to<double>();
break;
default:
diff --git a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
index 2a0f441eb7..e23a549ddd 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
@@ -61,14 +61,6 @@ class WasmSerializationTest {
memset(const_cast<uint8_t*>(wire_bytes_.data()), 0, wire_bytes_.size() / 2);
}
- void InvalidateNumFunctions() {
- Address num_functions_slot =
- reinterpret_cast<Address>(serialized_bytes_.data()) +
- WasmSerializer::kHeaderSize;
- CHECK_EQ(1, base::ReadUnalignedValue<uint32_t>(num_functions_slot));
- base::WriteUnalignedValue<uint32_t>(num_functions_slot, 0);
- }
-
MaybeHandle<WasmModuleObject> Deserialize(
Vector<const char> source_url = {}) {
return DeserializeNativeModule(CcTest::i_isolate(),
@@ -239,16 +231,6 @@ TEST(DeserializeNoSerializedData) {
test.CollectGarbage();
}
-TEST(DeserializeInvalidNumFunctions) {
- WasmSerializationTest test;
- {
- HandleScope scope(CcTest::i_isolate());
- test.InvalidateNumFunctions();
- CHECK(test.Deserialize().is_null());
- }
- test.CollectGarbage();
-}
-
TEST(DeserializeWireBytesAndSerializedDataInvalid) {
WasmSerializationTest test;
{
diff --git a/deps/v8/test/cctest/wasm/test-wasm-stack.cc b/deps/v8/test/cctest/wasm/test-wasm-stack.cc
index 7ef79a6350..9faab4479e 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-stack.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-stack.cc
@@ -196,11 +196,11 @@ WASM_COMPILED_EXEC_TEST(CollectDetailedWasmStack_WasmUrl) {
Handle<FixedArray> stack_trace_object =
isolate->GetDetailedStackTrace(Handle<JSObject>::cast(exception));
CHECK(!stack_trace_object.is_null());
- Handle<StackTraceFrame> stack_frame = Handle<StackTraceFrame>::cast(
- handle(stack_trace_object->get(0), isolate));
+ Handle<StackFrameInfo> stack_frame(
+ StackFrameInfo::cast(stack_trace_object->get(0)), isolate);
MaybeHandle<String> maybe_stack_trace_str =
- SerializeStackTraceFrame(isolate, stack_frame);
+ SerializeStackFrameInfo(isolate, stack_frame);
CHECK(!maybe_stack_trace_str.is_null());
Handle<String> stack_trace_str = maybe_stack_trace_str.ToHandleChecked();
diff --git a/deps/v8/test/cctest/wasm/wasm-run-utils.cc b/deps/v8/test/cctest/wasm/wasm-run-utils.cc
index 2657d7e9a7..82f7824315 100644
--- a/deps/v8/test/cctest/wasm/wasm-run-utils.cc
+++ b/deps/v8/test/cctest/wasm/wasm-run-utils.cc
@@ -335,6 +335,7 @@ Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() {
auto native_module = isolate_->wasm_engine()->NewNativeModule(
isolate_, enabled_features_, test_module_, code_size_estimate);
native_module->SetWireBytes(OwnedVector<const uint8_t>());
+ native_module->compilation_state()->set_compilation_id(0);
constexpr Vector<const char> kNoSourceUrl{"", 0};
Handle<Script> script = isolate_->wasm_engine()->GetOrCreateScript(
isolate_, native_module, kNoSourceUrl);
diff --git a/deps/v8/test/cctest/wasm/wasm-run-utils.h b/deps/v8/test/cctest/wasm/wasm-run-utils.h
index eeb29acf81..f873390283 100644
--- a/deps/v8/test/cctest/wasm/wasm-run-utils.h
+++ b/deps/v8/test/cctest/wasm/wasm-run-utils.h
@@ -233,12 +233,16 @@ class TestingModuleBuilder {
void SetExecutable() { native_module_->SetExecutable(true); }
- void TierDown() {
+ void SetTieredDown() {
native_module_->SetTieringState(kTieredDown);
- native_module_->RecompileForTiering();
execution_tier_ = TestExecutionTier::kLiftoff;
}
+ void TierDown() {
+ SetTieredDown();
+ native_module_->RecompileForTiering();
+ }
+
CompilationEnv CreateCompilationEnv();
ExecutionTier execution_tier() const {