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" |
11 | 11 |
12 namespace dart { | 12 namespace dart { |
13 | 13 |
14 #ifndef PRODUCT | 14 #ifndef PRODUCT |
15 | 15 |
16 #define DUMP_ASSERT(condition) \ | 16 #define DUMP_ASSERT(condition) \ |
17 if (!(condition)) { \ | 17 if (!(condition)) { \ |
18 dart::Expect(__FILE__, __LINE__).Fail("expected: %s", #condition); \ | 18 dart::Expect(__FILE__, __LINE__).Fail("expected: %s", #condition); \ |
19 THR_Print(">>> BEGIN source position table for `%s`\n", graph_name_); \ | 19 THR_Print(">>> BEGIN source position table for `%s`\n", graph_name_); \ |
20 Dump(); \ | 20 Dump(); \ |
21 THR_Print("<<< END source position table for `%s`\n", graph_name_); \ | 21 THR_Print("<<< END source position table for `%s`\n", graph_name_); \ |
22 OS::Abort(); \ | 22 OS::Abort(); \ |
23 } | 23 } |
24 | 24 |
25 class SourcePositionTest : public ValueObject { | 25 class SourcePositionTest : public ValueObject { |
26 public: | 26 public: |
27 SourcePositionTest(Thread* thread, | 27 SourcePositionTest(Thread* thread, const char* script) |
28 const char* script) | |
29 : thread_(thread), | 28 : thread_(thread), |
30 isolate_(thread->isolate()), | 29 isolate_(thread->isolate()), |
31 script_(script), | 30 script_(script), |
32 root_lib_(Library::Handle()), | 31 root_lib_(Library::Handle()), |
33 root_script_(Script::Handle()), | 32 root_script_(Script::Handle()), |
34 graph_(NULL), | 33 graph_(NULL), |
35 blocks_(NULL) { | 34 blocks_(NULL) { |
36 EXPECT(thread_ != NULL); | 35 EXPECT(thread_ != NULL); |
37 EXPECT(isolate_ != NULL); | 36 EXPECT(isolate_ != NULL); |
38 EXPECT(script_ != NULL); | 37 EXPECT(script_ != NULL); |
39 Dart_Handle lib = TestCase::LoadTestScript(script, NULL); | 38 Dart_Handle lib = TestCase::LoadTestScript(script, NULL); |
40 EXPECT_VALID(lib); | 39 EXPECT_VALID(lib); |
41 root_lib_ ^= Api::UnwrapHandle(lib); | 40 root_lib_ ^= Api::UnwrapHandle(lib); |
42 EXPECT(!root_lib_.IsNull()); | 41 EXPECT(!root_lib_.IsNull()); |
43 root_script_ ^= root_lib_.LookupScript( | 42 root_script_ ^= |
44 String::Handle(String::New(USER_TEST_URI))); | 43 root_lib_.LookupScript(String::Handle(String::New(USER_TEST_URI))); |
45 EXPECT(!root_script_.IsNull()); | 44 EXPECT(!root_script_.IsNull()); |
46 } | 45 } |
47 | 46 |
48 void BuildGraphFor(const char* function_name) { | 47 void BuildGraphFor(const char* function_name) { |
49 graph_ = NULL; | 48 graph_ = NULL; |
50 blocks_ = NULL; | 49 blocks_ = NULL; |
51 graph_name_ = NULL; | 50 graph_name_ = NULL; |
52 | 51 |
53 // Only support unoptimized code for now. | 52 // Only support unoptimized code for now. |
54 const bool optimized = false; | 53 const bool optimized = false; |
55 | 54 |
56 const Function& function = | 55 const Function& function = |
57 Function::Handle(GetFunction(root_lib_, function_name)); | 56 Function::Handle(GetFunction(root_lib_, function_name)); |
58 ZoneGrowableArray<const ICData*>* ic_data_array = | 57 ZoneGrowableArray<const ICData*>* ic_data_array = |
59 new ZoneGrowableArray<const ICData*>(); | 58 new ZoneGrowableArray<const ICData*>(); |
60 ParsedFunction* parsed_function = new ParsedFunction( | 59 ParsedFunction* parsed_function = |
61 thread_, Function::ZoneHandle(function.raw())); | 60 new ParsedFunction(thread_, Function::ZoneHandle(function.raw())); |
62 Parser::ParseFunction(parsed_function); | 61 Parser::ParseFunction(parsed_function); |
63 parsed_function->AllocateVariables(); | 62 parsed_function->AllocateVariables(); |
64 FlowGraphBuilder builder( | 63 FlowGraphBuilder builder(*parsed_function, *ic_data_array, NULL, |
65 *parsed_function, | 64 Compiler::kNoOSRDeoptId); |
66 *ic_data_array, | |
67 NULL, | |
68 Compiler::kNoOSRDeoptId); | |
69 graph_ = builder.BuildGraph(); | 65 graph_ = builder.BuildGraph(); |
70 EXPECT(graph_ != NULL); | 66 EXPECT(graph_ != NULL); |
71 blocks_ = graph_->CodegenBlockOrder(optimized); | 67 blocks_ = graph_->CodegenBlockOrder(optimized); |
72 EXPECT(blocks_ != NULL); | 68 EXPECT(blocks_ != NULL); |
73 graph_name_ = function_name; | 69 graph_name_ = function_name; |
74 EXPECT(graph_name_ != NULL); | 70 EXPECT(graph_name_ != NULL); |
75 } | 71 } |
76 | 72 |
77 // Expect to find an instance call at |line| and |column|. | 73 // Expect to find an instance call at |line| and |column|. |
78 void InstanceCallAt(intptr_t line, | 74 void InstanceCallAt(intptr_t line, |
(...skipping 12 matching lines...) Expand all Loading... |
91 } | 87 } |
92 } else { | 88 } else { |
93 count++; | 89 count++; |
94 } | 90 } |
95 } | 91 } |
96 } | 92 } |
97 DUMP_ASSERT(count > 0); | 93 DUMP_ASSERT(count > 0); |
98 } | 94 } |
99 | 95 |
100 // Expect to find an instance call at |line| and |column|. | 96 // Expect to find an instance call at |line| and |column|. |
101 void InstanceCallAt(const char* needle, | 97 void InstanceCallAt(const char* needle, intptr_t line, intptr_t column = -1) { |
102 intptr_t line, | |
103 intptr_t column = -1) { | |
104 ZoneGrowableArray<Instruction*>* instructions = | 98 ZoneGrowableArray<Instruction*>* instructions = |
105 FindInstructionsAt(line, column); | 99 FindInstructionsAt(line, column); |
106 intptr_t count = 0; | 100 intptr_t count = 0; |
107 for (intptr_t i = 0; i < instructions->length(); i++) { | 101 for (intptr_t i = 0; i < instructions->length(); i++) { |
108 Instruction* instr = instructions->At(i); | 102 Instruction* instr = instructions->At(i); |
109 EXPECT(instr != NULL); | 103 EXPECT(instr != NULL); |
110 if (instr->IsInstanceCall()) { | 104 if (instr->IsInstanceCall()) { |
111 const char* haystack = instr->ToCString(); | 105 const char* haystack = instr->ToCString(); |
112 if (strstr(haystack, needle) != NULL) { | 106 if (strstr(haystack, needle) != NULL) { |
113 count++; | 107 count++; |
114 } | 108 } |
115 } | 109 } |
116 } | 110 } |
117 DUMP_ASSERT(count > 0); | 111 DUMP_ASSERT(count > 0); |
118 } | 112 } |
119 | 113 |
120 // Expect to find at least one static call at |line| and |column|. The | 114 // Expect to find at least one static call at |line| and |column|. The |
121 // static call will have |needle| in its |ToCString| representation. | 115 // static call will have |needle| in its |ToCString| representation. |
122 void StaticCallAt(const char* needle, | 116 void StaticCallAt(const char* needle, intptr_t line, intptr_t column = -1) { |
123 intptr_t line, | |
124 intptr_t column = -1) { | |
125 ZoneGrowableArray<Instruction*>* instructions = | 117 ZoneGrowableArray<Instruction*>* instructions = |
126 FindInstructionsAt(line, column); | 118 FindInstructionsAt(line, column); |
127 intptr_t count = 0; | 119 intptr_t count = 0; |
128 for (intptr_t i = 0; i < instructions->length(); i++) { | 120 for (intptr_t i = 0; i < instructions->length(); i++) { |
129 Instruction* instr = instructions->At(i); | 121 Instruction* instr = instructions->At(i); |
130 EXPECT(instr != NULL); | 122 EXPECT(instr != NULL); |
131 if (instr->IsStaticCall()) { | 123 if (instr->IsStaticCall()) { |
132 const char* haystack = instr->ToCString(); | 124 const char* haystack = instr->ToCString(); |
133 if (strstr(haystack, needle) != NULL) { | 125 if (strstr(haystack, needle) != NULL) { |
134 count++; | 126 count++; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 synthetic = true; | 181 synthetic = true; |
190 token_pos = token_pos.FromSynthetic(); | 182 token_pos = token_pos.FromSynthetic(); |
191 } | 183 } |
192 if (token_pos.IsClassifying()) { | 184 if (token_pos.IsClassifying()) { |
193 const char* token_pos_string = token_pos.ToCString(); | 185 const char* token_pos_string = token_pos.ToCString(); |
194 THR_Print("%12s -- %s\n", token_pos_string, instr->ToCString()); | 186 THR_Print("%12s -- %s\n", token_pos_string, instr->ToCString()); |
195 return; | 187 return; |
196 } | 188 } |
197 intptr_t token_line = -1; | 189 intptr_t token_line = -1; |
198 intptr_t token_column = -1; | 190 intptr_t token_column = -1; |
199 root_script_.GetTokenLocation(token_pos, | 191 root_script_.GetTokenLocation(token_pos, &token_line, &token_column, NULL); |
200 &token_line, | |
201 &token_column, | |
202 NULL); | |
203 if (synthetic) { | 192 if (synthetic) { |
204 THR_Print(" *%02d:%02d -- %s\n", | 193 THR_Print(" *%02d:%02d -- %s\n", static_cast<int>(token_line), |
205 static_cast<int>(token_line), | 194 static_cast<int>(token_column), instr->ToCString()); |
206 static_cast<int>(token_column), | |
207 instr->ToCString()); | |
208 } else { | 195 } else { |
209 THR_Print(" %02d:%02d -- %s\n", | 196 THR_Print(" %02d:%02d -- %s\n", static_cast<int>(token_line), |
210 static_cast<int>(token_line), | 197 static_cast<int>(token_column), instr->ToCString()); |
211 static_cast<int>(token_column), | |
212 instr->ToCString()); | |
213 } | 198 } |
214 } | 199 } |
215 | 200 |
216 Instruction* FindFirstInstructionAt(intptr_t line, intptr_t column) { | 201 Instruction* FindFirstInstructionAt(intptr_t line, intptr_t column) { |
217 ZoneGrowableArray<Instruction*>* instructions = | 202 ZoneGrowableArray<Instruction*>* instructions = |
218 FindInstructionsAt(line, column); | 203 FindInstructionsAt(line, column); |
219 if (instructions->length() == 0) { | 204 if (instructions->length() == 0) { |
220 return NULL; | 205 return NULL; |
221 } | 206 } |
222 return instructions->At(0); | 207 return instructions->At(0); |
223 } | 208 } |
224 | 209 |
225 ZoneGrowableArray<Instruction*>* FindInstructionsAt( | 210 ZoneGrowableArray<Instruction*>* FindInstructionsAt(intptr_t line, |
226 intptr_t line, intptr_t column) { | 211 intptr_t column) { |
227 ZoneGrowableArray<Instruction*>* instructions = | 212 ZoneGrowableArray<Instruction*>* instructions = |
228 new ZoneGrowableArray<Instruction*>(); | 213 new ZoneGrowableArray<Instruction*>(); |
229 for (intptr_t i = 0; i < blocks_->length(); i++) { | 214 for (intptr_t i = 0; i < blocks_->length(); i++) { |
230 BlockEntryInstr* entry = (*blocks_)[i]; | 215 BlockEntryInstr* entry = (*blocks_)[i]; |
231 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 216 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
232 Instruction* instr = it.Current(); | 217 Instruction* instr = it.Current(); |
233 TokenPosition token_pos = instr->token_pos(); | 218 TokenPosition token_pos = instr->token_pos(); |
234 if (token_pos.IsSynthetic()) { | 219 if (token_pos.IsSynthetic()) { |
235 token_pos = token_pos.FromSynthetic(); | 220 token_pos = token_pos.FromSynthetic(); |
236 } | 221 } |
237 if (!token_pos.IsReal()) { | 222 if (!token_pos.IsReal()) { |
238 continue; | 223 continue; |
239 } | 224 } |
240 intptr_t token_line = -1; | 225 intptr_t token_line = -1; |
241 intptr_t token_column = -1; | 226 intptr_t token_column = -1; |
242 root_script_.GetTokenLocation(token_pos, | 227 root_script_.GetTokenLocation(token_pos, &token_line, &token_column, |
243 &token_line, | |
244 &token_column, | |
245 NULL); | 228 NULL); |
246 if (token_line == line) { | 229 if (token_line == line) { |
247 if ((column < 0) || (column == token_column)) { | 230 if ((column < 0) || (column == token_column)) { |
248 instructions->Add(instr); | 231 instructions->Add(instr); |
249 } | 232 } |
250 } | 233 } |
251 } | 234 } |
252 } | 235 } |
253 return instructions; | 236 return instructions; |
254 } | 237 } |
255 | 238 |
256 ZoneGrowableArray<Instruction*>* FindInstructionsAt(intptr_t token_pos) { | 239 ZoneGrowableArray<Instruction*>* FindInstructionsAt(intptr_t token_pos) { |
257 ZoneGrowableArray<Instruction*>* instructions = | 240 ZoneGrowableArray<Instruction*>* instructions = |
258 new ZoneGrowableArray<Instruction*>(); | 241 new ZoneGrowableArray<Instruction*>(); |
259 for (intptr_t i = 0; i < blocks_->length(); i++) { | 242 for (intptr_t i = 0; i < blocks_->length(); i++) { |
260 BlockEntryInstr* entry = (*blocks_)[i]; | 243 BlockEntryInstr* entry = (*blocks_)[i]; |
261 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 244 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
262 Instruction* instr = it.Current(); | 245 Instruction* instr = it.Current(); |
263 if (instr->token_pos().value() == token_pos) { | 246 if (instr->token_pos().value() == token_pos) { |
264 instructions->Add(instr); | 247 instructions->Add(instr); |
265 } | 248 } |
266 } | 249 } |
267 } | 250 } |
268 return instructions; | 251 return instructions; |
269 } | 252 } |
270 | 253 |
271 RawFunction* GetFunction(const Library& lib, const char* name) { | 254 RawFunction* GetFunction(const Library& lib, const char* name) { |
272 const Function& result = Function::Handle(lib.LookupFunctionAllowPrivate( | 255 const Function& result = Function::Handle( |
273 String::Handle(String::New(name)))); | 256 lib.LookupFunctionAllowPrivate(String::Handle(String::New(name)))); |
274 EXPECT(!result.IsNull()); | 257 EXPECT(!result.IsNull()); |
275 return result.raw(); | 258 return result.raw(); |
276 } | 259 } |
277 | 260 |
278 RawFunction* GetFunction(const Class& cls, const char* name) { | 261 RawFunction* GetFunction(const Class& cls, const char* name) { |
279 const Function& result = Function::Handle(cls.LookupFunctionAllowPrivate( | 262 const Function& result = Function::Handle( |
280 String::Handle(String::New(name)))); | 263 cls.LookupFunctionAllowPrivate(String::Handle(String::New(name)))); |
281 EXPECT(!result.IsNull()); | 264 EXPECT(!result.IsNull()); |
282 return result.raw(); | 265 return result.raw(); |
283 } | 266 } |
284 | 267 |
285 RawClass* GetClass(const Library& lib, const char* name) { | 268 RawClass* GetClass(const Library& lib, const char* name) { |
286 const Class& cls = Class::Handle( | 269 const Class& cls = Class::Handle( |
287 lib.LookupClass(String::Handle(Symbols::New(thread_, name)))); | 270 lib.LookupClass(String::Handle(Symbols::New(thread_, name)))); |
288 EXPECT(!cls.IsNull()); // No ambiguity error expected. | 271 EXPECT(!cls.IsNull()); // No ambiguity error expected. |
289 return cls.raw(); | 272 return cls.raw(); |
290 } | 273 } |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 SourcePositionTest spt(thread, kScript); | 632 SourcePositionTest spt(thread, kScript); |
650 spt.BuildGraphFor("main"); | 633 spt.BuildGraphFor("main"); |
651 | 634 |
652 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); | 635 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); |
653 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); | 636 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); |
654 spt.FuzzyInstructionMatchAt("Constant(#Field", 4, 11); | 637 spt.FuzzyInstructionMatchAt("Constant(#Field", 4, 11); |
655 spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 11); | 638 spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 11); |
656 spt.FuzzyInstructionMatchAt("StoreLocal(:switch_expr", 4, 11); | 639 spt.FuzzyInstructionMatchAt("StoreLocal(:switch_expr", 4, 11); |
657 | 640 |
658 spt.FuzzyInstructionMatchAt("Constant(#1", 5, 10); | 641 spt.FuzzyInstructionMatchAt("Constant(#1", 5, 10); |
659 spt.FuzzyInstructionMatchAt("LoadLocal(:switch_expr", 5, 5); // 'c' | 642 spt.FuzzyInstructionMatchAt("LoadLocal(:switch_expr", 5, 5); // 'c' |
660 spt.InstanceCallAt(5, 10, Token::kEQ); // '1' | 643 spt.InstanceCallAt(5, 10, Token::kEQ); // '1' |
661 | 644 |
662 spt.FuzzyInstructionMatchAt("Constant(#3", 5, 20); // '3' | 645 spt.FuzzyInstructionMatchAt("Constant(#3", 5, 20); // '3' |
663 spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 13); | 646 spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 13); |
664 spt.FuzzyInstructionMatchAt("Return", 5, 13); | 647 spt.FuzzyInstructionMatchAt("Return", 5, 13); |
665 | 648 |
666 spt.FuzzyInstructionMatchAt("Constant(#2", 6, 10); | 649 spt.FuzzyInstructionMatchAt("Constant(#2", 6, 10); |
667 spt.FuzzyInstructionMatchAt("LoadLocal(:switch_expr", 6, 5); // 'c' | 650 spt.FuzzyInstructionMatchAt("LoadLocal(:switch_expr", 6, 5); // 'c' |
668 spt.InstanceCallAt(6, 10, Token::kEQ); // '2' | 651 spt.InstanceCallAt(6, 10, Token::kEQ); // '2' |
669 | 652 |
670 spt.FuzzyInstructionMatchAt("Constant(#4", 6, 20); // '4' | 653 spt.FuzzyInstructionMatchAt("Constant(#4", 6, 20); // '4' |
671 spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 13); | 654 spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 13); |
672 spt.FuzzyInstructionMatchAt("Return", 6, 13); | 655 spt.FuzzyInstructionMatchAt("Return", 6, 13); |
673 | 656 |
674 spt.FuzzyInstructionMatchAt("Constant(#5", 7, 21); // '5' | 657 spt.FuzzyInstructionMatchAt("Constant(#5", 7, 21); // '5' |
675 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 14); | 658 spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 14); |
676 spt.FuzzyInstructionMatchAt("Return", 7, 14); | 659 spt.FuzzyInstructionMatchAt("Return", 7, 14); |
677 | 660 |
678 spt.EnsureSourcePositions(); | 661 spt.EnsureSourcePositions(); |
679 } | 662 } |
680 | 663 |
681 | 664 |
682 TEST_CASE(SourcePosition_TryCatchFinally) { | 665 TEST_CASE(SourcePosition_TryCatchFinally) { |
683 const char* kScript = | 666 const char* kScript = |
684 "var x = 5;\n" | 667 "var x = 5;\n" |
685 "var y = 5;\n" | 668 "var y = 5;\n" |
686 "main() {\n" | 669 "main() {\n" |
687 " try {\n" | 670 " try {\n" |
688 " throw 'A';\n" | 671 " throw 'A';\n" |
689 " } catch (e) {\n" | 672 " } catch (e) {\n" |
690 " print(e);\n" | 673 " print(e);\n" |
691 " return 77;\n" | 674 " return 77;\n" |
692 " } finally {\n" | 675 " } finally {\n" |
693 " return 99;\n" | 676 " return 99;\n" |
694 " }\n" | 677 " }\n" |
695 "}\n"; | 678 "}\n"; |
696 | 679 |
697 SourcePositionTest spt(thread, kScript); | 680 SourcePositionTest spt(thread, kScript); |
698 spt.BuildGraphFor("main"); | 681 spt.BuildGraphFor("main"); |
699 | 682 |
700 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); | 683 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5); |
701 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); | 684 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5); |
702 | 685 |
703 spt.FuzzyInstructionMatchAt("LoadLocal(:current_context", 4, 3); // 't' | 686 spt.FuzzyInstructionMatchAt("LoadLocal(:current_context", 4, 3); // 't' |
704 spt.FuzzyInstructionMatchAt("StoreLocal(:saved_try_context", 4, 3); | 687 spt.FuzzyInstructionMatchAt("StoreLocal(:saved_try_context", 4, 3); |
705 | 688 |
706 spt.FuzzyInstructionMatchAt("Constant(#A", 5, 11); // 'A' | 689 spt.FuzzyInstructionMatchAt("Constant(#A", 5, 11); // 'A' |
707 spt.FuzzyInstructionMatchAt("Throw", 5, 5); // 't' | 690 spt.FuzzyInstructionMatchAt("Throw", 5, 5); // 't' |
708 | 691 |
709 spt.FuzzyInstructionMatchAt("LoadLocal(:saved_try_context", 6, 5); // 'c' | 692 spt.FuzzyInstructionMatchAt("LoadLocal(:saved_try_context", 6, 5); // 'c' |
710 spt.FuzzyInstructionMatchAt("StoreLocal(:current_context", 6, 5); // 'c' | 693 spt.FuzzyInstructionMatchAt("StoreLocal(:current_context", 6, 5); // 'c' |
711 spt.FuzzyInstructionMatchAt("LoadLocal(:exception_var", 6, 5); // 'c' | 694 spt.FuzzyInstructionMatchAt("LoadLocal(:exception_var", 6, 5); // 'c' |
712 spt.FuzzyInstructionMatchAt("StoreLocal(e", 6, 5); // 'c' | 695 spt.FuzzyInstructionMatchAt("StoreLocal(e", 6, 5); // 'c' |
713 | 696 |
714 spt.FuzzyInstructionMatchAt("LoadLocal(e", 7, 11); // 'e' | 697 spt.FuzzyInstructionMatchAt("LoadLocal(e", 7, 11); // 'e' |
715 | 698 |
716 spt.FuzzyInstructionMatchAt("StaticCall", 7, 5); // 'p' | 699 spt.FuzzyInstructionMatchAt("StaticCall", 7, 5); // 'p' |
717 | 700 |
718 spt.FuzzyInstructionMatchAt("Constant(#77", 8, 12); // '7' | 701 spt.FuzzyInstructionMatchAt("Constant(#77", 8, 12); // '7' |
719 spt.FuzzyInstructionMatchAt("StoreLocal(:finally_ret_val", 8, 5); // 'r' | 702 spt.FuzzyInstructionMatchAt("StoreLocal(:finally_ret_val", 8, 5); // 'r' |
720 | 703 |
721 spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12); // '9' | 704 spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12); // '9' |
722 spt.FuzzyInstructionMatchAt("Return", 10, 5); // 'r' | 705 spt.FuzzyInstructionMatchAt("Return", 10, 5); // 'r' |
723 | 706 |
724 spt.FuzzyInstructionMatchAt("LoadLocal(:saved_try_context", 9, 13); // '{' | 707 spt.FuzzyInstructionMatchAt("LoadLocal(:saved_try_context", 9, 13); // '{' |
725 spt.FuzzyInstructionMatchAt("StoreLocal(:current_context", 9, 13); // '{' | 708 spt.FuzzyInstructionMatchAt("StoreLocal(:current_context", 9, 13); // '{' |
726 | 709 |
727 spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12); // '9' | 710 spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12); // '9' |
728 spt.FuzzyInstructionMatchAt("Return", 10, 5); // 'r' | 711 spt.FuzzyInstructionMatchAt("Return", 10, 5); // 'r' |
729 | 712 |
730 spt.EnsureSourcePositions(); | 713 spt.EnsureSourcePositions(); |
731 } | 714 } |
732 | 715 |
733 | 716 |
734 TEST_CASE(SourcePosition_InstanceFields) { | 717 TEST_CASE(SourcePosition_InstanceFields) { |
735 const char* kScript = | 718 const char* kScript = |
736 "class A {\n" | 719 "class A {\n" |
737 " var x;\n" | 720 " var x;\n" |
738 " var y;\n" | 721 " var y;\n" |
739 "}\n" | 722 "}\n" |
740 "main() {\n" | 723 "main() {\n" |
741 " var z = new A();\n" | 724 " var z = new A();\n" |
742 " z.x = 99;\n" | 725 " z.x = 99;\n" |
743 " z.y = z.x;\n" | 726 " z.y = z.x;\n" |
744 " return z.y;\n" | 727 " return z.y;\n" |
745 "}\n"; | 728 "}\n"; |
746 | 729 |
747 SourcePositionTest spt(thread, kScript); | 730 SourcePositionTest spt(thread, kScript); |
748 spt.BuildGraphFor("main"); | 731 spt.BuildGraphFor("main"); |
749 spt.FuzzyInstructionMatchAt("AllocateObject(A)", 6, 15); // 'A' | 732 spt.FuzzyInstructionMatchAt("AllocateObject(A)", 6, 15); // 'A' |
750 spt.FuzzyInstructionMatchAt("StaticCall", 6, 15); // 'A' | 733 spt.FuzzyInstructionMatchAt("StaticCall", 6, 15); // 'A' |
751 spt.FuzzyInstructionMatchAt("StoreLocal(z", 6, 9); // '=' | 734 spt.FuzzyInstructionMatchAt("StoreLocal(z", 6, 9); // '=' |
752 spt.InstanceCallAt("set:x", 7, 5); // 'x' | 735 spt.InstanceCallAt("set:x", 7, 5); // 'x' |
753 spt.InstanceCallAt("get:x", 8, 11); // 'x' | 736 spt.InstanceCallAt("get:x", 8, 11); // 'x' |
754 spt.InstanceCallAt("set:y", 8, 5); // 'y' | 737 spt.InstanceCallAt("set:y", 8, 5); // 'y' |
755 | 738 |
756 spt.InstanceCallAt("get:y", 9, 12); // 'y' | 739 spt.InstanceCallAt("get:y", 9, 12); // 'y' |
757 spt.FuzzyInstructionMatchAt("DebugStepCheck", 9, 3); | 740 spt.FuzzyInstructionMatchAt("DebugStepCheck", 9, 3); |
758 spt.FuzzyInstructionMatchAt("Return", 9, 3); | 741 spt.FuzzyInstructionMatchAt("Return", 9, 3); |
759 | 742 |
760 spt.EnsureSourcePositions(); | 743 spt.EnsureSourcePositions(); |
761 } | 744 } |
762 | 745 |
763 | 746 |
764 TEST_CASE(SourcePosition_Async) { | 747 TEST_CASE(SourcePosition_Async) { |
765 const char* kScript = | 748 const char* kScript = |
766 "import 'dart:async';\n" | 749 "import 'dart:async';\n" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 EXPECT(TokenPosition(9).ToSynthetic().IsSynthetic()); | 784 EXPECT(TokenPosition(9).ToSynthetic().IsSynthetic()); |
802 EXPECT(!TokenPosition(-1).FromSynthetic().IsSynthetic()); | 785 EXPECT(!TokenPosition(-1).FromSynthetic().IsSynthetic()); |
803 EXPECT(!TokenPosition::kNoSource.IsSynthetic()); | 786 EXPECT(!TokenPosition::kNoSource.IsSynthetic()); |
804 EXPECT(!TokenPosition::kLast.IsSynthetic()); | 787 EXPECT(!TokenPosition::kLast.IsSynthetic()); |
805 EXPECT(SyntheticRoundTripTest(TokenPosition(0))); | 788 EXPECT(SyntheticRoundTripTest(TokenPosition(0))); |
806 EXPECT(SyntheticRoundTripTest(TokenPosition::kMaxSource)); | 789 EXPECT(SyntheticRoundTripTest(TokenPosition::kMaxSource)); |
807 EXPECT(SyntheticRoundTripTest(TokenPosition::kMinSource)); | 790 EXPECT(SyntheticRoundTripTest(TokenPosition::kMinSource)); |
808 } | 791 } |
809 | 792 |
810 } // namespace dart | 793 } // namespace dart |
811 | |
OLD | NEW |