diff options
Diffstat (limited to 'deps/v8/test/unittests/wasm')
-rw-r--r-- | deps/v8/test/unittests/wasm/decoder-unittest.cc | 110 | ||||
-rw-r--r-- | deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc | 244 | ||||
-rw-r--r-- | deps/v8/test/unittests/wasm/leb-helper-unittest.cc | 26 | ||||
-rw-r--r-- | deps/v8/test/unittests/wasm/module-decoder-unittest.cc | 45 | ||||
-rw-r--r-- | deps/v8/test/unittests/wasm/streaming-decoder-unittest.cc | 11 | ||||
-rw-r--r-- | deps/v8/test/unittests/wasm/trap-handler-unittest.cc | 69 | ||||
-rw-r--r-- | deps/v8/test/unittests/wasm/wasm-heap-unittest.cc | 235 |
7 files changed, 632 insertions, 108 deletions
diff --git a/deps/v8/test/unittests/wasm/decoder-unittest.cc b/deps/v8/test/unittests/wasm/decoder-unittest.cc index 0f11933383..24606a43fd 100644 --- a/deps/v8/test/unittests/wasm/decoder-unittest.cc +++ b/deps/v8/test/unittests/wasm/decoder-unittest.cc @@ -19,50 +19,54 @@ class DecoderTest : public TestWithZone { Decoder decoder; }; -#define CHECK_UINT32V_INLINE(expected, expected_length, ...) \ - do { \ - const byte data[] = {__VA_ARGS__}; \ - decoder.Reset(data, data + sizeof(data)); \ - unsigned length; \ - EXPECT_EQ(static_cast<uint32_t>(expected), \ - decoder.read_u32v<true>(decoder.start(), &length)); \ - EXPECT_EQ(static_cast<unsigned>(expected_length), length); \ - EXPECT_EQ(data, decoder.pc()); \ - EXPECT_TRUE(decoder.ok()); \ - EXPECT_EQ(static_cast<uint32_t>(expected), decoder.consume_u32v()); \ - EXPECT_EQ(data + expected_length, decoder.pc()); \ +#define CHECK_UINT32V_INLINE(expected, expected_length, ...) \ + do { \ + const byte data[] = {__VA_ARGS__}; \ + decoder.Reset(data, data + sizeof(data)); \ + unsigned length; \ + EXPECT_EQ( \ + static_cast<uint32_t>(expected), \ + decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length)); \ + EXPECT_EQ(static_cast<unsigned>(expected_length), length); \ + EXPECT_EQ(data, decoder.pc()); \ + EXPECT_TRUE(decoder.ok()); \ + EXPECT_EQ(static_cast<uint32_t>(expected), decoder.consume_u32v()); \ + EXPECT_EQ(data + expected_length, decoder.pc()); \ } while (false) -#define CHECK_INT32V_INLINE(expected, expected_length, ...) \ - do { \ - const byte data[] = {__VA_ARGS__}; \ - decoder.Reset(data, data + sizeof(data)); \ - unsigned length; \ - EXPECT_EQ(expected, decoder.read_i32v<true>(decoder.start(), &length)); \ - EXPECT_EQ(static_cast<unsigned>(expected_length), length); \ - EXPECT_EQ(data, decoder.pc()); \ - EXPECT_TRUE(decoder.ok()); \ - EXPECT_EQ(expected, decoder.consume_i32v()); \ - EXPECT_EQ(data + expected_length, decoder.pc()); \ +#define CHECK_INT32V_INLINE(expected, expected_length, ...) \ + do { \ + const byte data[] = {__VA_ARGS__}; \ + decoder.Reset(data, data + sizeof(data)); \ + unsigned length; \ + EXPECT_EQ(expected, decoder.read_i32v<Decoder::kValidate>(decoder.start(), \ + &length)); \ + EXPECT_EQ(static_cast<unsigned>(expected_length), length); \ + EXPECT_EQ(data, decoder.pc()); \ + EXPECT_TRUE(decoder.ok()); \ + EXPECT_EQ(expected, decoder.consume_i32v()); \ + EXPECT_EQ(data + expected_length, decoder.pc()); \ } while (false) -#define CHECK_UINT64V_INLINE(expected, expected_length, ...) \ - do { \ - const byte data[] = {__VA_ARGS__}; \ - decoder.Reset(data, data + sizeof(data)); \ - unsigned length; \ - EXPECT_EQ(static_cast<uint64_t>(expected), \ - decoder.read_u64v<false>(decoder.start(), &length)); \ - EXPECT_EQ(static_cast<unsigned>(expected_length), length); \ +#define CHECK_UINT64V_INLINE(expected, expected_length, ...) \ + do { \ + const byte data[] = {__VA_ARGS__}; \ + decoder.Reset(data, data + sizeof(data)); \ + unsigned length; \ + EXPECT_EQ( \ + static_cast<uint64_t>(expected), \ + decoder.read_u64v<Decoder::kValidate>(decoder.start(), &length)); \ + EXPECT_EQ(static_cast<unsigned>(expected_length), length); \ } while (false) -#define CHECK_INT64V_INLINE(expected, expected_length, ...) \ - do { \ - const byte data[] = {__VA_ARGS__}; \ - decoder.Reset(data, data + sizeof(data)); \ - unsigned length; \ - EXPECT_EQ(expected, decoder.read_i64v<false>(decoder.start(), &length)); \ - EXPECT_EQ(static_cast<unsigned>(expected_length), length); \ +#define CHECK_INT64V_INLINE(expected, expected_length, ...) \ + do { \ + const byte data[] = {__VA_ARGS__}; \ + decoder.Reset(data, data + sizeof(data)); \ + unsigned length; \ + EXPECT_EQ(expected, decoder.read_i64v<Decoder::kValidate>(decoder.start(), \ + &length)); \ + EXPECT_EQ(static_cast<unsigned>(expected_length), length); \ } while (false) TEST_F(DecoderTest, ReadU32v_OneByte) { @@ -374,7 +378,7 @@ TEST_F(DecoderTest, ReadU32v_off_end1) { static const byte data[] = {U32V_1(11)}; unsigned length = 0; decoder.Reset(data, data); - decoder.read_u32v<true>(decoder.start(), &length); + decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length); EXPECT_EQ(0u, length); EXPECT_FALSE(decoder.ok()); } @@ -384,7 +388,7 @@ TEST_F(DecoderTest, ReadU32v_off_end2) { for (size_t i = 0; i < sizeof(data); i++) { unsigned length = 0; decoder.Reset(data, data + i); - decoder.read_u32v<true>(decoder.start(), &length); + decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length); EXPECT_EQ(i, length); EXPECT_FALSE(decoder.ok()); } @@ -395,7 +399,7 @@ TEST_F(DecoderTest, ReadU32v_off_end3) { for (size_t i = 0; i < sizeof(data); i++) { unsigned length = 0; decoder.Reset(data, data + i); - decoder.read_u32v<true>(decoder.start(), &length); + decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length); EXPECT_EQ(i, length); EXPECT_FALSE(decoder.ok()); } @@ -406,7 +410,7 @@ TEST_F(DecoderTest, ReadU32v_off_end4) { for (size_t i = 0; i < sizeof(data); i++) { unsigned length = 0; decoder.Reset(data, data + i); - decoder.read_u32v<true>(decoder.start(), &length); + decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length); EXPECT_EQ(i, length); EXPECT_FALSE(decoder.ok()); } @@ -417,7 +421,7 @@ TEST_F(DecoderTest, ReadU32v_off_end5) { for (size_t i = 0; i < sizeof(data); i++) { unsigned length = 0; decoder.Reset(data, data + i); - decoder.read_u32v<true>(decoder.start(), &length); + decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length); EXPECT_EQ(i, length); EXPECT_FALSE(decoder.ok()); } @@ -429,7 +433,7 @@ TEST_F(DecoderTest, ReadU32v_extra_bits) { data[4] = static_cast<byte>(i << 4); unsigned length = 0; decoder.Reset(data, data + sizeof(data)); - decoder.read_u32v<true>(decoder.start(), &length); + decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length); EXPECT_EQ(5u, length); EXPECT_FALSE(decoder.ok()); } @@ -440,7 +444,7 @@ TEST_F(DecoderTest, ReadI32v_extra_bits_negative) { unsigned length = 0; byte data[] = {0xff, 0xff, 0xff, 0xff, 0x7f}; decoder.Reset(data, data + sizeof(data)); - decoder.read_i32v<true>(decoder.start(), &length); + decoder.read_i32v<Decoder::kValidate>(decoder.start(), &length); EXPECT_EQ(5u, length); EXPECT_TRUE(decoder.ok()); } @@ -450,7 +454,7 @@ TEST_F(DecoderTest, ReadI32v_extra_bits_positive) { unsigned length = 0; byte data[] = {0x80, 0x80, 0x80, 0x80, 0x77}; decoder.Reset(data, data + sizeof(data)); - decoder.read_i32v<true>(decoder.start(), &length); + decoder.read_i32v<Decoder::kValidate>(decoder.start(), &length); EXPECT_EQ(5u, length); EXPECT_FALSE(decoder.ok()); } @@ -485,7 +489,7 @@ TEST_F(DecoderTest, ReadU32v_Bits) { for (unsigned limit = 0; limit <= kMaxSize; limit++) { decoder.Reset(data, data + limit); unsigned rlen; - uint32_t result = decoder.read_u32v<true>(data, &rlen); + uint32_t result = decoder.read_u32v<Decoder::kValidate>(data, &rlen); if (limit < length) { EXPECT_FALSE(decoder.ok()); } else { @@ -541,7 +545,7 @@ TEST_F(DecoderTest, ReadU64v_PowerOf2) { for (unsigned limit = 0; limit <= kMaxSize; limit++) { decoder.Reset(data, data + limit); unsigned length; - uint64_t result = decoder.read_u64v<true>(data, &length); + uint64_t result = decoder.read_u64v<Decoder::kValidate>(data, &length); if (limit <= index) { EXPECT_FALSE(decoder.ok()); } else { @@ -582,7 +586,7 @@ TEST_F(DecoderTest, ReadU64v_Bits) { for (unsigned limit = 0; limit <= kMaxSize; limit++) { decoder.Reset(data, data + limit); unsigned rlen; - uint64_t result = decoder.read_u64v<true>(data, &rlen); + uint64_t result = decoder.read_u64v<Decoder::kValidate>(data, &rlen); if (limit < length) { EXPECT_FALSE(decoder.ok()); } else { @@ -624,7 +628,7 @@ TEST_F(DecoderTest, ReadI64v_Bits) { for (unsigned limit = 0; limit <= kMaxSize; limit++) { decoder.Reset(data, data + limit); unsigned rlen; - int64_t result = decoder.read_i64v<true>(data, &rlen); + int64_t result = decoder.read_i64v<Decoder::kValidate>(data, &rlen); if (limit < length) { EXPECT_FALSE(decoder.ok()); } else { @@ -643,7 +647,7 @@ TEST_F(DecoderTest, ReadU64v_extra_bits) { data[9] = static_cast<byte>(i << 1); unsigned length = 0; decoder.Reset(data, data + sizeof(data)); - decoder.read_u64v<true>(decoder.start(), &length); + decoder.read_u64v<Decoder::kValidate>(decoder.start(), &length); EXPECT_EQ(10u, length); EXPECT_FALSE(decoder.ok()); } @@ -654,7 +658,7 @@ TEST_F(DecoderTest, ReadI64v_extra_bits_negative) { unsigned length = 0; byte data[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}; decoder.Reset(data, data + sizeof(data)); - decoder.read_i64v<true>(decoder.start(), &length); + decoder.read_i64v<Decoder::kValidate>(decoder.start(), &length); EXPECT_EQ(10u, length); EXPECT_TRUE(decoder.ok()); } @@ -664,7 +668,7 @@ TEST_F(DecoderTest, ReadI64v_extra_bits_positive) { unsigned length = 0; byte data[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x77}; decoder.Reset(data, data + sizeof(data)); - decoder.read_i64v<true>(decoder.start(), &length); + decoder.read_i64v<Decoder::kValidate>(decoder.start(), &length); EXPECT_EQ(10u, length); EXPECT_FALSE(decoder.ok()); } diff --git a/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc b/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc index bda1073281..d02dca36be 100644 --- a/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc +++ b/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc @@ -198,12 +198,12 @@ class TestModuleBuilder { } byte AddGlobal(ValueType type, bool mutability = true) { mod.globals.push_back({type, mutability, WasmInitExpr(), 0, false, false}); - CHECK(mod.globals.size() <= kMaxByteSizedLeb128); + CHECK_LE(mod.globals.size(), kMaxByteSizedLeb128); return static_cast<byte>(mod.globals.size() - 1); } byte AddSignature(FunctionSig* sig) { mod.signatures.push_back(sig); - CHECK(mod.signatures.size() <= kMaxByteSizedLeb128); + CHECK_LE(mod.signatures.size(), kMaxByteSizedLeb128); return static_cast<byte>(mod.signatures.size() - 1); } byte AddFunction(FunctionSig* sig) { @@ -214,7 +214,7 @@ class TestModuleBuilder { {0, 0}, // code false, // import false}); // export - CHECK(mod.functions.size() <= kMaxByteSizedLeb128); + CHECK_LE(mod.functions.size(), kMaxByteSizedLeb128); return static_cast<byte>(mod.functions.size() - 1); } byte AddImport(FunctionSig* sig) { @@ -224,7 +224,7 @@ class TestModuleBuilder { } byte AddException(WasmExceptionSig* sig) { mod.exceptions.emplace_back(sig); - CHECK(mod.signatures.size() <= kMaxByteSizedLeb128); + CHECK_LE(mod.signatures.size(), kMaxByteSizedLeb128); return static_cast<byte>(mod.exceptions.size() - 1); } @@ -2387,45 +2387,227 @@ TEST_F(FunctionBodyDecoderTest, TryCatch) { TEST_F(FunctionBodyDecoderTest, MultiValBlock1) { EXPERIMENTAL_FLAG_SCOPE(mv); - EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), - WASM_GET_LOCAL(1)), + TestModuleBuilder builder; + module = builder.module(); + byte f0 = builder.AddSignature(sigs.ii_v()); + EXPECT_VERIFIES(i_ii, WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), kExprI32Add); + EXPECT_FAILURE(i_ii, WASM_BLOCK_X(f0, WASM_NOP), kExprI32Add); + EXPECT_FAILURE(i_ii, WASM_BLOCK_X(f0, WASM_GET_LOCAL(0)), kExprI32Add); + EXPECT_FAILURE(i_ii, WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_GET_LOCAL(0)), + kExprI32Add); + EXPECT_FAILURE(i_ii, WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), + kExprF32Add); } TEST_F(FunctionBodyDecoderTest, MultiValBlock2) { EXPERIMENTAL_FLAG_SCOPE(mv); - EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), - WASM_GET_LOCAL(1)), + TestModuleBuilder builder; + module = builder.module(); + byte f0 = builder.AddSignature(sigs.ii_v()); + EXPECT_VERIFIES(i_ii, WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), WASM_I32_ADD(WASM_NOP, WASM_NOP)); + EXPECT_FAILURE(i_ii, WASM_BLOCK_X(f0, WASM_NOP), + WASM_I32_ADD(WASM_NOP, WASM_NOP)); + EXPECT_FAILURE(i_ii, WASM_BLOCK_X(f0, WASM_GET_LOCAL(0)), + WASM_I32_ADD(WASM_NOP, WASM_NOP)); + EXPECT_FAILURE(i_ii, WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_GET_LOCAL(0)), + WASM_I32_ADD(WASM_NOP, WASM_NOP)); + EXPECT_FAILURE(i_ii, WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), + WASM_F32_ADD(WASM_NOP, WASM_NOP)); +} + +TEST_F(FunctionBodyDecoderTest, MultiValBlockBr) { + EXPERIMENTAL_FLAG_SCOPE(mv); + TestModuleBuilder builder; + module = builder.module(); + byte f0 = builder.AddSignature(sigs.ii_v()); + EXPECT_FAILURE(i_ii, WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_BR(0)), + kExprI32Add); + EXPECT_VERIFIES(i_ii, WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), + WASM_GET_LOCAL(1), WASM_BR(0)), + kExprI32Add); } -TEST_F(FunctionBodyDecoderTest, MultiValBlockBr1) { +TEST_F(FunctionBodyDecoderTest, MultiValLoop1) { EXPERIMENTAL_FLAG_SCOPE(mv); - EXPECT_FAILURE( - i_ii, WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), WASM_BR(0)), - kExprI32Add); - EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), - WASM_GET_LOCAL(1), WASM_BR(0)), + TestModuleBuilder builder; + module = builder.module(); + byte f0 = builder.AddSignature(sigs.ii_v()); + EXPECT_VERIFIES(i_ii, WASM_LOOP_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), kExprI32Add); + EXPECT_FAILURE(i_ii, WASM_LOOP_X(f0, WASM_NOP), kExprI32Add); + EXPECT_FAILURE(i_ii, WASM_LOOP_X(f0, WASM_GET_LOCAL(0)), kExprI32Add); + EXPECT_FAILURE(i_ii, WASM_LOOP_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_GET_LOCAL(0)), + kExprI32Add); + EXPECT_FAILURE(i_ii, WASM_LOOP_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), + kExprF32Add); } -TEST_F(FunctionBodyDecoderTest, MultiValIf1) { +TEST_F(FunctionBodyDecoderTest, MultiValIf) { EXPERIMENTAL_FLAG_SCOPE(mv); + TestModuleBuilder builder; + module = builder.module(); + byte f0 = builder.AddSignature(sigs.ii_v()); + EXPECT_VERIFIES( + i_ii, WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), + WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), + WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))), + kExprI32Add); EXPECT_FAILURE( - i_ii, WASM_IF_ELSE_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), - WASM_SEQ(WASM_GET_LOCAL(0)), - WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))), + i_ii, WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP), kExprI32Add); - EXPECT_FAILURE(i_ii, - WASM_IF_ELSE_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), - WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), - WASM_SEQ(WASM_GET_LOCAL(1))), - kExprI32Add); - EXPECT_VERIFIES( - i_ii, WASM_IF_ELSE_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), - WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), - WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))), + EXPECT_FAILURE( + i_ii, WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), + WASM_NOP, + WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))), + kExprI32Add); + EXPECT_FAILURE( + i_ii, WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), + WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), + WASM_NOP), + kExprI32Add); + EXPECT_FAILURE( + i_ii, WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), + WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), + kExprI32Add); + EXPECT_FAILURE( + i_ii, WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), + WASM_GET_LOCAL(0), + WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))), + kExprI32Add); + EXPECT_FAILURE( + i_ii, WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), + WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), + WASM_GET_LOCAL(1)), + kExprI32Add); + EXPECT_FAILURE( + i_ii, WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), + WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), + WASM_GET_LOCAL(0)), + WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0), + WASM_GET_LOCAL(0))), kExprI32Add); + EXPECT_FAILURE( + i_ii, WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), + WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), + WASM_GET_LOCAL(0)), + WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))), + kExprI32Add); + EXPECT_FAILURE( + i_ii, WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), + WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), + WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(1), + WASM_GET_LOCAL(1))), + kExprI32Add); + EXPECT_FAILURE( + i_ii, WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), + WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), + WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))), + kExprF32Add); +} + +TEST_F(FunctionBodyDecoderTest, BlockParam) { + EXPERIMENTAL_FLAG_SCOPE(mv); + TestModuleBuilder builder; + module = builder.module(); + byte f1 = builder.AddSignature(sigs.i_i()); + byte f2 = builder.AddSignature(sigs.i_ii()); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), + WASM_BLOCK_X(f1, WASM_GET_LOCAL(1), + WASM_I32_ADD(WASM_NOP, WASM_NOP))); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_BLOCK_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP))); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_BLOCK_X(f1, WASM_NOP), + WASM_I32_ADD(WASM_NOP, WASM_NOP)); + EXPECT_FAILURE(i_ii, WASM_BLOCK_X(f1, WASM_NOP), + WASM_RETURN1(WASM_GET_LOCAL(0))); + EXPECT_FAILURE(i_ii, WASM_BLOCK_X(f1, WASM_GET_LOCAL(0)), + WASM_RETURN1(WASM_GET_LOCAL(0))); + EXPECT_FAILURE(i_ii, WASM_GET_LOCAL(0), + WASM_BLOCK_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP)), + WASM_RETURN1(WASM_GET_LOCAL(0))); + EXPECT_FAILURE(i_ii, WASM_GET_LOCAL(0), + WASM_BLOCK_X(f1, WASM_F32_NEG(WASM_NOP)), + WASM_RETURN1(WASM_GET_LOCAL(0))); +} + +TEST_F(FunctionBodyDecoderTest, LoopParam) { + EXPERIMENTAL_FLAG_SCOPE(mv); + TestModuleBuilder builder; + module = builder.module(); + byte f1 = builder.AddSignature(sigs.i_i()); + byte f2 = builder.AddSignature(sigs.i_ii()); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), + WASM_LOOP_X(f1, WASM_GET_LOCAL(1), + WASM_I32_ADD(WASM_NOP, WASM_NOP))); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_LOOP_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP))); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_LOOP_X(f1, WASM_NOP), + WASM_I32_ADD(WASM_NOP, WASM_NOP)); + EXPECT_FAILURE(i_ii, WASM_LOOP_X(f1, WASM_NOP), + WASM_RETURN1(WASM_GET_LOCAL(0))); + EXPECT_FAILURE(i_ii, WASM_LOOP_X(f1, WASM_GET_LOCAL(0)), + WASM_RETURN1(WASM_GET_LOCAL(0))); + EXPECT_FAILURE(i_ii, WASM_GET_LOCAL(0), + WASM_LOOP_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP)), + WASM_RETURN1(WASM_GET_LOCAL(0))); + EXPECT_FAILURE(i_ii, WASM_GET_LOCAL(0), + WASM_LOOP_X(f1, WASM_F32_NEG(WASM_NOP)), + WASM_RETURN1(WASM_GET_LOCAL(0))); +} + +TEST_F(FunctionBodyDecoderTest, LoopParamBr) { + EXPERIMENTAL_FLAG_SCOPE(mv); + TestModuleBuilder builder; + module = builder.module(); + byte f1 = builder.AddSignature(sigs.i_i()); + byte f2 = builder.AddSignature(sigs.i_ii()); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), + WASM_LOOP_X(f1, WASM_BR(0))); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), + WASM_LOOP_X(f1, WASM_BRV(0, WASM_GET_LOCAL(1)))); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_LOOP_X(f2, WASM_BR(0))); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), + WASM_LOOP_X(f1, WASM_BLOCK_X(f1, WASM_BR(1)))); + EXPECT_FAILURE(i_ii, WASM_GET_LOCAL(0), + WASM_LOOP_X(f1, WASM_BLOCK(WASM_BR(1))), + WASM_RETURN1(WASM_GET_LOCAL(0))); + EXPECT_FAILURE(i_ii, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_LOOP_X(f2, WASM_BLOCK_X(f1, WASM_BR(1))), + WASM_RETURN1(WASM_GET_LOCAL(0))); +} + +TEST_F(FunctionBodyDecoderTest, IfParam) { + EXPERIMENTAL_FLAG_SCOPE(mv); + TestModuleBuilder builder; + module = builder.module(); + byte f1 = builder.AddSignature(sigs.i_i()); + byte f2 = builder.AddSignature(sigs.i_ii()); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), + WASM_IF_X(f1, WASM_GET_LOCAL(0), + WASM_I32_ADD(WASM_NOP, WASM_GET_LOCAL(1)))); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), + WASM_IF_ELSE_X(f1, WASM_GET_LOCAL(0), + WASM_I32_ADD(WASM_NOP, WASM_GET_LOCAL(1)), + WASM_I32_EQZ(WASM_NOP))); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_IF_ELSE_X(f2, WASM_GET_LOCAL(0), + WASM_I32_ADD(WASM_NOP, WASM_NOP), + WASM_I32_MUL(WASM_NOP, WASM_NOP))); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_IF_X(f1, WASM_GET_LOCAL(0), WASM_NOP), + WASM_I32_ADD(WASM_NOP, WASM_NOP)); + EXPECT_VERIFIES(i_ii, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_IF_ELSE_X(f1, WASM_GET_LOCAL(0), + WASM_NOP, WASM_I32_EQZ(WASM_NOP)), + WASM_I32_ADD(WASM_NOP, WASM_NOP)); } TEST_F(FunctionBodyDecoderTest, Regression709741) { @@ -2451,15 +2633,15 @@ class BranchTableIteratorTest : public TestWithZone { BranchTableIteratorTest() : TestWithZone() {} void CheckBrTableSize(const byte* start, const byte* end) { Decoder decoder(start, end); - BranchTableOperand<true> operand(&decoder, start); - BranchTableIterator<true> iterator(&decoder, operand); + BranchTableOperand<Decoder::kValidate> operand(&decoder, start); + BranchTableIterator<Decoder::kValidate> iterator(&decoder, operand); EXPECT_EQ(end - start - 1u, iterator.length()); EXPECT_TRUE(decoder.ok()); } void CheckBrTableError(const byte* start, const byte* end) { Decoder decoder(start, end); - BranchTableOperand<true> operand(&decoder, start); - BranchTableIterator<true> iterator(&decoder, operand); + BranchTableOperand<Decoder::kValidate> operand(&decoder, start); + BranchTableIterator<Decoder::kValidate> iterator(&decoder, operand); iterator.length(); EXPECT_FALSE(decoder.ok()); } diff --git a/deps/v8/test/unittests/wasm/leb-helper-unittest.cc b/deps/v8/test/unittests/wasm/leb-helper-unittest.cc index 474d49c1c5..ec9fd3efb3 100644 --- a/deps/v8/test/unittests/wasm/leb-helper-unittest.cc +++ b/deps/v8/test/unittests/wasm/leb-helper-unittest.cc @@ -88,19 +88,19 @@ TEST_F(LEBHelperTest, sizeof_i32v) { } } -#define DECLARE_ENCODE_DECODE_CHECKER(ctype, name) \ - static void CheckEncodeDecode_##name(ctype val) { \ - static const int kSize = 16; \ - static byte buffer[kSize]; \ - byte* ptr = buffer; \ - LEBHelper::write_##name(&ptr, val); \ - EXPECT_EQ(LEBHelper::sizeof_##name(val), \ - static_cast<size_t>(ptr - buffer)); \ - Decoder decoder(buffer, buffer + kSize); \ - unsigned length = 0; \ - ctype result = decoder.read_##name<false>(buffer, &length); \ - EXPECT_EQ(val, result); \ - EXPECT_EQ(LEBHelper::sizeof_##name(val), static_cast<size_t>(length)); \ +#define DECLARE_ENCODE_DECODE_CHECKER(ctype, name) \ + static void CheckEncodeDecode_##name(ctype val) { \ + static const int kSize = 16; \ + static byte buffer[kSize]; \ + byte* ptr = buffer; \ + LEBHelper::write_##name(&ptr, val); \ + EXPECT_EQ(LEBHelper::sizeof_##name(val), \ + static_cast<size_t>(ptr - buffer)); \ + Decoder decoder(buffer, buffer + kSize); \ + unsigned length = 0; \ + ctype result = decoder.read_##name<Decoder::kNoValidate>(buffer, &length); \ + EXPECT_EQ(val, result); \ + EXPECT_EQ(LEBHelper::sizeof_##name(val), static_cast<size_t>(length)); \ } DECLARE_ENCODE_DECODE_CHECKER(int32_t, i32v) diff --git a/deps/v8/test/unittests/wasm/module-decoder-unittest.cc b/deps/v8/test/unittests/wasm/module-decoder-unittest.cc index 2e76d374d3..ae98bd9a70 100644 --- a/deps/v8/test/unittests/wasm/module-decoder-unittest.cc +++ b/deps/v8/test/unittests/wasm/module-decoder-unittest.cc @@ -494,7 +494,7 @@ TEST_F(WasmModuleVerifyTest, DataSegmentWithImmutableImportedGlobal) { 0, // mutability SECTION(Memory, 4), ENTRY_COUNT(1), - kResizableMaximumFlag, + kHasMaximumFlag, 28, 28, SECTION(Data, 9), @@ -527,7 +527,7 @@ TEST_F(WasmModuleVerifyTest, DataSegmentWithMutableImportedGlobal) { 1, // mutability SECTION(Memory, 4), ENTRY_COUNT(1), - kResizableMaximumFlag, + kHasMaximumFlag, 28, 28, SECTION(Data, 9), @@ -546,7 +546,7 @@ TEST_F(WasmModuleVerifyTest, DataSegmentWithImmutableGlobal) { const byte data[] = { SECTION(Memory, 4), ENTRY_COUNT(1), - kResizableMaximumFlag, + kHasMaximumFlag, 28, 28, SECTION(Global, 8), // -- @@ -571,7 +571,7 @@ TEST_F(WasmModuleVerifyTest, OneDataSegment) { const byte data[] = { SECTION(Memory, 4), ENTRY_COUNT(1), - kResizableMaximumFlag, + kHasMaximumFlag, 28, 28, SECTION(Data, 11), @@ -610,7 +610,7 @@ TEST_F(WasmModuleVerifyTest, TwoDataSegments) { const byte data[] = { SECTION(Memory, 4), ENTRY_COUNT(1), - kResizableMaximumFlag, + kHasMaximumFlag, 28, 28, SECTION(Data, 29), @@ -678,15 +678,13 @@ TEST_F(WasmModuleVerifyTest, DataWithoutMemory) { TEST_F(WasmModuleVerifyTest, MaxMaximumMemorySize) { { const byte data[] = { - SECTION(Memory, 6), ENTRY_COUNT(1), kResizableMaximumFlag, 0, - U32V_3(65536), + SECTION(Memory, 6), ENTRY_COUNT(1), kHasMaximumFlag, 0, U32V_3(65536), }; EXPECT_VERIFIES(data); } { const byte data[] = { - SECTION(Memory, 6), ENTRY_COUNT(1), kResizableMaximumFlag, 0, - U32V_3(65537), + SECTION(Memory, 6), ENTRY_COUNT(1), kHasMaximumFlag, 0, U32V_3(65537), }; EXPECT_FAILURE(data); } @@ -696,7 +694,7 @@ TEST_F(WasmModuleVerifyTest, DataSegment_wrong_init_type) { const byte data[] = { SECTION(Memory, 4), ENTRY_COUNT(1), - kResizableMaximumFlag, + kHasMaximumFlag, 28, 28, SECTION(Data, 11), @@ -715,7 +713,7 @@ TEST_F(WasmModuleVerifyTest, DataSegment_wrong_init_type) { TEST_F(WasmModuleVerifyTest, DataSegmentEndOverflow) { const byte data[] = { SECTION(Memory, 4), // memory section - ENTRY_COUNT(1), kResizableMaximumFlag, 28, 28, + ENTRY_COUNT(1), kHasMaximumFlag, 28, 28, SECTION(Data, 10), // data section ENTRY_COUNT(1), // one entry LINEAR_MEMORY_INDEX_0, // mem index @@ -1505,6 +1503,31 @@ TEST_F(WasmModuleVerifyTest, Regression_738097) { EXPECT_FAILURE(data); } +TEST_F(WasmModuleVerifyTest, FunctionBodySizeLimit) { + const uint32_t delta = 3; + for (uint32_t body_size = kV8MaxWasmFunctionSize - delta; + body_size < kV8MaxWasmFunctionSize + delta; body_size++) { + byte data[] = { + SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // -- + FUNCTION_SIGNATURES_SECTION(1, 0), // -- + kCodeSectionCode, // code section + U32V_5(1 + body_size + 5), // section size + 1, // # functions + U32V_5(body_size) // body size + }; + size_t total = sizeof(data) + body_size; + byte* buffer = reinterpret_cast<byte*>(calloc(1, total)); + memcpy(buffer, data, sizeof(data)); + ModuleResult result = DecodeModule(buffer, buffer + total); + if (body_size <= kV8MaxWasmFunctionSize) { + EXPECT_TRUE(result.ok()); + } else { + EXPECT_FALSE(result.ok()); + } + free(buffer); + } +} + TEST_F(WasmModuleVerifyTest, FunctionBodies_empty) { static const byte data[] = { EMPTY_SIGNATURES_SECTION, // -- diff --git a/deps/v8/test/unittests/wasm/streaming-decoder-unittest.cc b/deps/v8/test/unittests/wasm/streaming-decoder-unittest.cc index 2ed28125f0..41211ac960 100644 --- a/deps/v8/test/unittests/wasm/streaming-decoder-unittest.cc +++ b/deps/v8/test/unittests/wasm/streaming-decoder-unittest.cc @@ -461,6 +461,17 @@ TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooHigh) { ExpectFailure(Vector<const uint8_t>(data, arraysize(data))); } +TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooHighZeroFunctions) { + const uint8_t data[] = { + U32_LE(kWasmMagic), // -- + U32_LE(kWasmVersion), // -- + kCodeSectionCode, // Section ID + 0xd, // Section Length + 0x0, // Number of Functions + }; + ExpectFailure(ArrayVector(data)); +} + TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooLow) { const uint8_t data[] = { U32_LE(kWasmMagic), // -- diff --git a/deps/v8/test/unittests/wasm/trap-handler-unittest.cc b/deps/v8/test/unittests/wasm/trap-handler-unittest.cc new file mode 100644 index 0000000000..eb578647ad --- /dev/null +++ b/deps/v8/test/unittests/wasm/trap-handler-unittest.cc @@ -0,0 +1,69 @@ +// Copyright 2017 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/trap-handler/trap-handler.h" +#include "include/v8.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if V8_OS_POSIX +#include <setjmp.h> +#include <signal.h> +#endif + +namespace { + +#if V8_OS_POSIX + +void CrashOnPurpose() { *reinterpret_cast<volatile int*>(42); } + +// When using V8::RegisterDefaultSignalHandler, we save the old one to fall back +// on if V8 doesn't handle the signal. This allows tools like ASan to register a +// handler early on during the process startup and still generate stack traces +// on failures. +class SignalHandlerFallbackTest : public ::testing::Test { + protected: + virtual void SetUp() { + struct sigaction action; + action.sa_sigaction = SignalHandler; + sigemptyset(&action.sa_mask); + action.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &action, &old_segv_action_); + sigaction(SIGBUS, &action, &old_bus_action_); + } + + virtual void TearDown() { + // be a good citizen and restore the old signal handler. + sigaction(SIGSEGV, &old_segv_action_, nullptr); + sigaction(SIGBUS, &old_bus_action_, nullptr); + } + + static sigjmp_buf continuation_; + + private: + static void SignalHandler(int signal, siginfo_t* info, void*) { + siglongjmp(continuation_, 1); + } + struct sigaction old_segv_action_; + struct sigaction old_bus_action_; // We get SIGBUS on Mac sometimes. +}; +sigjmp_buf SignalHandlerFallbackTest::continuation_; + +TEST_F(SignalHandlerFallbackTest, DoTest) { + const int save_sigs = 1; + if (!sigsetjmp(continuation_, save_sigs)) { + v8::V8::RegisterDefaultSignalHandler(); + CrashOnPurpose(); + FAIL(); + } else { + // Our signal handler ran. + v8::internal::trap_handler::RestoreOriginalSignalHandler(); + SUCCEED(); + return; + } + FAIL(); +} + +#endif + +} // namespace diff --git a/deps/v8/test/unittests/wasm/wasm-heap-unittest.cc b/deps/v8/test/unittests/wasm/wasm-heap-unittest.cc index 6e75e84b43..d0c9284f93 100644 --- a/deps/v8/test/unittests/wasm/wasm-heap-unittest.cc +++ b/deps/v8/test/unittests/wasm/wasm-heap-unittest.cc @@ -151,6 +151,241 @@ TEST_F(DisjointAllocationPoolTest, MergingSkipLargerSrcWithGap) { CheckLooksLike(a, {{10, 15}, {20, 35}, {36, 40}}); } +class WasmCodeManagerTest : public TestWithIsolate { + public: + using NativeModulePtr = std::unique_ptr<NativeModule>; + enum ModuleStyle : int { Fixed = 0, Growable = 1 }; + + const std::vector<ModuleStyle> styles() const { + return std::vector<ModuleStyle>({Fixed, Growable}); + } + // We pretend all our modules have 10 functions and no imports, just so + // we can size up the code_table. + NativeModulePtr AllocFixedModule(WasmCodeManager* manager, size_t size) { + return manager->NewNativeModule(size, 10, 0, false); + } + + NativeModulePtr AllocGrowableModule(WasmCodeManager* manager, size_t size) { + return manager->NewNativeModule(size, 10, 0, true); + } + + NativeModulePtr AllocModule(WasmCodeManager* manager, size_t size, + ModuleStyle style) { + switch (style) { + case Fixed: + return AllocFixedModule(manager, size); + case Growable: + return AllocGrowableModule(manager, size); + default: + UNREACHABLE(); + } + } + + WasmCode* AddCode(NativeModule* native_module, uint32_t index, size_t size) { + CodeDesc desc; + memset(reinterpret_cast<void*>(&desc), 0, sizeof(CodeDesc)); + std::unique_ptr<byte[]> exec_buff(new byte[size]); + desc.buffer = exec_buff.get(); + desc.instr_size = static_cast<int>(size); + return native_module->AddCode(desc, 0, index, 0, {}, false); + } + + size_t page() const { return base::OS::AllocatePageSize(); } + v8::Isolate* v8_isolate() const { + return reinterpret_cast<v8::Isolate*>(isolate()); + } +}; + +TEST_F(WasmCodeManagerTest, EmptyCase) { + for (auto style : styles()) { + WasmCodeManager manager(v8_isolate(), 0 * page()); + CHECK_EQ(0, manager.remaining_uncommitted()); + + NativeModulePtr native_module = AllocModule(&manager, 1 * page(), style); + CHECK(native_module); + WasmCode* code = AddCode(native_module.get(), 0, 10); + CHECK_NULL(code); + CHECK_EQ(0, manager.remaining_uncommitted()); + native_module.reset(); + CHECK_EQ(0, manager.remaining_uncommitted()); + } +} + +TEST_F(WasmCodeManagerTest, AllocateAndGoOverLimit) { + for (auto style : styles()) { + WasmCodeManager manager(v8_isolate(), 1 * page()); + CHECK_EQ(1 * page(), manager.remaining_uncommitted()); + NativeModulePtr native_module = AllocModule(&manager, 1 * page(), style); + CHECK(native_module); + CHECK_EQ(1 * page(), manager.remaining_uncommitted()); + uint32_t index = 0; + WasmCode* code = AddCode(native_module.get(), index++, 1 * kCodeAlignment); + CHECK_NOT_NULL(code); + CHECK_EQ(0, manager.remaining_uncommitted()); + + code = AddCode(native_module.get(), index++, 3 * kCodeAlignment); + CHECK_NOT_NULL(code); + CHECK_EQ(0, manager.remaining_uncommitted()); + + code = AddCode(native_module.get(), index++, page() - 4 * kCodeAlignment); + CHECK_NOT_NULL(code); + CHECK_EQ(0, manager.remaining_uncommitted()); + + code = AddCode(native_module.get(), index++, 1 * kCodeAlignment); + CHECK_NULL(code); + CHECK_EQ(0, manager.remaining_uncommitted()); + + native_module.reset(); + CHECK_EQ(1 * page(), manager.remaining_uncommitted()); + } +} + +TEST_F(WasmCodeManagerTest, TotalLimitIrrespectiveOfModuleCount) { + for (auto style : styles()) { + WasmCodeManager manager(v8_isolate(), 1 * page()); + NativeModulePtr nm1 = AllocModule(&manager, 1 * page(), style); + NativeModulePtr nm2 = AllocModule(&manager, 1 * page(), style); + CHECK(nm1); + CHECK(nm2); + WasmCode* code = AddCode(nm1.get(), 0, 1 * page()); + CHECK_NOT_NULL(code); + code = AddCode(nm2.get(), 0, 1 * page()); + CHECK_NULL(code); + } +} + +TEST_F(WasmCodeManagerTest, DifferentHeapsApplyLimitsIndependently) { + for (auto style : styles()) { + WasmCodeManager manager1(v8_isolate(), 1 * page()); + WasmCodeManager manager2(v8_isolate(), 2 * page()); + NativeModulePtr nm1 = AllocModule(&manager1, 1 * page(), style); + NativeModulePtr nm2 = AllocModule(&manager2, 1 * page(), style); + CHECK(nm1); + CHECK(nm2); + WasmCode* code = AddCode(nm1.get(), 0, 1 * page()); + CHECK_NOT_NULL(code); + CHECK_EQ(0, manager1.remaining_uncommitted()); + code = AddCode(nm2.get(), 0, 1 * page()); + CHECK_NOT_NULL(code); + } +} + +TEST_F(WasmCodeManagerTest, GrowingVsFixedModule) { + for (auto style : styles()) { + WasmCodeManager manager(v8_isolate(), 3 * page()); + NativeModulePtr nm = AllocModule(&manager, 1 * page(), style); + WasmCode* code = AddCode(nm.get(), 0, 1 * page() + kCodeAlignment); + if (style == Fixed) { + CHECK_NULL(code); + CHECK_EQ(manager.remaining_uncommitted(), 3 * page()); + } else { + CHECK_NOT_NULL(code); + CHECK_EQ(manager.remaining_uncommitted(), 1 * page()); + } + } +} + +TEST_F(WasmCodeManagerTest, CommitIncrements) { + for (auto style : styles()) { + WasmCodeManager manager(v8_isolate(), 10 * page()); + NativeModulePtr nm = AllocModule(&manager, 3 * page(), style); + WasmCode* code = AddCode(nm.get(), 0, kCodeAlignment); + CHECK_NOT_NULL(code); + CHECK_EQ(manager.remaining_uncommitted(), 9 * page()); + code = AddCode(nm.get(), 1, 2 * page()); + CHECK_NOT_NULL(code); + CHECK_EQ(manager.remaining_uncommitted(), 7 * page()); + code = AddCode(nm.get(), 2, page() - kCodeAlignment); + CHECK_NOT_NULL(code); + CHECK_EQ(manager.remaining_uncommitted(), 7 * page()); + } +} + +TEST_F(WasmCodeManagerTest, Lookup) { + for (auto style : styles()) { + WasmCodeManager manager(v8_isolate(), 2 * page()); + + NativeModulePtr nm1 = AllocModule(&manager, 1 * page(), style); + NativeModulePtr nm2 = AllocModule(&manager, 1 * page(), style); + WasmCode* code1_0 = AddCode(nm1.get(), 0, kCodeAlignment); + CHECK_EQ(nm1.get(), code1_0->owner()); + WasmCode* code1_1 = AddCode(nm1.get(), 1, kCodeAlignment); + WasmCode* code2_0 = AddCode(nm2.get(), 0, kCodeAlignment); + WasmCode* code2_1 = AddCode(nm2.get(), 1, kCodeAlignment); + CHECK_EQ(nm2.get(), code2_1->owner()); + + CHECK_EQ(0, code1_0->index()); + CHECK_EQ(1, code1_1->index()); + CHECK_EQ(0, code2_0->index()); + CHECK_EQ(1, code2_1->index()); + + // we know the manager object is allocated here, so we shouldn't + // find any WasmCode* associated with that ptr. + WasmCode* not_found = + manager.LookupCode(reinterpret_cast<Address>(&manager)); + CHECK_NULL(not_found); + WasmCode* found = manager.LookupCode(code1_0->instructions().start()); + CHECK_EQ(found, code1_0); + found = manager.LookupCode(code2_1->instructions().start() + + (code2_1->instructions().size() / 2)); + CHECK_EQ(found, code2_1); + found = manager.LookupCode(code2_1->instructions().start() + + code2_1->instructions().size() - 1); + CHECK_EQ(found, code2_1); + found = manager.LookupCode(code2_1->instructions().start() + + code2_1->instructions().size()); + CHECK_NULL(found); + Address mid_code1_1 = + code1_1->instructions().start() + (code1_1->instructions().size() / 2); + CHECK_EQ(code1_1, manager.LookupCode(mid_code1_1)); + nm1.reset(); + CHECK_NULL(manager.LookupCode(mid_code1_1)); + } +} + +TEST_F(WasmCodeManagerTest, MultiManagerLookup) { + for (auto style : styles()) { + WasmCodeManager manager1(v8_isolate(), 2 * page()); + WasmCodeManager manager2(v8_isolate(), 2 * page()); + + NativeModulePtr nm1 = AllocModule(&manager1, 1 * page(), style); + NativeModulePtr nm2 = AllocModule(&manager2, 1 * page(), style); + + WasmCode* code1_0 = AddCode(nm1.get(), 0, kCodeAlignment); + CHECK_EQ(nm1.get(), code1_0->owner()); + WasmCode* code1_1 = AddCode(nm1.get(), 1, kCodeAlignment); + WasmCode* code2_0 = AddCode(nm2.get(), 0, kCodeAlignment); + WasmCode* code2_1 = AddCode(nm2.get(), 1, kCodeAlignment); + CHECK_EQ(nm2.get(), code2_1->owner()); + + CHECK_EQ(0, code1_0->index()); + CHECK_EQ(1, code1_1->index()); + CHECK_EQ(0, code2_0->index()); + CHECK_EQ(1, code2_1->index()); + + CHECK_EQ(code1_0, manager1.LookupCode(code1_0->instructions().start())); + CHECK_NULL(manager2.LookupCode(code1_0->instructions().start())); + } +} + +TEST_F(WasmCodeManagerTest, LookupWorksAfterRewrite) { + for (auto style : styles()) { + WasmCodeManager manager(v8_isolate(), 2 * page()); + + NativeModulePtr nm1 = AllocModule(&manager, 1 * page(), style); + + WasmCode* code0 = AddCode(nm1.get(), 0, kCodeAlignment); + WasmCode* code1 = AddCode(nm1.get(), 1, kCodeAlignment); + CHECK_EQ(0, code0->index()); + CHECK_EQ(1, code1->index()); + CHECK_EQ(code1, manager.LookupCode(code1->instructions().start())); + WasmCode* code1_1 = AddCode(nm1.get(), 1, kCodeAlignment); + CHECK_EQ(1, code1_1->index()); + CHECK_EQ(code1, manager.LookupCode(code1->instructions().start())); + CHECK_EQ(code1_1, manager.LookupCode(code1_1->instructions().start())); + } +} + } // namespace wasm_heap_unittest } // namespace wasm } // namespace internal |