Index: test/cctest/interpreter/test-bytecode-generator.cc |
diff --git a/test/cctest/interpreter/test-bytecode-generator.cc b/test/cctest/interpreter/test-bytecode-generator.cc |
index 5c6cea0167653669d9a8b0f5b569819bc1252ff7..b8ee068f37507cededb3c7426bea41f9c86bfb2b 100644 |
--- a/test/cctest/interpreter/test-bytecode-generator.cc |
+++ b/test/cctest/interpreter/test-bytecode-generator.cc |
@@ -72,9 +72,9 @@ struct ExpectedSnippet { |
int frame_size; |
int parameter_count; |
int bytecode_length; |
- const uint8_t bytecode[32]; |
+ const uint8_t bytecode[512]; |
int constant_count; |
- T constants[16]; |
+ T constants[4]; |
}; |
@@ -95,6 +95,11 @@ static void CheckConstant(const char* expected, Object* actual) { |
} |
+static void CheckConstant(Handle<Object> expected, Object* actual) { |
+ CHECK(actual == *expected || expected->StrictEquals(actual)); |
+} |
+ |
+ |
template <typename T> |
static void CheckBytecodeArrayEqual(struct ExpectedSnippet<T> expected, |
Handle<BytecodeArray> actual, |
@@ -166,8 +171,7 @@ TEST(PrimitiveReturnStatements) { |
{"return -128;", 0, 1, 3, {B(LdaSmi8), U8(-128), B(Return)}, 0}, |
}; |
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
- for (size_t i = 0; i < num_snippets; i++) { |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
Handle<BytecodeArray> bytecode_array = |
helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
@@ -208,8 +212,7 @@ TEST(PrimitiveExpressions) { |
0 |
}}; |
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
- for (size_t i = 0; i < num_snippets; i++) { |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
Handle<BytecodeArray> bytecode_array = |
helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
@@ -234,8 +237,7 @@ TEST(Parameters) { |
0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 7), B(Return)}, 0} |
}; |
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
- for (size_t i = 0; i < num_snippets; i++) { |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
Handle<BytecodeArray> bytecode_array = |
helper.MakeBytecodeForFunction(snippets[i].code_snippet); |
CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
@@ -243,122 +245,145 @@ TEST(Parameters) { |
} |
-TEST(Constants) { |
+TEST(IntegerConstants) { |
InitializedHandleScope handle_scope; |
BytecodeGeneratorHelper helper; |
- // Check large SMIs. |
- { |
- ExpectedSnippet<int> snippets[] = { |
- {"return 12345678;", 0, 1, 3, |
- { |
- B(LdaConstant), U8(0), |
- B(Return) |
- }, 1, { 12345678 } |
- }, |
- {"var a = 1234; return 5678;", 1 * kPointerSize, 1, 7, |
- { |
- B(LdaConstant), U8(0), |
- B(Star), R(0), |
- B(LdaConstant), U8(1), |
- B(Return) |
- }, 2, { 1234, 5678 } |
- }, |
- {"var a = 1234; return 1234;", |
- 1 * kPointerSize, 1, 7, |
- { |
- B(LdaConstant), U8(0), |
- B(Star), R(0), |
- B(LdaConstant), U8(0), |
- B(Return) |
- }, 1, { 1234 } |
- } |
- }; |
+ ExpectedSnippet<int> snippets[] = { |
+ {"return 12345678;", |
+ 0, |
+ 1, |
+ 3, |
+ { |
+ B(LdaConstant), U8(0), // |
+ B(Return) // |
+ }, |
+ 1, |
+ {12345678}}, |
+ {"var a = 1234; return 5678;", |
+ 1 * kPointerSize, |
+ 1, |
+ 7, |
+ { |
+ B(LdaConstant), U8(0), // |
+ B(Star), R(0), // |
+ B(LdaConstant), U8(1), // |
+ B(Return) // |
+ }, |
+ 2, |
+ {1234, 5678}}, |
+ {"var a = 1234; return 1234;", |
+ 1 * kPointerSize, |
+ 1, |
+ 7, |
+ { |
+ B(LdaConstant), U8(0), // |
+ B(Star), R(0), // |
+ B(LdaConstant), U8(0), // |
+ B(Return) // |
+ }, |
+ 1, |
+ {1234}}}; |
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
- for (size_t i = 0; i < num_snippets; i++) { |
- Handle<BytecodeArray> bytecode_array = |
- helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
+ Handle<BytecodeArray> bytecode_array = |
+ helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
- } |
} |
+} |
- // Check heap number double constants |
- { |
- ExpectedSnippet<double> snippets[] = { |
- {"return 1.2;", |
- 0, 1, 3, |
- { |
- B(LdaConstant), U8(0), |
- B(Return) |
- }, 1, { 1.2 } |
- }, |
- {"var a = 1.2; return 2.6;", 1 * kPointerSize, 1, 7, |
- { |
- B(LdaConstant), U8(0), |
- B(Star), R(0), |
- B(LdaConstant), U8(1), |
- B(Return) |
- }, 2, { 1.2, 2.6 } |
- }, |
- {"var a = 3.14; return 3.14;", 1 * kPointerSize, 1, 7, |
- { |
- B(LdaConstant), U8(0), |
- B(Star), R(0), |
- B(LdaConstant), U8(1), |
- B(Return) |
- }, 2, |
- // TODO(rmcilroy): Currently multiple identical double literals end up |
- // being allocated as new HeapNumbers and so require multiple constant |
- // pool entries. De-dup identical values. |
- { 3.14, 3.14 } |
- } |
- }; |
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
- for (size_t i = 0; i < num_snippets; i++) { |
- Handle<BytecodeArray> bytecode_array = |
- helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
- CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
- } |
+TEST(HeapNumberConstants) { |
+ InitializedHandleScope handle_scope; |
+ BytecodeGeneratorHelper helper; |
+ |
+ ExpectedSnippet<double> snippets[] = { |
+ {"return 1.2;", |
+ 0, |
+ 1, |
+ 3, |
+ { |
+ B(LdaConstant), U8(0), // |
+ B(Return) // |
+ }, |
+ 1, |
+ {1.2}}, |
+ {"var a = 1.2; return 2.6;", |
+ 1 * kPointerSize, |
+ 1, |
+ 7, |
+ { |
+ B(LdaConstant), U8(0), // |
+ B(Star), R(0), // |
+ B(LdaConstant), U8(1), // |
+ B(Return) // |
+ }, |
+ 2, |
+ {1.2, 2.6}}, |
+ {"var a = 3.14; return 3.14;", |
+ 1 * kPointerSize, |
+ 1, |
+ 7, |
+ { |
+ B(LdaConstant), U8(0), // |
+ B(Star), R(0), // |
+ B(LdaConstant), U8(1), // |
+ B(Return) // |
+ }, |
+ 2, |
+ {3.14, 3.14}}}; |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
+ Handle<BytecodeArray> bytecode_array = |
+ helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
+ CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
} |
+} |
- // Check string literals |
- { |
- ExpectedSnippet<const char*> snippets[] = { |
- {"return \"This is a string\";", 0, 1, 3, |
- { |
- B(LdaConstant), U8(0), |
- B(Return) |
- }, 1, |
- { "This is a string" } |
- }, |
- {"var a = \"First string\"; return \"Second string\";", |
- 1 * kPointerSize, 1, 7, |
- { |
- B(LdaConstant), U8(0), |
- B(Star), R(0), |
- B(LdaConstant), U8(1), |
- B(Return) |
- }, 2, { "First string", "Second string"} |
- }, |
- {"var a = \"Same string\"; return \"Same string\";", |
- 1 * kPointerSize, 1, 7, |
- { |
- B(LdaConstant), U8(0), |
- B(Star), R(0), |
- B(LdaConstant), U8(0), |
- B(Return) |
- }, 1, { "Same string" } |
- } |
- }; |
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
- for (size_t i = 0; i < num_snippets; i++) { |
- Handle<BytecodeArray> bytecode_array = |
- helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
- CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
- } |
+TEST(StringConstants) { |
+ InitializedHandleScope handle_scope; |
+ BytecodeGeneratorHelper helper; |
+ |
+ ExpectedSnippet<const char*> snippets[] = { |
+ {"return \"This is a string\";", |
+ 0, |
+ 1, |
+ 3, |
+ { |
+ B(LdaConstant), U8(0), // |
+ B(Return) // |
+ }, |
+ 1, |
+ {"This is a string"}}, |
+ {"var a = \"First string\"; return \"Second string\";", |
+ 1 * kPointerSize, |
+ 1, |
+ 7, |
+ { |
+ B(LdaConstant), U8(0), // |
+ B(Star), R(0), // |
+ B(LdaConstant), U8(1), // |
+ B(Return) // |
+ }, |
+ 2, |
+ {"First string", "Second string"}}, |
+ {"var a = \"Same string\"; return \"Same string\";", |
+ 1 * kPointerSize, |
+ 1, |
+ 7, |
+ { |
+ B(LdaConstant), U8(0), // |
+ B(Star), R(0), // |
+ B(LdaConstant), U8(0), // |
+ B(Return) // |
+ }, |
+ 1, |
+ {"Same string"}}}; |
+ |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
+ Handle<BytecodeArray> bytecode_array = |
+ helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
+ CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
} |
} |
@@ -374,67 +399,75 @@ TEST(PropertyLoads) { |
ExpectedSnippet<const char*> snippets[] = { |
{"function f(a) { return a.name; }\nf({name : \"test\"})", |
- 1 * kPointerSize, 2, 10, |
+ 1 * kPointerSize, |
+ 2, |
+ 10, |
{ |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(0), |
- B(LdaConstant), U8(0), |
- B(LoadIC), R(0), U8(vector->first_ic_slot_index()), |
- B(Return) |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(0), // |
+ B(LdaConstant), U8(0), // |
+ B(LoadIC), R(0), U8(vector->first_ic_slot_index()), // |
+ B(Return) // |
}, |
- 1, { "name" } |
- }, |
+ 1, |
+ {"name"}}, |
{"function f(a) { return a[\"key\"]; }\nf({key : \"test\"})", |
- 1 * kPointerSize, 2, 10, |
+ 1 * kPointerSize, |
+ 2, |
+ 10, |
{ |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(0), |
- B(LdaConstant), U8(0), |
- B(LoadIC), R(0), U8(vector->first_ic_slot_index()), |
- B(Return) |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(0), // |
+ B(LdaConstant), U8(0), // |
+ B(LoadIC), R(0), U8(vector->first_ic_slot_index()), // |
+ B(Return) // |
}, |
- 1, { "key" } |
- }, |
+ 1, |
+ {"key"}}, |
{"function f(a) { return a[100]; }\nf({100 : \"test\"})", |
- 1 * kPointerSize, 2, 10, |
+ 1 * kPointerSize, |
+ 2, |
+ 10, |
{ |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(0), |
- B(LdaSmi8), U8(100), |
- B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), |
- B(Return) |
- }, 0 |
- }, |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(0), // |
+ B(LdaSmi8), U8(100), // |
+ B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), // |
+ B(Return) // |
+ }, |
+ 0}, |
{"function f(a, b) { return a[b]; }\nf({arg : \"test\"}, \"arg\")", |
- 1 * kPointerSize, 3, 10, |
+ 1 * kPointerSize, |
+ 3, |
+ 10, |
{ |
- B(Ldar), R(helper.kLastParamIndex - 1), |
- B(Star), R(0), |
- B(Ldar), R(helper.kLastParamIndex), |
- B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), |
- B(Return) |
- }, 0 |
- }, |
+ B(Ldar), R(helper.kLastParamIndex - 1), // |
+ B(Star), R(0), // |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), // |
+ B(Return) // |
+ }, |
+ 0}, |
{"function f(a) { var b = a.name; return a[-124]; }\n" |
"f({\"-124\" : \"test\", name : 123 })", |
- 2 * kPointerSize, 2, 21, |
+ 2 * kPointerSize, |
+ 2, |
+ 21, |
{ |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(1), |
- B(LdaConstant), U8(0), |
- B(LoadIC), R(1), U8(vector->first_ic_slot_index()), |
- B(Star), R(0), |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(1), |
- B(LdaSmi8), U8(-124), |
- B(KeyedLoadIC), R(1), U8(vector->first_ic_slot_index() + 2), |
- B(Return) |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(1), // |
+ B(LdaConstant), U8(0), // |
+ B(LoadIC), R(1), U8(vector->first_ic_slot_index()), // |
+ B(Star), R(0), // |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(1), // |
+ B(LdaSmi8), U8(-124), // |
+ B(KeyedLoadIC), R(1), U8(vector->first_ic_slot_index() + 2), // |
+ B(Return) // |
}, |
- 1, { "name" } |
- } |
- }; |
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
- for (size_t i = 0; i < num_snippets; i++) { |
+ 1, |
+ {"name"}}}; |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
Handle<BytecodeArray> bytecode_array = |
helper.MakeBytecode(snippets[i].code_snippet, "f"); |
CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
@@ -453,82 +486,90 @@ TEST(PropertyStores) { |
ExpectedSnippet<const char*> snippets[] = { |
{"function f(a) { a.name = \"val\"; }\nf({name : \"test\"})", |
- 2 * kPointerSize, 2, 16, |
+ 2 * kPointerSize, |
+ 2, |
+ 16, |
{ |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(0), |
- B(LdaConstant), U8(0), |
- B(Star), R(1), |
- B(LdaConstant), U8(1), |
- B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), |
- B(LdaUndefined), |
- B(Return) |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(0), // |
+ B(LdaConstant), U8(0), // |
+ B(Star), R(1), // |
+ B(LdaConstant), U8(1), // |
+ B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), // |
+ B(LdaUndefined), // |
+ B(Return) // |
}, |
- 2, { "name", "val" } |
- }, |
+ 2, |
+ {"name", "val"}}, |
{"function f(a) { a[\"key\"] = \"val\"; }\nf({key : \"test\"})", |
- 2 * kPointerSize, 2, 16, |
+ 2 * kPointerSize, |
+ 2, |
+ 16, |
{ |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(0), |
- B(LdaConstant), U8(0), |
- B(Star), R(1), |
- B(LdaConstant), U8(1), |
- B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), |
- B(LdaUndefined), |
- B(Return) |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(0), // |
+ B(LdaConstant), U8(0), // |
+ B(Star), R(1), // |
+ B(LdaConstant), U8(1), // |
+ B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), // |
+ B(LdaUndefined), // |
+ B(Return) // |
}, |
- 2, { "key", "val" } |
- }, |
+ 2, |
+ {"key", "val"}}, |
{"function f(a) { a[100] = \"val\"; }\nf({100 : \"test\"})", |
- 2 * kPointerSize, 2, 16, |
+ 2 * kPointerSize, |
+ 2, |
+ 16, |
{ |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(0), |
- B(LdaSmi8), U8(100), |
- B(Star), R(1), |
- B(LdaConstant), U8(0), |
- B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), |
- B(LdaUndefined), |
- B(Return) |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(0), // |
+ B(LdaSmi8), U8(100), // |
+ B(Star), R(1), // |
+ B(LdaConstant), U8(0), // |
+ B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), // |
+ B(LdaUndefined), // |
+ B(Return) // |
}, |
- 1, { "val" } |
- }, |
+ 1, |
+ {"val"}}, |
{"function f(a, b) { a[b] = \"val\"; }\nf({arg : \"test\"}, \"arg\")", |
- 2 * kPointerSize, 3, 16, |
+ 2 * kPointerSize, |
+ 3, |
+ 16, |
{ |
- B(Ldar), R(helper.kLastParamIndex - 1), |
- B(Star), R(0), |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(1), |
- B(LdaConstant), U8(0), |
- B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), |
- B(LdaUndefined), |
- B(Return) |
+ B(Ldar), R(helper.kLastParamIndex - 1), // |
+ B(Star), R(0), // |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(1), // |
+ B(LdaConstant), U8(0), // |
+ B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), // |
+ B(LdaUndefined), // |
+ B(Return) // |
}, |
- 1, { "val" } |
- }, |
+ 1, |
+ {"val"}}, |
{"function f(a) { a.name = a[-124]; }\n" |
"f({\"-124\" : \"test\", name : 123 })", |
- 3 * kPointerSize, 2, 23, |
+ 3 * kPointerSize, |
+ 2, |
+ 23, |
{ |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(0), |
- B(LdaConstant), U8(0), |
- B(Star), R(1), |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(2), |
- B(LdaSmi8), U8(-124), |
- B(KeyedLoadIC), R(2), U8(vector->first_ic_slot_index()), |
- B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index() + 2), |
- B(LdaUndefined), |
- B(Return) |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(0), // |
+ B(LdaConstant), U8(0), // |
+ B(Star), R(1), // |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(2), // |
+ B(LdaSmi8), U8(-124), // |
+ B(KeyedLoadIC), R(2), U8(vector->first_ic_slot_index()), // |
+ B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index() + 2), // |
+ B(LdaUndefined), // |
+ B(Return) // |
}, |
- 1, { "name" } |
- } |
- }; |
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
- for (size_t i = 0; i < num_snippets; i++) { |
+ 1, |
+ {"name"}}}; |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
Handle<BytecodeArray> bytecode_array = |
helper.MakeBytecode(snippets[i].code_snippet, "f"); |
CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
@@ -541,7 +582,7 @@ TEST(PropertyStores) { |
TEST(PropertyCall) { |
InitializedHandleScope handle_scope; |
- BytecodeGeneratorHelper helper; |
+ BytecodeGeneratorHelper helper; // |
Code::Kind ic_kinds[] = { i::Code::LOAD_IC, i::Code::LOAD_IC }; |
FeedbackVectorSpec feedback_spec(0, 2, ic_kinds); |
@@ -550,58 +591,62 @@ TEST(PropertyCall) { |
ExpectedSnippet<const char*> snippets[] = { |
{"function f(a) { return a.func(); }\nf(" FUNC_ARG ")", |
- 2 * kPointerSize, 2, 16, |
+ 2 * kPointerSize, |
+ 2, |
+ 16, |
{ |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(1), |
- B(LdaConstant), U8(0), |
- B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), |
- B(Star), R(0), |
- B(Call), R(0), R(1), U8(0), |
- B(Return) |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(1), // |
+ B(LdaConstant), U8(0), // |
+ B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), // |
+ B(Star), R(0), // |
+ B(Call), R(0), R(1), U8(0), // |
+ B(Return) // |
}, |
- 1, { "func" } |
- }, |
+ 1, |
+ {"func"}}, |
{"function f(a, b, c) { return a.func(b, c); }\nf(" FUNC_ARG ", 1, 2)", |
- 4 * kPointerSize, 4, 24, |
+ 4 * kPointerSize, |
+ 4, |
+ 24, |
{ |
- B(Ldar), R(helper.kLastParamIndex - 2), |
- B(Star), R(1), |
- B(LdaConstant), U8(0), |
- B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), |
- B(Star), R(0), |
- B(Ldar), R(helper.kLastParamIndex - 1), |
- B(Star), R(2), |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(3), |
- B(Call), R(0), R(1), U8(2), |
- B(Return) |
+ B(Ldar), R(helper.kLastParamIndex - 2), // |
+ B(Star), R(1), // |
+ B(LdaConstant), U8(0), // |
+ B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), // |
+ B(Star), R(0), // |
+ B(Ldar), R(helper.kLastParamIndex - 1), // |
+ B(Star), R(2), // |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(3), // |
+ B(Call), R(0), R(1), U8(2), // |
+ B(Return) // |
}, |
- 1, { "func" } |
- }, |
- {"function f(a, b) { return a.func(b + b, b); }\nf(" FUNC_ARG ", 1)", |
- 4 * kPointerSize, 3, 30, |
- { |
- B(Ldar), R(helper.kLastParamIndex - 1), |
- B(Star), R(1), |
- B(LdaConstant), U8(0), |
- B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), |
- B(Star), R(0), |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(2), |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Add), R(2), |
- B(Star), R(2), |
- B(Ldar), R(helper.kLastParamIndex), |
- B(Star), R(3), |
- B(Call), R(0), R(1), U8(2), |
- B(Return) |
+ 1, |
+ {"func"}}, |
+ {"function f(a, b) { return a.func(b + b, b); }\nf(" FUNC_ARG ", 1)", |
+ 4 * kPointerSize, |
+ 3, |
+ 30, |
+ { |
+ B(Ldar), R(helper.kLastParamIndex - 1), // |
+ B(Star), R(1), // |
+ B(LdaConstant), U8(0), // |
+ B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), // |
+ B(Star), R(0), // |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(2), // |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Add), R(2), // |
+ B(Star), R(2), // |
+ B(Ldar), R(helper.kLastParamIndex), // |
+ B(Star), R(3), // |
+ B(Call), R(0), R(1), U8(2), // |
+ B(Return) // |
}, |
- 1, { "func" } |
- } |
- }; |
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
- for (size_t i = 0; i < num_snippets; i++) { |
+ 1, |
+ {"func"}}}; |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
Handle<BytecodeArray> bytecode_array = |
helper.MakeBytecode(snippets[i].code_snippet, "f"); |
CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
@@ -630,8 +675,7 @@ TEST(LoadGlobal) { |
}, |
}; |
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
- for (size_t i = 0; i < num_snippets; i++) { |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
Handle<BytecodeArray> bytecode_array = |
helper.MakeBytecode(snippets[i].code_snippet, "f"); |
bytecode_array->Print(); |
@@ -675,14 +719,162 @@ TEST(CallGlobal) { |
}, |
}; |
- size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
- for (size_t i = 0; i < num_snippets; i++) { |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
Handle<BytecodeArray> bytecode_array = |
helper.MakeBytecode(snippets[i].code_snippet, "f"); |
CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); |
} |
} |
+ |
+TEST(IfConditions) { |
+ InitializedHandleScope handle_scope; |
+ BytecodeGeneratorHelper helper; |
+ |
+ Handle<Object> unused = helper.factory()->undefined_value(); |
+ |
+ ExpectedSnippet<Handle<Object>> snippets[] = { |
+ {"function f() { if (0) { return 1; } else { return -1; } }", |
+ 0, |
+ 1, |
+ 14, |
+ {B(LdaZero), // |
+ B(ToBoolean), // |
+ B(JumpIfFalse), U8(7), // |
+ B(LdaSmi8), U8(1), // |
+ B(Return), // |
+ B(Jump), U8(5), // TODO(oth): Unreachable jump after return |
+ B(LdaSmi8), U8(-1), // |
+ B(Return), // |
+ B(LdaUndefined), // |
+ B(Return)}, // |
+ 0, |
+ {unused, unused, unused, unused}}, |
+ {"function f() { if ('lucky') { return 1; } else { return -1; } }", |
+ 0, |
+ 1, |
+ 15, |
+ {B(LdaConstant), U8(0), // |
+ B(ToBoolean), // |
+ B(JumpIfFalse), U8(7), // |
+ B(LdaSmi8), U8(1), // |
+ B(Return), // |
+ B(Jump), U8(5), // TODO(oth): Unreachable jump after return |
+ B(LdaSmi8), U8(-1), // |
+ B(Return), // |
+ B(LdaUndefined), // |
+ B(Return)}, // |
+ 1, |
+ {helper.factory()->NewStringFromStaticChars("lucky"), unused, |
+ unused, unused}}, |
+ {"function f() { if (false) { return 1; } else { return -1; } }", |
+ 0, |
+ 1, |
+ 13, |
+ {B(LdaFalse), // |
+ B(JumpIfFalse), U8(7), // |
+ B(LdaSmi8), U8(1), // |
+ B(Return), // |
+ B(Jump), U8(5), // TODO(oth): Unreachable jump after return |
+ B(LdaSmi8), U8(-1), // |
+ B(Return), // |
+ B(LdaUndefined), // |
+ B(Return)}, // |
+ 0, |
+ {unused, unused, unused, unused}}, |
+ {"function f(a) { if (a <= 0) { return 200; } else { return -200; } }", |
+ kPointerSize, |
+ 2, |
+ 19, |
+ {B(Ldar), R(-5), // |
+ B(Star), R(0), // |
+ B(LdaZero), // |
+ B(TestLessThanEqual), R(0), // |
+ B(JumpIfFalse), U8(7), // |
+ B(LdaConstant), U8(0), // |
+ B(Return), // |
+ B(Jump), U8(5), // TODO(oth): Unreachable jump after return |
+ B(LdaConstant), U8(1), // |
+ B(Return), // |
+ B(LdaUndefined), // |
+ B(Return)}, // |
+ 2, |
+ {helper.factory()->NewNumberFromInt(200), |
+ helper.factory()->NewNumberFromInt(-200), unused, unused}}, |
+ {"function f(a, b) { if (a in b) { return 200; } }", |
+ kPointerSize, |
+ 3, |
+ 17, |
+ {B(Ldar), R(-6), // |
+ B(Star), R(0), // |
+ B(Ldar), R(-5), // |
+ B(TestIn), R(0), // |
+ B(JumpIfFalse), U8(7), // |
+ B(LdaConstant), U8(0), // |
+ B(Return), // |
+ B(Jump), U8(2), // TODO(oth): Unreachable jump after return |
+ B(LdaUndefined), // |
+ B(Return)}, // |
+ 1, |
+ {helper.factory()->NewNumberFromInt(200), unused, unused, unused}}, |
+ {"function f(a, b) { if (a instanceof b) { return 200; } }", |
+ kPointerSize, |
+ 3, |
+ 17, |
+ {B(Ldar), R(-6), // |
+ B(Star), R(0), // |
+ B(Ldar), R(-5), // |
+ B(TestInstanceOf), R(0), // |
+ B(JumpIfFalse), U8(7), // |
+ B(LdaConstant), U8(0), // |
+ B(Return), // |
+ B(Jump), U8(2), // TODO(oth): Unreachable jump after return |
+ B(LdaUndefined), // |
+ B(Return)}, // |
+ 1, |
+ {helper.factory()->NewNumberFromInt(200), unused, unused, unused}}, |
+ {"function f(z) { var a = 0; var b = 0; if (a === 0.01) { " |
+#define X "b = a; a = b; " |
+ X X X X X X X X X X X X X X X X X X X X X X X X |
+#undef X |
+ " return 200; } else { return -200; } }", |
+ 3 * kPointerSize, |
+ 2, |
+ 218, |
+ {B(LdaZero), // |
+ B(Star), R(0), // |
+ B(LdaZero), // |
+ B(Star), R(1), // |
+ B(Ldar), R(0), // |
+ B(Star), R(2), // |
+ B(LdaConstant), U8(0), // |
+ B(TestEqualStrict), R(2), // |
+ B(JumpIfFalseConstant), U8(2), // |
+#define X B(Ldar), R(0), B(Star), R(1), B(Ldar), R(1), B(Star), R(0), |
+ X X X X X X X X X X X X X X X X X X X X X X X X |
+#undef X |
+ B(LdaConstant), |
+ U8(1), // |
+ B(Return), // |
+ B(Jump), U8(5), // TODO(oth): Unreachable jump after return |
+ B(LdaConstant), U8(3), // |
+ B(Return), // |
+ B(LdaUndefined), // |
+ B(Return)}, // |
+ 4, |
+ {helper.factory()->NewHeapNumber(0.01), |
+ helper.factory()->NewNumberFromInt(200), |
+ helper.factory()->NewNumberFromInt(199), |
+ helper.factory()->NewNumberFromInt(-200)}}}; |
+ |
+ for (size_t i = 0; i < arraysize(snippets); i++) { |
+ Handle<BytecodeArray> bytecode_array = |
+ helper.MakeBytecodeForFunction(snippets[i].code_snippet); |
+ CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
+ } |
+} |
+ |
+ |
} // namespace interpreter |
} // namespace internal |
} // namespance v8 |