Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/compiler.h" | 5 #include "vm/compiler.h" |
| 6 #include "vm/dart_api_impl.h" | 6 #include "vm/dart_api_impl.h" |
| 7 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/unit_test.h" | 10 #include "vm/unit_test.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 blocks_ = graph_->CodegenBlockOrder(optimized); | 68 blocks_ = graph_->CodegenBlockOrder(optimized); |
| 69 EXPECT(blocks_ != NULL); | 69 EXPECT(blocks_ != NULL); |
| 70 graph_name_ = function_name; | 70 graph_name_ = function_name; |
| 71 EXPECT(graph_name_ != NULL); | 71 EXPECT(graph_name_ != NULL); |
| 72 } | 72 } |
| 73 | 73 |
| 74 // Expect to find an instance call at |line| and |column|. | 74 // Expect to find an instance call at |line| and |column|. |
| 75 void InstanceCallAt(intptr_t line, | 75 void InstanceCallAt(intptr_t line, |
| 76 intptr_t column = -1, | 76 intptr_t column = -1, |
| 77 Token::Kind kind = Token::kNumTokens) { | 77 Token::Kind kind = Token::kNumTokens) { |
| 78 Instruction* instr = FindFirstInstructionAt(line, column); | 78 ZoneGrowableArray<Instruction*>* instructions = |
| 79 DUMP_EXPECT(instr->IsInstanceCall()); | 79 FindInstructionsAt(line, column); |
| 80 if (kind != Token::kNumTokens) { | 80 DUMP_EXPECT(instructions->length() > 0); |
| 81 DUMP_EXPECT(instr->AsInstanceCall()->token_kind() == kind); | 81 for (intptr_t i = 0; i < instructions->length(); i++) { |
| 82 Instruction* instr = instructions->At(i); | |
| 83 EXPECT(instr != NULL); | |
| 84 if (instr->IsInstanceCall()) { | |
| 85 if (kind != Token::kNumTokens) { | |
| 86 DUMP_EXPECT(instr->AsInstanceCall()->token_kind() == kind); | |
| 87 } | |
| 88 return; | |
| 89 } | |
| 82 } | 90 } |
| 91 DUMP_EXPECT(false); | |
| 83 } | 92 } |
| 84 | 93 |
| 85 // Expect that at least one of the instructions found at |line| and |column| | 94 // Expect that at least one of the instructions found at |line| and |column| |
| 86 // contain |needle| in their |ToCString| representation. | 95 // contain |needle| in their |ToCString| representation. |
| 87 void FuzzyInstructionMatchAt(const char* needle, | 96 void FuzzyInstructionMatchAt(const char* needle, |
| 88 intptr_t line, | 97 intptr_t line, |
| 89 intptr_t column = -1) { | 98 intptr_t column = -1) { |
| 90 ZoneGrowableArray<Instruction*>* instructions = | 99 ZoneGrowableArray<Instruction*>* instructions = |
| 91 FindInstructionsAt(line, column); | 100 FindInstructionsAt(line, column); |
| 92 DUMP_EXPECT(instructions->length() > 0); | 101 DUMP_EXPECT(instructions->length() > 0); |
| 93 intptr_t count = 0; | 102 intptr_t count = 0; |
| 94 for (intptr_t i = 0; i < instructions->length(); i++) { | 103 for (intptr_t i = 0; i < instructions->length(); i++) { |
| 95 Instruction* instr = instructions->At(i); | 104 Instruction* instr = instructions->At(i); |
| 96 const char* haystack = instr->ToCString(); | 105 const char* haystack = instr->ToCString(); |
| 97 if (strstr(haystack, needle) != NULL) { | 106 if (strstr(haystack, needle) != NULL) { |
| 98 count++; | 107 count++; |
| 99 } | 108 } |
| 100 } | 109 } |
| 101 DUMP_EXPECT(count > 0); | 110 DUMP_EXPECT(count > 0); |
| 102 } | 111 } |
| 103 | 112 |
| 104 // Utility to dump the instructions with token positions or line numbers. | 113 // Utility to dump the instructions with token positions or line numbers. |
| 105 void Dump() { | 114 void Dump() { |
| 106 for (intptr_t i = 0; i < blocks_->length(); i++) { | 115 for (intptr_t i = 0; i < blocks_->length(); i++) { |
| 107 BlockEntryInstr* entry = (*blocks_)[i]; | 116 BlockEntryInstr* entry = (*blocks_)[i]; |
| 117 THR_Print("B%" Pd ":\n", entry->block_id()); | |
| 108 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 118 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 109 Instruction* instr = it.Current(); | 119 Instruction* instr = it.Current(); |
| 110 const intptr_t token_pos = instr->token_pos(); | 120 const intptr_t token_pos = instr->token_pos(); |
| 111 if (token_pos < 0) { | 121 if (token_pos < 0) { |
| 112 THR_Print("%5d -- %s\n", | 122 const char* token_pos_string = |
| 113 static_cast<int>(token_pos), instr->ToCString()); | 123 ClassifyingTokenPositions::ToCString(token_pos); |
| 124 THR_Print("%12s -- %s\n", token_pos_string, instr->ToCString()); | |
| 114 continue; | 125 continue; |
| 115 } | 126 } |
| 116 intptr_t token_line = -1; | 127 intptr_t token_line = -1; |
| 117 intptr_t token_column = -1; | 128 intptr_t token_column = -1; |
| 118 root_script_.GetTokenLocation(token_pos, | 129 root_script_.GetTokenLocation(token_pos, |
| 119 &token_line, | 130 &token_line, |
| 120 &token_column, | 131 &token_column, |
| 121 NULL); | 132 NULL); |
| 122 THR_Print("%02d:%02d -- %s\n", | 133 THR_Print(" %02d:%02d -- %s\n", |
| 123 static_cast<int>(token_line), | 134 static_cast<int>(token_line), |
| 124 static_cast<int>(token_column), | 135 static_cast<int>(token_column), |
| 125 instr->ToCString()); | 136 instr->ToCString()); |
| 126 } | 137 } |
| 127 } | 138 } |
| 128 } | 139 } |
| 129 | 140 |
| 130 private: | 141 private: |
| 131 Instruction* FindFirstInstructionAt(intptr_t line, intptr_t column) { | 142 Instruction* FindFirstInstructionAt(intptr_t line, intptr_t column) { |
| 132 ZoneGrowableArray<Instruction*>* instructions = | 143 ZoneGrowableArray<Instruction*>* instructions = |
| 133 FindInstructionsAt(line, column); | 144 FindInstructionsAt(line, column); |
| 134 DUMP_EXPECT(instructions->length() > 0); | 145 if (instructions->length() == 0) { |
| 146 return NULL; | |
| 147 } | |
| 135 return instructions->At(0); | 148 return instructions->At(0); |
| 136 } | 149 } |
| 137 | 150 |
| 138 ZoneGrowableArray<Instruction*>* FindInstructionsAt( | 151 ZoneGrowableArray<Instruction*>* FindInstructionsAt( |
| 139 intptr_t line, intptr_t column) { | 152 intptr_t line, intptr_t column) { |
| 140 ZoneGrowableArray<Instruction*>* instructions = | 153 ZoneGrowableArray<Instruction*>* instructions = |
| 141 new ZoneGrowableArray<Instruction*>(); | 154 new ZoneGrowableArray<Instruction*>(); |
| 142 for (intptr_t i = 0; i < blocks_->length(); i++) { | 155 for (intptr_t i = 0; i < blocks_->length(); i++) { |
| 143 BlockEntryInstr* entry = (*blocks_)[i]; | 156 BlockEntryInstr* entry = (*blocks_)[i]; |
| 144 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 157 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 221 | 234 |
| 222 SourcePositionTest spt(thread, kScript); | 235 SourcePositionTest spt(thread, kScript); |
| 223 spt.BuildGraphFor("main"); | 236 spt.BuildGraphFor("main"); |
| 224 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); | 237 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); |
| 225 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); | 238 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); |
| 226 spt.InstanceCallAt(4, 13, Token::kADD); | 239 spt.InstanceCallAt(4, 13, Token::kADD); |
| 227 spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 3); | 240 spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 3); |
| 228 spt.FuzzyInstructionMatchAt("Return", 5, 3); | 241 spt.FuzzyInstructionMatchAt("Return", 5, 3); |
| 229 } | 242 } |
| 230 | 243 |
| 244 | |
| 245 TEST_CASE(SourcePosition_If) { | |
| 246 const char* kScript = | |
| 247 "var x = 5;\n" | |
| 248 "var y = 5;\n" | |
| 249 "main() {\n" | |
| 250 " if (x != 0) {\n" | |
| 251 " return x;\n" | |
| 252 " }\n" | |
| 253 " return y;\n" | |
| 254 "}\n"; | |
| 255 | |
| 256 SourcePositionTest spt(thread, kScript); | |
| 257 spt.BuildGraphFor("main"); | |
| 258 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); | |
| 259 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); | |
| 260 spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 7); | |
| 261 spt.InstanceCallAt(4, 9, Token::kEQ); | |
| 262 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 9); | |
| 263 spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 12); | |
|
rmacnak
2016/01/09 00:35:56
Missing return and debug step check for 'return x'
Cutch
2016/01/11 18:12:48
Done.
| |
| 264 spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10); | |
| 265 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3); | |
| 266 spt.FuzzyInstructionMatchAt("Return", 7, 3); | |
| 267 } | |
| 268 | |
| 269 | |
| 270 TEST_CASE(SourcePosition_ForLoop) { | |
| 271 const char* kScript = | |
| 272 "var x = 0;\n" | |
| 273 "var y = 5;\n" | |
| 274 "main() {\n" | |
| 275 " for (var i = 0; i < 10; i++) {\n" | |
| 276 " x += i;\n" | |
| 277 " }\n" | |
| 278 " return x;\n" | |
| 279 "}\n"; | |
| 280 | |
| 281 SourcePositionTest spt(thread, kScript); | |
| 282 spt.BuildGraphFor("main"); | |
| 283 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); | |
| 284 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); | |
| 285 spt.FuzzyInstructionMatchAt("StoreLocal", 4, 14); | |
| 286 spt.FuzzyInstructionMatchAt("LoadLocal", 4, 19); | |
| 287 spt.InstanceCallAt(4, 21, Token::kLT); | |
| 288 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 21); | |
| 289 spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 5); | |
| 290 spt.FuzzyInstructionMatchAt("StoreStaticField", 5, 5); | |
| 291 spt.InstanceCallAt(5, 7, Token::kADD); | |
| 292 spt.FuzzyInstructionMatchAt("LoadLocal", 5, 10); | |
| 293 spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10); | |
| 294 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3); | |
| 295 spt.FuzzyInstructionMatchAt("Return", 7, 3); | |
| 296 } | |
| 297 | |
| 298 | |
| 299 TEST_CASE(SourcePosition_While) { | |
| 300 const char* kScript = | |
| 301 "var x = 0;\n" | |
| 302 "var y = 5;\n" | |
| 303 "main() {\n" | |
| 304 " while (x < 10) {\n" | |
| 305 " if (y == 5) {\n" | |
| 306 " return y;\n" | |
| 307 " }\n" | |
| 308 " x++;\n" | |
| 309 " }\n" | |
| 310 " return x;\n" | |
| 311 "}\n"; | |
| 312 | |
| 313 SourcePositionTest spt(thread, kScript); | |
| 314 spt.BuildGraphFor("main"); | |
| 315 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); | |
| 316 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); | |
| 317 | |
| 318 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 4, 3); | |
| 319 spt.FuzzyInstructionMatchAt("Constant", 4, 10); | |
| 320 spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 10); | |
| 321 spt.InstanceCallAt(4, 12, Token::kLT); | |
| 322 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 12); | |
| 323 | |
| 324 spt.FuzzyInstructionMatchAt("Constant", 5, 9); | |
| 325 spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 9); | |
| 326 spt.InstanceCallAt(5, 11, Token::kEQ); | |
| 327 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 5, 11); | |
| 328 | |
| 329 spt.FuzzyInstructionMatchAt("Constant", 6, 14); | |
| 330 spt.FuzzyInstructionMatchAt("LoadStaticField", 6, 14); | |
| 331 spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 7); | |
| 332 spt.FuzzyInstructionMatchAt("Return", 6, 7); | |
| 333 | |
| 334 spt.FuzzyInstructionMatchAt("Constant", 8, 5); | |
| 335 spt.FuzzyInstructionMatchAt("LoadStaticField", 8, 5); | |
| 336 spt.FuzzyInstructionMatchAt("Constant(#1)", 8, 6); | |
| 337 spt.InstanceCallAt(8, 6, Token::kADD); | |
| 338 spt.FuzzyInstructionMatchAt("StoreStaticField", 8, 5); | |
| 339 | |
| 340 spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10); | |
| 341 spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3); | |
| 342 spt.FuzzyInstructionMatchAt("Return", 10, 3); | |
| 343 } | |
| 344 | |
| 231 } // namespace dart | 345 } // namespace dart |
| OLD | NEW |