summaryrefslogtreecommitdiff
path: root/deps/v8/test/unittests/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/unittests/wasm')
-rw-r--r--deps/v8/test/unittests/wasm/decoder-unittest.cc110
-rw-r--r--deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc244
-rw-r--r--deps/v8/test/unittests/wasm/leb-helper-unittest.cc26
-rw-r--r--deps/v8/test/unittests/wasm/module-decoder-unittest.cc45
-rw-r--r--deps/v8/test/unittests/wasm/streaming-decoder-unittest.cc11
-rw-r--r--deps/v8/test/unittests/wasm/trap-handler-unittest.cc69
-rw-r--r--deps/v8/test/unittests/wasm/wasm-heap-unittest.cc235
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