Chromium Code Reviews| Index: runtime/vm/flow_graph_builder_test.cc |
| diff --git a/runtime/vm/flow_graph_builder_test.cc b/runtime/vm/flow_graph_builder_test.cc |
| index 14ae5968da0bcb3c4b2285b1b063b210561d3893..c568f49d9969aa9b60a330ce0f82ab4d32ed7336 100644 |
| --- a/runtime/vm/flow_graph_builder_test.cc |
| +++ b/runtime/vm/flow_graph_builder_test.cc |
| @@ -17,6 +17,7 @@ namespace dart { |
| THR_Print(">>> BEGIN source position table for `%s`\n", graph_name_); \ |
| Dump(); \ |
| THR_Print("<<< END source position table for `%s`\n", graph_name_); \ |
| + OS::Abort(); \ |
| } |
| class SourcePositionTest : public ValueObject { |
| @@ -77,18 +78,42 @@ class SourcePositionTest : public ValueObject { |
| Token::Kind kind = Token::kNumTokens) { |
| ZoneGrowableArray<Instruction*>* instructions = |
| FindInstructionsAt(line, column); |
| - DUMP_EXPECT(instructions->length() > 0); |
| + intptr_t count = 0; |
| for (intptr_t i = 0; i < instructions->length(); i++) { |
| Instruction* instr = instructions->At(i); |
| EXPECT(instr != NULL); |
| if (instr->IsInstanceCall()) { |
| if (kind != Token::kNumTokens) { |
| - DUMP_EXPECT(instr->AsInstanceCall()->token_kind() == kind); |
| + if (instr->AsInstanceCall()->token_kind() == kind) { |
| + count++; |
| + } |
| + } else { |
| + count++; |
| } |
| - return; |
| } |
| } |
| - DUMP_EXPECT(false); |
| + DUMP_EXPECT(count > 0); |
| + } |
| + |
| + // Expect to find at least one ctatic call at |line| and |column|. The |
|
rmacnak
2016/01/11 22:03:22
ctatic -> static
Cutch
2016/01/11 22:14:58
Done.
|
| + // static call will have |needle| in its |ToCString| representation. |
| + void StaticCallAt(const char* needle, |
| + intptr_t line, |
| + intptr_t column = -1) { |
| + ZoneGrowableArray<Instruction*>* instructions = |
| + FindInstructionsAt(line, column); |
| + intptr_t count = 0; |
| + for (intptr_t i = 0; i < instructions->length(); i++) { |
| + Instruction* instr = instructions->At(i); |
| + EXPECT(instr != NULL); |
| + if (instr->IsStaticCall()) { |
| + const char* haystack = instr->ToCString(); |
| + if (strstr(haystack, needle) != NULL) { |
| + count++; |
| + } |
| + } |
| + } |
| + DUMP_EXPECT(count > 0); |
| } |
| // Expect that at least one of the instructions found at |line| and |column| |
| @@ -98,7 +123,6 @@ class SourcePositionTest : public ValueObject { |
| intptr_t column = -1) { |
| ZoneGrowableArray<Instruction*>* instructions = |
| FindInstructionsAt(line, column); |
| - DUMP_EXPECT(instructions->length() > 0); |
| intptr_t count = 0; |
| for (intptr_t i = 0; i < instructions->length(); i++) { |
| Instruction* instr = instructions->At(i); |
| @@ -115,30 +139,34 @@ class SourcePositionTest : public ValueObject { |
| for (intptr_t i = 0; i < blocks_->length(); i++) { |
| BlockEntryInstr* entry = (*blocks_)[i]; |
| THR_Print("B%" Pd ":\n", entry->block_id()); |
| + DumpInstruction(entry); |
| for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| - Instruction* instr = it.Current(); |
| - const intptr_t token_pos = instr->token_pos(); |
| - if (token_pos < 0) { |
| - const char* token_pos_string = |
| - ClassifyingTokenPositions::ToCString(token_pos); |
| - THR_Print("%12s -- %s\n", token_pos_string, instr->ToCString()); |
| - continue; |
| - } |
| - intptr_t token_line = -1; |
| - intptr_t token_column = -1; |
| - root_script_.GetTokenLocation(token_pos, |
| - &token_line, |
| - &token_column, |
| - NULL); |
| - THR_Print(" %02d:%02d -- %s\n", |
| - static_cast<int>(token_line), |
| - static_cast<int>(token_column), |
| - instr->ToCString()); |
| + DumpInstruction(it.Current()); |
| } |
| } |
| } |
| private: |
| + void DumpInstruction(Instruction* instr) { |
| + const intptr_t token_pos = instr->token_pos(); |
| + if (token_pos < 0) { |
| + const char* token_pos_string = |
| + ClassifyingTokenPositions::ToCString(token_pos); |
| + THR_Print("%12s -- %s\n", token_pos_string, instr->ToCString()); |
| + return; |
| + } |
| + intptr_t token_line = -1; |
| + intptr_t token_column = -1; |
| + root_script_.GetTokenLocation(token_pos, |
| + &token_line, |
| + &token_column, |
| + NULL); |
| + THR_Print(" %02d:%02d -- %s\n", |
| + static_cast<int>(token_line), |
| + static_cast<int>(token_column), |
| + instr->ToCString()); |
| + } |
| + |
| Instruction* FindFirstInstructionAt(intptr_t line, intptr_t column) { |
| ZoneGrowableArray<Instruction*>* instructions = |
| FindInstructionsAt(line, column); |
| @@ -344,4 +372,168 @@ TEST_CASE(SourcePosition_While) { |
| spt.FuzzyInstructionMatchAt("Return", 10, 3); |
| } |
| + |
| +TEST_CASE(SourcePosition_WhileContinueBreak) { |
| + const char* kScript = |
| + "var x = 0;\n" |
| + "var y = 5;\n" |
| + "main() {\n" |
| + " while (x < 10) {\n" |
| + " if (y == 5) {\n" |
| + " continue;\n" |
| + " }\n" |
| + " break;\n" |
| + " }\n" |
| + " return x;\n" |
| + "}\n"; |
| + |
| + SourcePositionTest spt(thread, kScript); |
| + spt.BuildGraphFor("main"); |
| + spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); |
| + spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); |
| + |
| + spt.FuzzyInstructionMatchAt("CheckStackOverflow", 4, 3); |
| + spt.FuzzyInstructionMatchAt("Constant", 4, 10); |
|
rmacnak
2016/01/11 22:03:22
This is the position of "x", should be that of "10
Cutch
2016/01/11 22:14:58
Done.
|
| + spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 10); |
| + spt.InstanceCallAt(4, 12, Token::kLT); |
| + spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 12); |
| + |
| + spt.FuzzyInstructionMatchAt("Constant", 5, 9); |
|
rmacnak
2016/01/11 22:03:22
This is the position of "y", should be that of "5"
Cutch
2016/01/11 22:14:58
Done.
|
| + spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 9); |
| + spt.InstanceCallAt(5, 11, Token::kEQ); |
| + spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 5, 11); |
| + |
| + spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10); |
| + spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3); |
| + spt.FuzzyInstructionMatchAt("Return", 10, 3); |
| +} |
| + |
| + |
| +TEST_CASE(SourcePosition_LoadIndexed) { |
| + const char* kScript = |
| + "var x = 0;\n" |
| + "var z = new List(3);\n" |
| + "main() {\n" |
| + " z[0];\n" |
| + " var y = z[0] + z[1] + z[2];\n" |
| + "}\n"; |
| + |
| + SourcePositionTest spt(thread, kScript); |
| + spt.BuildGraphFor("main"); |
| + |
| + spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); |
| + spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); |
| + spt.StaticCallAt("get:z", 4, 3); |
| + spt.FuzzyInstructionMatchAt("Constant(#0)", 4, 5); |
| + spt.InstanceCallAt(4, 4, Token::kINDEX); |
| + |
| + spt.FuzzyInstructionMatchAt("Constant(#0)", 5, 13); |
| + spt.InstanceCallAt(5, 12, Token::kINDEX); |
| + spt.FuzzyInstructionMatchAt("Constant(#1)", 5, 20); |
| + spt.InstanceCallAt(5, 19, Token::kINDEX); |
| + |
| + spt.InstanceCallAt(5, 16, Token::kADD); |
| + |
| + spt.StaticCallAt("get:z", 5, 25); |
| + spt.FuzzyInstructionMatchAt("Constant(#2)", 5, 27); |
| + spt.InstanceCallAt(5, 26, Token::kINDEX); |
| + |
| + spt.InstanceCallAt(5, 23, Token::kADD); |
| + |
| + spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1); |
| + spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1); |
| + spt.FuzzyInstructionMatchAt("Return", 6, 1); |
| +} |
| + |
| + |
| +TEST_CASE(SourcePosition_StoreIndexed) { |
| + const char* kScript = |
| + "var x = 0;\n" |
| + "var z = new List(4);\n" |
| + "main() {\n" |
| + " z[0];\n" |
| + " z[3] = z[0] + z[1] + z[2];\n" |
| + "}\n"; |
| + |
| + SourcePositionTest spt(thread, kScript); |
| + spt.BuildGraphFor("main"); |
| + |
| + spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); |
| + spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); |
| + spt.StaticCallAt("get:z", 4, 3); |
| + spt.FuzzyInstructionMatchAt("Constant(#0)", 4, 5); |
| + spt.InstanceCallAt(4, 4, Token::kINDEX); |
| + |
| + spt.FuzzyInstructionMatchAt("Constant(#3)", 5, 5); |
| + |
| + spt.StaticCallAt("get:z", 5, 10); |
| + spt.FuzzyInstructionMatchAt("Constant(#0)", 5, 12); |
| + spt.InstanceCallAt(5, 11, Token::kINDEX); |
| + |
| + spt.InstanceCallAt(5, 15, Token::kADD); |
| + |
| + spt.StaticCallAt("get:z", 5, 17); |
| + spt.FuzzyInstructionMatchAt("Constant(#1)", 5, 19); |
| + spt.InstanceCallAt(5, 18, Token::kINDEX); |
| + |
| + spt.StaticCallAt("get:z", 5, 24); |
| + spt.FuzzyInstructionMatchAt("Constant(#2)", 5, 26); |
| + spt.InstanceCallAt(5, 25, Token::kINDEX); |
| + |
| + spt.InstanceCallAt(5, 4, Token::kASSIGN_INDEX); |
| + |
| + spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1); |
| + spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1); |
| + spt.FuzzyInstructionMatchAt("Return", 6, 1); |
| +} |
| + |
| + |
| +TEST_CASE(SourcePosition_BitwiseOperations) { |
| + const char* kScript = |
| + "var x = 0;\n" |
| + "var y = 1;\n" |
| + "main() {\n" |
| + " var z;\n" |
| + " z = x & y;\n" |
| + " z = x | y;\n" |
| + " z = x ^ y;\n" |
| + " z = ~z;\n" |
| + " return z;\n" |
| + "}\n"; |
| + |
| + SourcePositionTest spt(thread, kScript); |
| + spt.BuildGraphFor("main"); |
| + |
| + spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); |
| + spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); |
| + |
| + spt.FuzzyInstructionMatchAt("DebugStepCheck", 4, 7); |
| + spt.FuzzyInstructionMatchAt("Constant(#null", 4, 7); |
| + spt.FuzzyInstructionMatchAt("StoreLocal(z", 4, 7); |
| + |
| + spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 7); |
| + spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 11); |
| + spt.InstanceCallAt(5, 9, Token::kBIT_AND); |
| + spt.FuzzyInstructionMatchAt("StoreLocal(z", 5, 3); |
| + |
| + spt.FuzzyInstructionMatchAt("LoadStaticField", 6, 7); |
| + spt.FuzzyInstructionMatchAt("LoadStaticField", 6, 11); |
| + spt.InstanceCallAt(6, 9, Token::kBIT_OR); |
| + spt.FuzzyInstructionMatchAt("StoreLocal(z", 6, 3); |
| + |
| + spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 7); |
| + spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 11); |
| + spt.InstanceCallAt(7, 9, Token::kBIT_XOR); |
| + spt.FuzzyInstructionMatchAt("StoreLocal(z", 7, 3); |
| + |
| + spt.FuzzyInstructionMatchAt("LoadLocal(z", 8, 8); |
| + spt.InstanceCallAt(8, 7, Token::kBIT_NOT); |
| + spt.FuzzyInstructionMatchAt("StoreLocal(z", 8, 3); |
| + |
| + spt.FuzzyInstructionMatchAt("LoadLocal(z", 9, 10); |
| + spt.FuzzyInstructionMatchAt("DebugStepCheck", 9, 3); |
| + spt.FuzzyInstructionMatchAt("Return", 9, 3); |
| +} |
| + |
| } // namespace dart |
| + |