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 |