| 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 count++; | 88 count++; |
| 89 } | 89 } |
| 90 } else { | 90 } else { |
| 91 count++; | 91 count++; |
| 92 } | 92 } |
| 93 } | 93 } |
| 94 } | 94 } |
| 95 DUMP_ASSERT(count > 0); | 95 DUMP_ASSERT(count > 0); |
| 96 } | 96 } |
| 97 | 97 |
| 98 // Expect to find an instance call at |line| and |column|. |
| 99 void InstanceCallAt(const char* needle, |
| 100 intptr_t line, |
| 101 intptr_t column = -1) { |
| 102 ZoneGrowableArray<Instruction*>* instructions = |
| 103 FindInstructionsAt(line, column); |
| 104 intptr_t count = 0; |
| 105 for (intptr_t i = 0; i < instructions->length(); i++) { |
| 106 Instruction* instr = instructions->At(i); |
| 107 EXPECT(instr != NULL); |
| 108 if (instr->IsInstanceCall()) { |
| 109 const char* haystack = instr->ToCString(); |
| 110 if (strstr(haystack, needle) != NULL) { |
| 111 count++; |
| 112 } |
| 113 } |
| 114 } |
| 115 DUMP_ASSERT(count > 0); |
| 116 } |
| 117 |
| 98 // Expect to find at least one static call at |line| and |column|. The | 118 // Expect to find at least one static call at |line| and |column|. The |
| 99 // static call will have |needle| in its |ToCString| representation. | 119 // static call will have |needle| in its |ToCString| representation. |
| 100 void StaticCallAt(const char* needle, | 120 void StaticCallAt(const char* needle, |
| 101 intptr_t line, | 121 intptr_t line, |
| 102 intptr_t column = -1) { | 122 intptr_t column = -1) { |
| 103 ZoneGrowableArray<Instruction*>* instructions = | 123 ZoneGrowableArray<Instruction*>* instructions = |
| 104 FindInstructionsAt(line, column); | 124 FindInstructionsAt(line, column); |
| 105 intptr_t count = 0; | 125 intptr_t count = 0; |
| 106 for (intptr_t i = 0; i < instructions->length(); i++) { | 126 for (intptr_t i = 0; i < instructions->length(); i++) { |
| 107 Instruction* instr = instructions->At(i); | 127 Instruction* instr = instructions->At(i); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 for (intptr_t i = 0; i < blocks_->length(); i++) { | 159 for (intptr_t i = 0; i < blocks_->length(); i++) { |
| 140 BlockEntryInstr* entry = (*blocks_)[i]; | 160 BlockEntryInstr* entry = (*blocks_)[i]; |
| 141 THR_Print("B%" Pd ":\n", entry->block_id()); | 161 THR_Print("B%" Pd ":\n", entry->block_id()); |
| 142 DumpInstruction(entry); | 162 DumpInstruction(entry); |
| 143 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 163 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 144 DumpInstruction(it.Current()); | 164 DumpInstruction(it.Current()); |
| 145 } | 165 } |
| 146 } | 166 } |
| 147 } | 167 } |
| 148 | 168 |
| 169 // Fails if any of the IR nodes has a token position of Token::kNoSourcePos. |
| 170 void EnsureSourcePositions() { |
| 171 for (intptr_t i = 0; i < blocks_->length(); i++) { |
| 172 BlockEntryInstr* entry = (*blocks_)[i]; |
| 173 DUMP_ASSERT(entry->token_pos() != Token::kNoSourcePos); |
| 174 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 175 Instruction* instr = it.Current(); |
| 176 DUMP_ASSERT(instr->token_pos() != Token::kNoSourcePos); |
| 177 } |
| 178 } |
| 179 } |
| 180 |
| 149 private: | 181 private: |
| 150 void DumpInstruction(Instruction* instr) { | 182 void DumpInstruction(Instruction* instr) { |
| 151 const intptr_t token_pos = instr->token_pos(); | 183 intptr_t token_pos = instr->token_pos(); |
| 184 bool synthetic = false; |
| 185 if (Token::IsSynthetic(token_pos)) { |
| 186 synthetic = true; |
| 187 token_pos = Token::FromSynthetic(token_pos); |
| 188 } |
| 152 if (token_pos < 0) { | 189 if (token_pos < 0) { |
| 153 const char* token_pos_string = | 190 const char* token_pos_string = |
| 154 ClassifyingTokenPositions::ToCString(token_pos); | 191 ClassifyingTokenPositions::ToCString(token_pos); |
| 155 THR_Print("%12s -- %s\n", token_pos_string, instr->ToCString()); | 192 THR_Print("%12s -- %s\n", token_pos_string, instr->ToCString()); |
| 156 return; | 193 return; |
| 157 } | 194 } |
| 158 intptr_t token_line = -1; | 195 intptr_t token_line = -1; |
| 159 intptr_t token_column = -1; | 196 intptr_t token_column = -1; |
| 160 root_script_.GetTokenLocation(token_pos, | 197 root_script_.GetTokenLocation(token_pos, |
| 161 &token_line, | 198 &token_line, |
| 162 &token_column, | 199 &token_column, |
| 163 NULL); | 200 NULL); |
| 164 THR_Print(" %02d:%02d -- %s\n", | 201 if (synthetic) { |
| 165 static_cast<int>(token_line), | 202 THR_Print(" *%02d:%02d -- %s\n", |
| 166 static_cast<int>(token_column), | 203 static_cast<int>(token_line), |
| 167 instr->ToCString()); | 204 static_cast<int>(token_column), |
| 205 instr->ToCString()); |
| 206 } else { |
| 207 THR_Print(" %02d:%02d -- %s\n", |
| 208 static_cast<int>(token_line), |
| 209 static_cast<int>(token_column), |
| 210 instr->ToCString()); |
| 211 } |
| 168 } | 212 } |
| 169 | 213 |
| 170 Instruction* FindFirstInstructionAt(intptr_t line, intptr_t column) { | 214 Instruction* FindFirstInstructionAt(intptr_t line, intptr_t column) { |
| 171 ZoneGrowableArray<Instruction*>* instructions = | 215 ZoneGrowableArray<Instruction*>* instructions = |
| 172 FindInstructionsAt(line, column); | 216 FindInstructionsAt(line, column); |
| 173 if (instructions->length() == 0) { | 217 if (instructions->length() == 0) { |
| 174 return NULL; | 218 return NULL; |
| 175 } | 219 } |
| 176 return instructions->At(0); | 220 return instructions->At(0); |
| 177 } | 221 } |
| 178 | 222 |
| 179 ZoneGrowableArray<Instruction*>* FindInstructionsAt( | 223 ZoneGrowableArray<Instruction*>* FindInstructionsAt( |
| 180 intptr_t line, intptr_t column) { | 224 intptr_t line, intptr_t column) { |
| 181 ZoneGrowableArray<Instruction*>* instructions = | 225 ZoneGrowableArray<Instruction*>* instructions = |
| 182 new ZoneGrowableArray<Instruction*>(); | 226 new ZoneGrowableArray<Instruction*>(); |
| 183 for (intptr_t i = 0; i < blocks_->length(); i++) { | 227 for (intptr_t i = 0; i < blocks_->length(); i++) { |
| 184 BlockEntryInstr* entry = (*blocks_)[i]; | 228 BlockEntryInstr* entry = (*blocks_)[i]; |
| 185 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 229 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 186 Instruction* instr = it.Current(); | 230 Instruction* instr = it.Current(); |
| 187 intptr_t token_pos = instr->token_pos(); | 231 intptr_t token_pos = instr->token_pos(); |
| 232 if (Token::IsSynthetic(token_pos)) { |
| 233 token_pos = Token::FromSynthetic(token_pos); |
| 234 } |
| 188 if (token_pos < 0) { | 235 if (token_pos < 0) { |
| 189 continue; | 236 continue; |
| 190 } | 237 } |
| 191 intptr_t token_line = -1; | 238 intptr_t token_line = -1; |
| 192 intptr_t token_column = -1; | 239 intptr_t token_column = -1; |
| 193 root_script_.GetTokenLocation(token_pos, | 240 root_script_.GetTokenLocation(token_pos, |
| 194 &token_line, | 241 &token_line, |
| 195 &token_column, | 242 &token_column, |
| 196 NULL); | 243 NULL); |
| 197 if (token_line == line) { | 244 if (token_line == line) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 " return z;\n" | 307 " return z;\n" |
| 261 "}\n"; | 308 "}\n"; |
| 262 | 309 |
| 263 SourcePositionTest spt(thread, kScript); | 310 SourcePositionTest spt(thread, kScript); |
| 264 spt.BuildGraphFor("main"); | 311 spt.BuildGraphFor("main"); |
| 265 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); | 312 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); |
| 266 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); | 313 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); |
| 267 spt.InstanceCallAt(4, 13, Token::kADD); | 314 spt.InstanceCallAt(4, 13, Token::kADD); |
| 268 spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 3); | 315 spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 3); |
| 269 spt.FuzzyInstructionMatchAt("Return", 5, 3); | 316 spt.FuzzyInstructionMatchAt("Return", 5, 3); |
| 317 |
| 318 spt.EnsureSourcePositions(); |
| 270 } | 319 } |
| 271 | 320 |
| 272 | 321 |
| 273 TEST_CASE(SourcePosition_If) { | 322 TEST_CASE(SourcePosition_If) { |
| 274 const char* kScript = | 323 const char* kScript = |
| 275 "var x = 5;\n" | 324 "var x = 5;\n" |
| 276 "var y = 5;\n" | 325 "var y = 5;\n" |
| 277 "main() {\n" | 326 "main() {\n" |
| 278 " if (x != 0) {\n" | 327 " if (x != 0) {\n" |
| 279 " return x;\n" | 328 " return x;\n" |
| 280 " }\n" | 329 " }\n" |
| 281 " return y;\n" | 330 " return y;\n" |
| 282 "}\n"; | 331 "}\n"; |
| 283 | 332 |
| 284 SourcePositionTest spt(thread, kScript); | 333 SourcePositionTest spt(thread, kScript); |
| 285 spt.BuildGraphFor("main"); | 334 spt.BuildGraphFor("main"); |
| 286 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); | 335 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); |
| 287 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); | 336 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); |
| 288 spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 7); | 337 spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 7); |
| 289 spt.InstanceCallAt(4, 9, Token::kEQ); | 338 spt.InstanceCallAt(4, 9, Token::kEQ); |
| 290 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 9); | 339 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 9); |
| 291 spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 12); | 340 spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 12); |
| 292 spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 5); | 341 spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 5); |
| 293 spt.FuzzyInstructionMatchAt("Return", 5, 5); | 342 spt.FuzzyInstructionMatchAt("Return", 5, 5); |
| 294 spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10); | 343 spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10); |
| 295 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3); | 344 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3); |
| 296 spt.FuzzyInstructionMatchAt("Return", 7, 3); | 345 spt.FuzzyInstructionMatchAt("Return", 7, 3); |
| 346 |
| 347 spt.EnsureSourcePositions(); |
| 297 } | 348 } |
| 298 | 349 |
| 299 | 350 |
| 300 TEST_CASE(SourcePosition_ForLoop) { | 351 TEST_CASE(SourcePosition_ForLoop) { |
| 301 const char* kScript = | 352 const char* kScript = |
| 302 "var x = 0;\n" | 353 "var x = 0;\n" |
| 303 "var y = 5;\n" | 354 "var y = 5;\n" |
| 304 "main() {\n" | 355 "main() {\n" |
| 305 " for (var i = 0; i < 10; i++) {\n" | 356 " for (var i = 0; i < 10; i++) {\n" |
| 306 " x += i;\n" | 357 " x += i;\n" |
| 307 " }\n" | 358 " }\n" |
| 308 " return x;\n" | 359 " return x;\n" |
| 309 "}\n"; | 360 "}\n"; |
| 310 | 361 |
| 311 SourcePositionTest spt(thread, kScript); | 362 SourcePositionTest spt(thread, kScript); |
| 312 spt.BuildGraphFor("main"); | 363 spt.BuildGraphFor("main"); |
| 313 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); | 364 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); |
| 314 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); | 365 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); |
| 315 spt.FuzzyInstructionMatchAt("StoreLocal", 4, 14); | 366 spt.FuzzyInstructionMatchAt("StoreLocal", 4, 14); |
| 316 spt.FuzzyInstructionMatchAt("LoadLocal", 4, 19); | 367 spt.FuzzyInstructionMatchAt("LoadLocal", 4, 19); |
| 317 spt.InstanceCallAt(4, 21, Token::kLT); | 368 spt.InstanceCallAt(4, 21, Token::kLT); |
| 318 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 21); | 369 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 21); |
| 319 spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 5); | 370 spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 5); |
| 320 spt.FuzzyInstructionMatchAt("StoreStaticField", 5, 5); | 371 spt.FuzzyInstructionMatchAt("StoreStaticField", 5, 5); |
| 321 spt.InstanceCallAt(5, 7, Token::kADD); | 372 spt.InstanceCallAt(5, 7, Token::kADD); |
| 322 spt.FuzzyInstructionMatchAt("LoadLocal", 5, 10); | 373 spt.FuzzyInstructionMatchAt("LoadLocal", 5, 10); |
| 323 spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10); | 374 spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10); |
| 324 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3); | 375 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3); |
| 325 spt.FuzzyInstructionMatchAt("Return", 7, 3); | 376 spt.FuzzyInstructionMatchAt("Return", 7, 3); |
| 377 |
| 378 spt.EnsureSourcePositions(); |
| 326 } | 379 } |
| 327 | 380 |
| 328 | 381 |
| 329 TEST_CASE(SourcePosition_While) { | 382 TEST_CASE(SourcePosition_While) { |
| 330 const char* kScript = | 383 const char* kScript = |
| 331 "var x = 0;\n" | 384 "var x = 0;\n" |
| 332 "var y = 5;\n" | 385 "var y = 5;\n" |
| 333 "main() {\n" | 386 "main() {\n" |
| 334 " while (x < 10) {\n" | 387 " while (x < 10) {\n" |
| 335 " if (y == 5) {\n" | 388 " if (y == 5) {\n" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 363 | 416 |
| 364 spt.FuzzyInstructionMatchAt("Constant", 8, 5); | 417 spt.FuzzyInstructionMatchAt("Constant", 8, 5); |
| 365 spt.FuzzyInstructionMatchAt("LoadStaticField", 8, 5); | 418 spt.FuzzyInstructionMatchAt("LoadStaticField", 8, 5); |
| 366 spt.FuzzyInstructionMatchAt("Constant(#1)", 8, 6); | 419 spt.FuzzyInstructionMatchAt("Constant(#1)", 8, 6); |
| 367 spt.InstanceCallAt(8, 6, Token::kADD); | 420 spt.InstanceCallAt(8, 6, Token::kADD); |
| 368 spt.FuzzyInstructionMatchAt("StoreStaticField", 8, 5); | 421 spt.FuzzyInstructionMatchAt("StoreStaticField", 8, 5); |
| 369 | 422 |
| 370 spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10); | 423 spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10); |
| 371 spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3); | 424 spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3); |
| 372 spt.FuzzyInstructionMatchAt("Return", 10, 3); | 425 spt.FuzzyInstructionMatchAt("Return", 10, 3); |
| 426 |
| 427 spt.EnsureSourcePositions(); |
| 373 } | 428 } |
| 374 | 429 |
| 375 | 430 |
| 376 TEST_CASE(SourcePosition_WhileContinueBreak) { | 431 TEST_CASE(SourcePosition_WhileContinueBreak) { |
| 377 const char* kScript = | 432 const char* kScript = |
| 378 "var x = 0;\n" | 433 "var x = 0;\n" |
| 379 "var y = 5;\n" | 434 "var y = 5;\n" |
| 380 "main() {\n" | 435 "main() {\n" |
| 381 " while (x < 10) {\n" | 436 " while (x < 10) {\n" |
| 382 " if (y == 5) {\n" | 437 " if (y == 5) {\n" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 401 | 456 |
| 402 spt.FuzzyInstructionMatchAt("Constant(#Field", 5, 9); | 457 spt.FuzzyInstructionMatchAt("Constant(#Field", 5, 9); |
| 403 spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 9); | 458 spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 9); |
| 404 spt.FuzzyInstructionMatchAt("Constant(#5", 5, 14); | 459 spt.FuzzyInstructionMatchAt("Constant(#5", 5, 14); |
| 405 spt.InstanceCallAt(5, 11, Token::kEQ); | 460 spt.InstanceCallAt(5, 11, Token::kEQ); |
| 406 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 5, 11); | 461 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 5, 11); |
| 407 | 462 |
| 408 spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10); | 463 spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10); |
| 409 spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3); | 464 spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3); |
| 410 spt.FuzzyInstructionMatchAt("Return", 10, 3); | 465 spt.FuzzyInstructionMatchAt("Return", 10, 3); |
| 466 |
| 467 spt.EnsureSourcePositions(); |
| 411 } | 468 } |
| 412 | 469 |
| 413 | 470 |
| 414 TEST_CASE(SourcePosition_LoadIndexed) { | 471 TEST_CASE(SourcePosition_LoadIndexed) { |
| 415 const char* kScript = | 472 const char* kScript = |
| 416 "var x = 0;\n" | 473 "var x = 0;\n" |
| 417 "var z = new List(3);\n" | 474 "var z = new List(3);\n" |
| 418 "main() {\n" | 475 "main() {\n" |
| 419 " z[0];\n" | 476 " z[0];\n" |
| 420 " var y = z[0] + z[1] + z[2];\n" | 477 " var y = z[0] + z[1] + z[2];\n" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 438 | 495 |
| 439 spt.StaticCallAt("get:z", 5, 25); | 496 spt.StaticCallAt("get:z", 5, 25); |
| 440 spt.FuzzyInstructionMatchAt("Constant(#2)", 5, 27); | 497 spt.FuzzyInstructionMatchAt("Constant(#2)", 5, 27); |
| 441 spt.InstanceCallAt(5, 26, Token::kINDEX); | 498 spt.InstanceCallAt(5, 26, Token::kINDEX); |
| 442 | 499 |
| 443 spt.InstanceCallAt(5, 23, Token::kADD); | 500 spt.InstanceCallAt(5, 23, Token::kADD); |
| 444 | 501 |
| 445 spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1); | 502 spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1); |
| 446 spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1); | 503 spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1); |
| 447 spt.FuzzyInstructionMatchAt("Return", 6, 1); | 504 spt.FuzzyInstructionMatchAt("Return", 6, 1); |
| 505 |
| 506 spt.EnsureSourcePositions(); |
| 448 } | 507 } |
| 449 | 508 |
| 450 | 509 |
| 451 TEST_CASE(SourcePosition_StoreIndexed) { | 510 TEST_CASE(SourcePosition_StoreIndexed) { |
| 452 const char* kScript = | 511 const char* kScript = |
| 453 "var x = 0;\n" | 512 "var x = 0;\n" |
| 454 "var z = new List(4);\n" | 513 "var z = new List(4);\n" |
| 455 "main() {\n" | 514 "main() {\n" |
| 456 " z[0];\n" | 515 " z[0];\n" |
| 457 " z[3] = z[0] + z[1] + z[2];\n" | 516 " z[3] = z[0] + z[1] + z[2];\n" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 480 | 539 |
| 481 spt.StaticCallAt("get:z", 5, 24); | 540 spt.StaticCallAt("get:z", 5, 24); |
| 482 spt.FuzzyInstructionMatchAt("Constant(#2)", 5, 26); | 541 spt.FuzzyInstructionMatchAt("Constant(#2)", 5, 26); |
| 483 spt.InstanceCallAt(5, 25, Token::kINDEX); | 542 spt.InstanceCallAt(5, 25, Token::kINDEX); |
| 484 | 543 |
| 485 spt.InstanceCallAt(5, 4, Token::kASSIGN_INDEX); | 544 spt.InstanceCallAt(5, 4, Token::kASSIGN_INDEX); |
| 486 | 545 |
| 487 spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1); | 546 spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1); |
| 488 spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1); | 547 spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1); |
| 489 spt.FuzzyInstructionMatchAt("Return", 6, 1); | 548 spt.FuzzyInstructionMatchAt("Return", 6, 1); |
| 549 |
| 550 spt.EnsureSourcePositions(); |
| 490 } | 551 } |
| 491 | 552 |
| 492 | 553 |
| 493 TEST_CASE(SourcePosition_BitwiseOperations) { | 554 TEST_CASE(SourcePosition_BitwiseOperations) { |
| 494 const char* kScript = | 555 const char* kScript = |
| 495 "var x = 0;\n" | 556 "var x = 0;\n" |
| 496 "var y = 1;\n" | 557 "var y = 1;\n" |
| 497 "main() {\n" | 558 "main() {\n" |
| 498 " var z;\n" | 559 " var z;\n" |
| 499 " z = x & y;\n" | 560 " z = x & y;\n" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 528 spt.InstanceCallAt(7, 9, Token::kBIT_XOR); | 589 spt.InstanceCallAt(7, 9, Token::kBIT_XOR); |
| 529 spt.FuzzyInstructionMatchAt("StoreLocal(z", 7, 3); | 590 spt.FuzzyInstructionMatchAt("StoreLocal(z", 7, 3); |
| 530 | 591 |
| 531 spt.FuzzyInstructionMatchAt("LoadLocal(z", 8, 8); | 592 spt.FuzzyInstructionMatchAt("LoadLocal(z", 8, 8); |
| 532 spt.InstanceCallAt(8, 7, Token::kBIT_NOT); | 593 spt.InstanceCallAt(8, 7, Token::kBIT_NOT); |
| 533 spt.FuzzyInstructionMatchAt("StoreLocal(z", 8, 3); | 594 spt.FuzzyInstructionMatchAt("StoreLocal(z", 8, 3); |
| 534 | 595 |
| 535 spt.FuzzyInstructionMatchAt("LoadLocal(z", 9, 10); | 596 spt.FuzzyInstructionMatchAt("LoadLocal(z", 9, 10); |
| 536 spt.FuzzyInstructionMatchAt("DebugStepCheck", 9, 3); | 597 spt.FuzzyInstructionMatchAt("DebugStepCheck", 9, 3); |
| 537 spt.FuzzyInstructionMatchAt("Return", 9, 3); | 598 spt.FuzzyInstructionMatchAt("Return", 9, 3); |
| 599 |
| 600 spt.EnsureSourcePositions(); |
| 538 } | 601 } |
| 539 | 602 |
| 540 | 603 |
| 541 TEST_CASE(SourcePosition_IfElse) { | 604 TEST_CASE(SourcePosition_IfElse) { |
| 542 const char* kScript = | 605 const char* kScript = |
| 543 "var x = 5;\n" | 606 "var x = 5;\n" |
| 544 "var y = 5;\n" | 607 "var y = 5;\n" |
| 545 "main() {\n" | 608 "main() {\n" |
| 546 " if (x != 0) {\n" | 609 " if (x != 0) {\n" |
| 547 " return x;\n" | 610 " return x;\n" |
| 548 " } else {\n" | 611 " } else {\n" |
| 549 " return y;\n" | 612 " return y;\n" |
| 550 " }\n" | 613 " }\n" |
| 551 "}\n"; | 614 "}\n"; |
| 552 | 615 |
| 553 SourcePositionTest spt(thread, kScript); | 616 SourcePositionTest spt(thread, kScript); |
| 554 spt.BuildGraphFor("main"); | 617 spt.BuildGraphFor("main"); |
| 555 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); | 618 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); |
| 556 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); | 619 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); |
| 557 spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 7); | 620 spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 7); |
| 558 spt.InstanceCallAt(4, 9, Token::kEQ); | 621 spt.InstanceCallAt(4, 9, Token::kEQ); |
| 559 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 9); | 622 spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 9); |
| 560 spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 12); | 623 spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 12); |
| 561 spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 5); | 624 spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 5); |
| 562 spt.FuzzyInstructionMatchAt("Return", 5, 5); | 625 spt.FuzzyInstructionMatchAt("Return", 5, 5); |
| 563 spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 12); | 626 spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 12); |
| 564 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 5); | 627 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 5); |
| 565 spt.FuzzyInstructionMatchAt("Return", 7, 5); | 628 spt.FuzzyInstructionMatchAt("Return", 7, 5); |
| 629 |
| 630 spt.EnsureSourcePositions(); |
| 566 } | 631 } |
| 567 | 632 |
| 568 | 633 |
| 569 TEST_CASE(SourcePosition_Switch) { | 634 TEST_CASE(SourcePosition_Switch) { |
| 570 const char* kScript = | 635 const char* kScript = |
| 571 "var x = 5;\n" | 636 "var x = 5;\n" |
| 572 "var y = 5;\n" | 637 "var y = 5;\n" |
| 573 "main() {\n" | 638 "main() {\n" |
| 574 " switch (x) {\n" | 639 " switch (x) {\n" |
| 575 " case 1: return 3;\n" | 640 " case 1: return 3;\n" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 600 spt.FuzzyInstructionMatchAt("LoadLocal(:switch_expr", 6, 5); // 'c' | 665 spt.FuzzyInstructionMatchAt("LoadLocal(:switch_expr", 6, 5); // 'c' |
| 601 spt.InstanceCallAt(6, 10, Token::kEQ); // '2' | 666 spt.InstanceCallAt(6, 10, Token::kEQ); // '2' |
| 602 | 667 |
| 603 spt.FuzzyInstructionMatchAt("Constant(#4", 6, 20); // '4' | 668 spt.FuzzyInstructionMatchAt("Constant(#4", 6, 20); // '4' |
| 604 spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 13); | 669 spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 13); |
| 605 spt.FuzzyInstructionMatchAt("Return", 6, 13); | 670 spt.FuzzyInstructionMatchAt("Return", 6, 13); |
| 606 | 671 |
| 607 spt.FuzzyInstructionMatchAt("Constant(#5", 7, 21); // '5' | 672 spt.FuzzyInstructionMatchAt("Constant(#5", 7, 21); // '5' |
| 608 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 14); | 673 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 14); |
| 609 spt.FuzzyInstructionMatchAt("Return", 7, 14); | 674 spt.FuzzyInstructionMatchAt("Return", 7, 14); |
| 675 |
| 676 spt.EnsureSourcePositions(); |
| 610 } | 677 } |
| 611 | 678 |
| 612 | 679 |
| 613 TEST_CASE(SourcePosition_TryCatchFinally) { | 680 TEST_CASE(SourcePosition_TryCatchFinally) { |
| 614 const char* kScript = | 681 const char* kScript = |
| 615 "var x = 5;\n" | 682 "var x = 5;\n" |
| 616 "var y = 5;\n" | 683 "var y = 5;\n" |
| 617 "main() {\n" | 684 "main() {\n" |
| 618 " try {\n" | 685 " try {\n" |
| 619 " throw 'A';\n" | 686 " throw 'A';\n" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 650 spt.FuzzyInstructionMatchAt("StoreLocal(:finally_ret_val", 8, 5); // 'r' | 717 spt.FuzzyInstructionMatchAt("StoreLocal(:finally_ret_val", 8, 5); // 'r' |
| 651 | 718 |
| 652 spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12); // '9' | 719 spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12); // '9' |
| 653 spt.FuzzyInstructionMatchAt("Return", 10, 5); // 'r' | 720 spt.FuzzyInstructionMatchAt("Return", 10, 5); // 'r' |
| 654 | 721 |
| 655 spt.FuzzyInstructionMatchAt("LoadLocal(:saved_try_context", 9, 13); // '{' | 722 spt.FuzzyInstructionMatchAt("LoadLocal(:saved_try_context", 9, 13); // '{' |
| 656 spt.FuzzyInstructionMatchAt("StoreLocal(:current_context", 9, 13); // '{' | 723 spt.FuzzyInstructionMatchAt("StoreLocal(:current_context", 9, 13); // '{' |
| 657 | 724 |
| 658 spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12); // '9' | 725 spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12); // '9' |
| 659 spt.FuzzyInstructionMatchAt("Return", 10, 5); // 'r' | 726 spt.FuzzyInstructionMatchAt("Return", 10, 5); // 'r' |
| 727 |
| 728 spt.EnsureSourcePositions(); |
| 729 } |
| 730 |
| 731 |
| 732 TEST_CASE(SourcePosition_InstanceFields) { |
| 733 const char* kScript = |
| 734 "class A {\n" |
| 735 " var x;\n" |
| 736 " var y;\n" |
| 737 "}\n" |
| 738 "main() {\n" |
| 739 " var z = new A();\n" |
| 740 " z.x = 99;\n" |
| 741 " z.y = z.x;\n" |
| 742 " return z.y;\n" |
| 743 "}\n"; |
| 744 |
| 745 SourcePositionTest spt(thread, kScript); |
| 746 spt.BuildGraphFor("main"); |
| 747 spt.FuzzyInstructionMatchAt("AllocateObject(A)", 6, 15); // 'A' |
| 748 spt.FuzzyInstructionMatchAt("StaticCall", 6, 15); // 'A' |
| 749 spt.FuzzyInstructionMatchAt("StoreLocal(z", 6, 9); // '=' |
| 750 spt.InstanceCallAt("set:x", 7, 5); // 'x' |
| 751 spt.InstanceCallAt("get:x", 8, 11); // 'x' |
| 752 spt.InstanceCallAt("set:y", 8, 5); // 'y' |
| 753 |
| 754 spt.InstanceCallAt("get:y", 9, 12); // 'y' |
| 755 spt.FuzzyInstructionMatchAt("DebugStepCheck", 9, 3); |
| 756 spt.FuzzyInstructionMatchAt("Return", 9, 3); |
| 757 |
| 758 spt.EnsureSourcePositions(); |
| 759 } |
| 760 |
| 761 |
| 762 TEST_CASE(SourcePosition_Async) { |
| 763 const char* kScript = |
| 764 "import 'dart:async';\n" |
| 765 "var x = 5;\n" |
| 766 "var y = 5;\n" |
| 767 "foo(Future f1, Future f2) async {\n" |
| 768 " await f1;\n" |
| 769 " await f2;\n" |
| 770 " return 55;\n" |
| 771 "}\n" |
| 772 "main() {\n" |
| 773 " foo(new Future.value(33));\n" |
| 774 "}\n"; |
| 775 |
| 776 SourcePositionTest spt(thread, kScript); |
| 777 spt.BuildGraphFor("foo"); |
| 778 spt.EnsureSourcePositions(); |
| 779 spt.Dump(); |
| 780 } |
| 781 |
| 782 |
| 783 static bool SyntheticRoundTripTest(intptr_t token_pos) { |
| 784 return Token::FromSynthetic(Token::ToSynthetic(token_pos)) == token_pos; |
| 785 } |
| 786 |
| 787 |
| 788 UNIT_TEST_CASE(SourcePosition_SyntheticTokens) { |
| 789 EXPECT(Token::kNoSourcePos == -1); |
| 790 EXPECT(Token::kMinSourcePos == 0); |
| 791 EXPECT(Token::kMaxSourcePos > 0); |
| 792 |
| 793 EXPECT(!Token::IsSynthetic(0)); |
| 794 EXPECT(Token::IsSynthetic(Token::ToSynthetic(0))); |
| 795 EXPECT(Token::IsSynthetic(Token::ToSynthetic(9))); |
| 796 EXPECT(!Token::IsSynthetic(Token::FromSynthetic(-1))); |
| 797 EXPECT(!Token::IsSynthetic(ClassifyingTokenPositions::kPrivate)); |
| 798 EXPECT(!Token::IsSynthetic(ClassifyingTokenPositions::kLast)); |
| 799 |
| 800 EXPECT(SyntheticRoundTripTest(0)); |
| 801 EXPECT(SyntheticRoundTripTest(Token::kMaxSourcePos)); |
| 802 EXPECT(SyntheticRoundTripTest(Token::kMinSourcePos)); |
| 660 } | 803 } |
| 661 | 804 |
| 662 } // namespace dart | 805 } // namespace dart |
| 663 | 806 |
| OLD | NEW |