Commit a9b8a567 authored by titzer's avatar titzer Committed by Commit bot

[wasm] Implement polymorphic checking, matching the reference interpreter.

R=rossberg@chromium.org, bradnelson@chromium.org
BUG=chromium:682659

Review-Url: https://codereview.chromium.org/2670673002
Cr-Commit-Position: refs/heads/master@{#42904}
parent a62322aa
This diff is collapsed.
......@@ -36,8 +36,7 @@ const ValueType kWasmI64 = MachineRepresentation::kWord64;
const ValueType kWasmF32 = MachineRepresentation::kFloat32;
const ValueType kWasmF64 = MachineRepresentation::kFloat64;
const ValueType kWasmS128 = MachineRepresentation::kSimd128;
// We use kTagged here because kNone is already used by kWasmStmt.
const ValueType kWasmEnd = MachineRepresentation::kTagged;
const ValueType kWasmVar = MachineRepresentation::kTagged;
typedef Signature<ValueType> FunctionSig;
std::ostream& operator<<(std::ostream& os, const FunctionSig& function);
......@@ -649,10 +648,9 @@ class V8_EXPORT_PRIVATE WasmOpcodes {
return 's';
case kWasmStmt:
return 'v';
case kWasmEnd:
return 'x';
case kWasmVar:
return '*';
default:
UNREACHABLE();
return '?';
}
}
......@@ -671,8 +669,8 @@ class V8_EXPORT_PRIVATE WasmOpcodes {
return "s128";
case kWasmStmt:
return "<stmt>";
case kWasmEnd:
return "<end>";
case kWasmVar:
return "<var>";
default:
return "<unknown>";
}
......
This diff is collapsed.
......@@ -727,7 +727,7 @@ WASM_EXEC_TEST(Return12) {
WASM_EXEC_TEST(Return17) {
WasmRunner<int32_t> r(execution_mode);
BUILD(r, WASM_BLOCK(RET_I8(17)));
BUILD(r, WASM_BLOCK(RET_I8(17)), WASM_ZERO);
CHECK_EQ(17, r.Call());
}
......@@ -836,11 +836,10 @@ WASM_EXEC_TEST(BrIf_strict) {
WASM_EXEC_TEST(Br_height) {
WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_BLOCK_I(WASM_BLOCK_I(WASM_BRV_IFD(0, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(0)),
WASM_RETURN1(WASM_I32V_1(9)),
WASM_I32V_1(7), WASM_I32V_1(7)),
WASM_BRV(0, WASM_I32V_1(8))));
BUILD(r, WASM_BLOCK_I(
WASM_BLOCK(WASM_BRV_IFD(0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)),
WASM_RETURN1(WASM_I32V_1(9))),
WASM_BRV(0, WASM_I32V_1(8))));
for (int32_t i = 0; i < 5; i++) {
int32_t expected = i != 0 ? 8 : 9;
......@@ -1277,7 +1276,8 @@ WASM_EXEC_TEST(Block_IfElse_P_return) {
BUILD(r, // --
WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
RET_I8(81), // --
RET_I8(82))); // --
RET_I8(82)), // --
WASM_ZERO); // --
FOR_INT32_INPUTS(i) {
int32_t expected = *i ? 81 : 82;
CHECK_EQ(expected, r.Call(*i));
......@@ -1298,7 +1298,7 @@ WASM_EXEC_TEST(Block_If_P_assign) {
WASM_EXEC_TEST(DanglingAssign) {
WasmRunner<int32_t, int32_t> r(execution_mode);
// { return 0; p0 = 0; }
BUILD(r, B2(RET_I8(99), WASM_SET_LOCAL(0, WASM_ZERO)));
BUILD(r, WASM_BLOCK_I(RET_I8(99), WASM_TEE_LOCAL(0, WASM_ZERO)));
CHECK_EQ(99, r.Call(1));
}
......@@ -1764,7 +1764,7 @@ WASM_EXEC_TEST(MemF64_Mul) {
WASM_EXEC_TEST(Build_Wasm_Infinite_Loop) {
WasmRunner<int32_t, int32_t> r(execution_mode);
// Only build the graph and compile, don't run.
BUILD(r, WASM_INFINITE_LOOP);
BUILD(r, WASM_INFINITE_LOOP, WASM_ZERO);
}
WASM_EXEC_TEST(Build_Wasm_Infinite_Loop_effect) {
......@@ -1807,24 +1807,33 @@ TEST(Build_Wasm_Unreachable3) {
TEST(Build_Wasm_UnreachableIf1) {
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
BUILD(r, WASM_UNREACHABLE, WASM_IF(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)));
BUILD(r, WASM_UNREACHABLE,
WASM_IF(WASM_GET_LOCAL(0), WASM_SEQ(WASM_GET_LOCAL(0), WASM_DROP)),
WASM_ZERO);
}
TEST(Build_Wasm_UnreachableIf2) {
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
BUILD(r, WASM_UNREACHABLE,
WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_UNREACHABLE));
WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_UNREACHABLE));
}
WASM_EXEC_TEST(Unreachable_Load) {
WasmRunner<int32_t, int32_t> r(execution_mode);
r.module().AddMemory(0L);
r.module().AddMemory(8);
BUILD(r, WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)),
WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))));
CHECK_EQ(11, r.Call(11));
CHECK_EQ(21, r.Call(21));
}
WASM_EXEC_TEST(BrV_Fallthrough) {
WasmRunner<int32_t> r(execution_mode);
BUILD(r, WASM_BLOCK_I(WASM_BLOCK(WASM_BRV(1, WASM_I32V_1(42))),
WASM_I32V_1(22)));
CHECK_EQ(42, r.Call());
}
WASM_EXEC_TEST(Infinite_Loop_not_taken1) {
WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_INFINITE_LOOP), WASM_I32V_1(45));
......@@ -1834,9 +1843,10 @@ WASM_EXEC_TEST(Infinite_Loop_not_taken1) {
WASM_EXEC_TEST(Infinite_Loop_not_taken2) {
WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_BLOCK_I(WASM_IF_ELSE(WASM_GET_LOCAL(0),
WASM_BRV(1, WASM_I32V_1(45)),
WASM_INFINITE_LOOP)));
BUILD(r, WASM_BLOCK_I(
WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I32V_1(45)),
WASM_INFINITE_LOOP),
WASM_ZERO));
// Run the code, but don't go into the infinite loop.
CHECK_EQ(45, r.Call(1));
}
......
......@@ -264,7 +264,7 @@ TEST(WasmStepInAndOut) {
WASM_SET_LOCAL(
0, WASM_BINOP(kExprI32Sub, WASM_GET_LOCAL(0), WASM_ONE)),
WASM_CALL_FUNCTION(runner.function_index(), WASM_GET_LOCAL(0)),
WASM_BR(1)));
WASM_DROP, WASM_BR(1)));
Isolate* isolate = runner.main_isolate();
Handle<JSFunction> main_fun_wrapper =
......
......@@ -39,7 +39,8 @@ let nop = kExprNop;
let iadd = kExprI32Add;
let unr = kExprUnreachable;
let ret = kExprReturn;
let br0 = [kExprBr, 0]
let br0 = [kExprBr, 0];
let brt = [kExprBrTable, 0, 0];
let f32 = [kExprF32Const, 0, 0, 0, 0];
let zero = [kExprI32Const, 0];
let if_else_empty = [kExprIf, kWasmStmt, kExprElse, kExprEnd];
......@@ -51,7 +52,7 @@ let block_block_unr = [kExprBlock, kWasmStmt, kExprBlock, kWasmStmt, kExprUnreac
let drop = kExprDrop;
run(V, "U", [unr]);
run(V, "U U", [unr, unr]);
run(V, 'U U', [unr, unr]);
run(V, "(if 0 () else ())", [...zero, ...if_else_empty]);
run(V, "(if 0 U)", [...zero, ...if_unr]);
run(V, "(if 0 U U)", [...zero, ...if_else_unr]);
......@@ -64,26 +65,33 @@ run(V, "(block U)", [...block_unr]);
run(V, "(loop U)", [...loop_unr]);
run(V, "(if 0 U U)", [...zero, ...if_else_unr]);
run(V, "U nop", [unr, nop]);
run(V, "U iadd drop", [unr, iadd, drop]);
run(V, "br0 iadd drop", [br0, iadd, drop]);
run(V, "ret iadd drop", [ret, iadd, drop]);
run(V, "br0 iadd", [br0, iadd]);
run(V, "ret iadd", [ret, iadd]);
run(V, "0 0 br0 iadd", [...zero, ...zero, br0, iadd]);
run(V, "0 0 ret iadd", [...zero, ...zero, ret, iadd]);
run(V, "(block U) iadd drop", [...block_unr, iadd, drop]);
run(V, "(block (block U)) iadd drop", [...block_block_unr, iadd, drop]);
run(V, "(loop U) iadd drop", [...loop_unr, iadd]);
run(V, "(if 0 U U) iadd drop", [...zero, ...if_else_unr, iadd, drop]);
run(V, "U 0 0 iadd drop", [unr, ...zero, ...zero, iadd, drop]);
run(V, 'U nop', [unr, nop]);
run(V, 'U iadd drop', [unr, iadd, drop]);
run(V, 'br0 iadd drop', [...br0, iadd, drop]);
run(V, '0 brt iadd drop', [...zero, ...brt, iadd, drop]);
run(V, 'ret iadd drop', [ret, iadd, drop]);
run(V, 'U 0 0 iadd drop', [unr, ...zero, ...zero, iadd, drop]);
run(V, 'br0 0 0 iadd drop', [...br0, ...zero, ...zero, iadd, drop]);
run(V, '0 brt 0 0 iadd drop', [...zero, ...brt, ...zero, ...zero, iadd, drop]);
run(V, 'ret 0 0 iadd drop', [ret, ...zero, ...zero, iadd, drop]);
run(I, 'br0 iadd', [...br0, iadd]);
run(I, '0 brt iadd', [...zero, ...brt, iadd]);
run(I, 'ret iadd', [ret, iadd]);
run(I, '0 0 br0 iadd', [...zero, ...zero, ...br0, iadd]);
run(I, '0 0 ret iadd', [...zero, ...zero, ret, iadd]);
run(I, '(block U) iadd drop', [...block_unr, iadd, drop]);
run(I, '(block (block U)) iadd drop', [...block_block_unr, iadd, drop]);
run(I, '(loop U) iadd drop', [...loop_unr, iadd]);
run(I, '(if 0 U U) iadd drop', [...zero, ...if_else_unr, iadd, drop]);
run(V, 'U 0 0 iadd drop', [unr, ...zero, ...zero, iadd, drop]);
run(V, "(block U) 0 0 iadd drop", [...block_unr, ...zero, ...zero, iadd, drop]);
run(V, "(loop U) 0 0 iadd drop", [...loop_unr, ...zero, ...zero, iadd, drop]);
run(V, "(block (block U)) 0 0 iadd drop", [...block_block_unr, ...zero, ...zero, iadd, drop]);
run(V, "0 0 U iadd drop", [...zero, ...zero, unr, iadd, drop]);
run(V, '0 0 U iadd drop', [...zero, ...zero, unr, iadd, drop]);
run(V, "0 0 (block U) iadd drop", [...zero, ...zero, ...block_unr, iadd, drop]);
run(V, "0 0 (loop U) iadd drop", [...zero, ...zero, ...loop_unr, iadd, drop]);
run(V, "0 0 (block (block U)) iadd drop", [...zero, ...zero, ...block_block_unr, iadd, drop]);
......@@ -96,10 +104,10 @@ run(I, "(block U) 0f 0 iadd drop", [...block_unr, ...f32, ...zero, iadd, drop]);
run(I, "(loop U) 0f 0 iadd drop", [...loop_unr, ...f32, ...zero, iadd, drop]);
run(I, "(block (block U)) 0f 0 iadd drop", [...block_block_unr, ...f32, ...zero, iadd, drop]);
run(V, "0f U iadd drop", [...f32, unr, iadd, drop]);
run(V, "0f 0 U iadd drop", [...f32, ...zero, unr, iadd, drop]);
run(V, '0f U iadd drop', [...f32, unr, iadd, drop]);
run(V, '0f 0 U iadd drop', [...f32, ...zero, unr, iadd, drop]);
run(I, "0f 0 (block U) iadd drop", [...f32, ...zero, ...block_unr, iadd, drop]);
run(V, "0f U 0 iadd drop", [...f32, unr, ...zero, iadd, drop]);
run(V, '0f U 0 iadd drop', [...f32, unr, ...zero, iadd, drop]);
run(I, "0 U 0f iadd drop", [...zero, unr, ...zero, ...f32, iadd, drop]);
run(I, "0f (block U) 0 iadd drop", [...f32, ...block_unr, ...zero, iadd, drop]);
run(I, "0 (block U) 0f iadd drop", [...zero, ...block_unr, ...f32, iadd, drop]);
......@@ -671,7 +671,7 @@ TEST_F(FunctionBodyDecoderTest, Block3_continue) {
}
TEST_F(FunctionBodyDecoderTest, NestedBlock_return) {
EXPECT_VERIFIES(i_i, B1(B1(WASM_RETURN1(WASM_ZERO))));
EXPECT_VERIFIES(i_i, B1(B1(WASM_RETURN1(WASM_ZERO))), WASM_ZERO);
}
TEST_F(FunctionBodyDecoderTest, BlockBrBinop) {
......@@ -861,13 +861,18 @@ TEST_F(FunctionBodyDecoderTest, Loop2_break) {
EXPECT_VERIFIES(v_i, WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO), WASM_BR(1)));
}
TEST_F(FunctionBodyDecoderTest, InfiniteLoop) {
EXPECT_VERIFIES(i_i, WASM_LOOP(WASM_BR(0)));
EXPECT_VERIFIES(i_i, WASM_LOOP(WASM_BRV(1, WASM_ZERO)));
TEST_F(FunctionBodyDecoderTest, InfiniteLoop1) {
EXPECT_VERIFIES(i_i, WASM_LOOP(WASM_BR(0)), WASM_ZERO);
EXPECT_VERIFIES(i_i, WASM_LOOP(WASM_BR(0)), WASM_ZERO);
EXPECT_VERIFIES(i_i, WASM_LOOP_I(WASM_BRV(1, WASM_ZERO)));
}
TEST_F(FunctionBodyDecoderTest, InfiniteLoop2) {
EXPECT_FAILURE(i_i, WASM_LOOP(WASM_BR(0), WASM_ZERO), WASM_ZERO);
}
TEST_F(FunctionBodyDecoderTest, Loop2_unreachable) {
EXPECT_VERIFIES(i_i, WASM_LOOP(WASM_BR(0), WASM_NOP));
EXPECT_VERIFIES(i_i, WASM_LOOP_I(WASM_BR(0), WASM_NOP));
}
TEST_F(FunctionBodyDecoderTest, LoopType) {
......@@ -926,25 +931,45 @@ TEST_F(FunctionBodyDecoderTest, ReturnVoid3) {
}
TEST_F(FunctionBodyDecoderTest, Unreachable1) {
EXPECT_VERIFIES(v_v, kExprUnreachable);
EXPECT_VERIFIES(v_v, kExprUnreachable, kExprUnreachable);
EXPECT_VERIFIES(v_v, B2(WASM_UNREACHABLE, WASM_ZERO));
EXPECT_VERIFIES(v_v, B2(WASM_BR(0), WASM_ZERO));
EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_UNREACHABLE, WASM_ZERO));
EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_BR(0), WASM_ZERO));
EXPECT_VERIFIES(v_v, WASM_UNREACHABLE);
EXPECT_VERIFIES(v_v, WASM_UNREACHABLE, WASM_UNREACHABLE);
EXPECT_VERIFIES(i_i, WASM_UNREACHABLE, WASM_ZERO);
}
TEST_F(FunctionBodyDecoderTest, Unreachable2) {
EXPECT_FAILURE(v_v, B2(WASM_UNREACHABLE, WASM_ZERO));
EXPECT_FAILURE(v_v, B2(WASM_BR(0), WASM_ZERO));
}
TEST_F(FunctionBodyDecoderTest, Unreachable_binop) {
TEST_F(FunctionBodyDecoderTest, UnreachableLoop1) {
EXPECT_FAILURE(v_v, WASM_LOOP(WASM_UNREACHABLE, WASM_ZERO));
EXPECT_FAILURE(v_v, WASM_LOOP(WASM_BR(0), WASM_ZERO));
EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_UNREACHABLE, WASM_NOP));
EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_BR(0), WASM_NOP));
}
TEST_F(FunctionBodyDecoderTest, Unreachable_binop1) {
EXPECT_VERIFIES(i_i, WASM_I32_AND(WASM_ZERO, WASM_UNREACHABLE));
EXPECT_VERIFIES(i_i, WASM_I32_AND(WASM_UNREACHABLE, WASM_ZERO));
}
TEST_F(FunctionBodyDecoderTest, Unreachable_select) {
TEST_F(FunctionBodyDecoderTest, Unreachable_binop2) {
EXPECT_VERIFIES(i_i, WASM_I32_AND(WASM_F32(0.0), WASM_UNREACHABLE));
EXPECT_FAILURE(i_i, WASM_I32_AND(WASM_UNREACHABLE, WASM_F32(0.0)));
}
TEST_F(FunctionBodyDecoderTest, Unreachable_select1) {
EXPECT_VERIFIES(i_i, WASM_SELECT(WASM_UNREACHABLE, WASM_ZERO, WASM_ZERO));
EXPECT_VERIFIES(i_i, WASM_SELECT(WASM_ZERO, WASM_UNREACHABLE, WASM_ZERO));
EXPECT_VERIFIES(i_i, WASM_SELECT(WASM_ZERO, WASM_ZERO, WASM_UNREACHABLE));
}
TEST_F(FunctionBodyDecoderTest, Unreachable_select2) {
EXPECT_VERIFIES(i_i, WASM_SELECT(WASM_F32(0.0), WASM_UNREACHABLE, WASM_ZERO));
EXPECT_FAILURE(i_i, WASM_SELECT(WASM_UNREACHABLE, WASM_F32(0.0), WASM_ZERO));
EXPECT_FAILURE(i_i, WASM_SELECT(WASM_UNREACHABLE, WASM_ZERO, WASM_F32(0.0)));
}
TEST_F(FunctionBodyDecoderTest, If1) {
EXPECT_VERIFIES(
i_i, WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I32V_1(9), WASM_I32V_1(8)));
......@@ -2133,15 +2158,20 @@ TEST_F(FunctionBodyDecoderTest, BrTable_invalid_br2) {
}
}
TEST_F(FunctionBodyDecoderTest, BrUnreachable) {
static byte code[] = {WASM_GET_LOCAL(0), kExprBrTable, 0,
BR_TARGET(0), kExprSetLocal, 0};
EXPECT_VERIFIES_C(v_i, code);
TEST_F(FunctionBodyDecoderTest, BrUnreachable1) {
EXPECT_VERIFIES(v_i, WASM_GET_LOCAL(0), kExprBrTable, 0, BR_TARGET(0));
}
TEST_F(FunctionBodyDecoderTest, BrUnreachable2) {
EXPECT_VERIFIES(v_i, WASM_GET_LOCAL(0), kExprBrTable, 0, BR_TARGET(0),
WASM_NOP);
EXPECT_FAILURE(v_i, WASM_GET_LOCAL(0), kExprBrTable, 0, BR_TARGET(0),
WASM_ZERO);
}
TEST_F(FunctionBodyDecoderTest, Brv1) {
EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_BRV(0, WASM_ZERO)));
EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_LOOP(WASM_BRV(2, WASM_ZERO))));
EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_LOOP_I(WASM_BRV(2, WASM_ZERO))));
}
TEST_F(FunctionBodyDecoderTest, Brv1_type) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment