| 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
|
|
|