| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { | 41 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { |
| 42 ASSERT(is_open()); | 42 ASSERT(is_open()); |
| 43 if (other_fragment.is_empty()) return; | 43 if (other_fragment.is_empty()) return; |
| 44 if (is_empty()) { | 44 if (is_empty()) { |
| 45 entry_ = other_fragment.entry(); | 45 entry_ = other_fragment.entry(); |
| 46 exit_ = other_fragment.exit(); | 46 exit_ = other_fragment.exit(); |
| 47 } else { | 47 } else { |
| 48 exit()->SetSuccessor(other_fragment.entry()); | 48 exit()->SetSuccessor(other_fragment.entry()); |
| 49 exit_ = other_fragment.exit(); | 49 exit_ = other_fragment.exit(); |
| 50 } | 50 } |
| 51 temp_index_ = other_fragment.temp_index(); |
| 51 } | 52 } |
| 52 | 53 |
| 53 | 54 |
| 54 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { | 55 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { |
| 55 ASSERT(is_open()); | 56 ASSERT(is_open()); |
| 57 DeallocateTempIndex(instruction->InputCount()); |
| 58 if (instruction->IsDefinition()) { |
| 59 instruction->AsDefinition()->set_temp_index(AllocateTempIndex()); |
| 60 } |
| 56 if (is_empty()) { | 61 if (is_empty()) { |
| 57 entry_ = exit_ = instruction; | 62 entry_ = exit_ = instruction; |
| 58 } else { | 63 } else { |
| 59 exit()->SetSuccessor(instruction); | 64 exit()->SetSuccessor(instruction); |
| 60 exit_ = instruction; | 65 exit_ = instruction; |
| 61 } | 66 } |
| 62 } | 67 } |
| 63 | 68 |
| 64 | 69 |
| 65 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, | 70 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 84 true_exit = true_fragment.is_empty() ? true_entry : true_fragment.exit(); | 89 true_exit = true_fragment.is_empty() ? true_entry : true_fragment.exit(); |
| 85 | 90 |
| 86 TargetEntryInstr* false_entry = new TargetEntryInstr(); | 91 TargetEntryInstr* false_entry = new TargetEntryInstr(); |
| 87 *test_fragment.false_successor_address() = false_entry; | 92 *test_fragment.false_successor_address() = false_entry; |
| 88 false_entry->SetSuccessor(false_fragment.entry()); | 93 false_entry->SetSuccessor(false_fragment.entry()); |
| 89 false_exit = false_fragment.is_empty() ? false_entry : false_fragment.exit(); | 94 false_exit = false_fragment.is_empty() ? false_entry : false_fragment.exit(); |
| 90 | 95 |
| 91 // 3. Add a join or select one (or neither) of the arms as exit. | 96 // 3. Add a join or select one (or neither) of the arms as exit. |
| 92 if (true_exit == NULL) { | 97 if (true_exit == NULL) { |
| 93 exit_ = false_exit; // May be NULL. | 98 exit_ = false_exit; // May be NULL. |
| 99 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); |
| 94 } else if (false_exit == NULL) { | 100 } else if (false_exit == NULL) { |
| 95 exit_ = true_exit; | 101 exit_ = true_exit; |
| 102 temp_index_ = true_fragment.temp_index(); |
| 96 } else { | 103 } else { |
| 97 exit_ = new JoinEntryInstr(); | 104 exit_ = new JoinEntryInstr(); |
| 98 true_exit->SetSuccessor(exit_); | 105 true_exit->SetSuccessor(exit_); |
| 99 false_exit->SetSuccessor(exit_); | 106 false_exit->SetSuccessor(exit_); |
| 107 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); |
| 108 temp_index_ = true_fragment.temp_index(); |
| 100 } | 109 } |
| 101 } | 110 } |
| 102 | 111 |
| 103 | 112 |
| 104 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, | 113 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, |
| 105 const EffectGraphVisitor& body_fragment) { | 114 const EffectGraphVisitor& body_fragment) { |
| 106 // We have: a test graph fragment with zero, one, or two available exits; | 115 // We have: a test graph fragment with zero, one, or two available exits; |
| 107 // and an effect graph fragment with zero or one available exits. We want | 116 // and an effect graph fragment with zero or one available exits. We want |
| 108 // to append the 'while loop' consisting of the test graph fragment as | 117 // to append the 'while loop' consisting of the test graph fragment as |
| 109 // condition and the effect graph fragment as body. | 118 // condition and the effect graph fragment as body. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 129 } | 138 } |
| 130 | 139 |
| 131 // 3. Set the exit to the graph to be the false successor of the test, a | 140 // 3. Set the exit to the graph to be the false successor of the test, a |
| 132 // fresh target node | 141 // fresh target node |
| 133 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); | 142 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); |
| 134 } | 143 } |
| 135 | 144 |
| 136 | 145 |
| 137 // Stores current context into the 'variable' | 146 // Stores current context into the 'variable' |
| 138 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) { | 147 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) { |
| 139 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); | 148 BindInstr* context = new BindInstr(new CurrentContextComp()); |
| 140 AddInstruction(context); | 149 AddInstruction(context); |
| 141 StoreLocalComp* store_context = | 150 StoreLocalComp* store_context = |
| 142 new StoreLocalComp(variable, new UseVal(context), | 151 new StoreLocalComp(variable, new UseVal(context), |
| 143 owner()->context_level()); | 152 owner()->context_level()); |
| 144 AddInstruction(new DoInstr(store_context)); | 153 AddInstruction(new DoInstr(store_context)); |
| 145 } | 154 } |
| 146 | 155 |
| 147 | 156 |
| 148 // Loads context saved in 'context_variable' into the current context. | 157 // Loads context saved in 'context_variable' into the current context. |
| 149 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { | 158 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { |
| 150 BindInstr* load_saved_context = | 159 BindInstr* load_saved_context = |
| 151 new BindInstr(temp_index(), | 160 new BindInstr(new LoadLocalComp(variable, owner()->context_level())); |
| 152 new LoadLocalComp(variable, owner()->context_level())); | |
| 153 AddInstruction(load_saved_context); | 161 AddInstruction(load_saved_context); |
| 154 DoInstr* store_context = | 162 DoInstr* store_context = |
| 155 new DoInstr(new StoreContextComp(new UseVal(load_saved_context))); | 163 new DoInstr(new StoreContextComp(new UseVal(load_saved_context))); |
| 156 AddInstruction(store_context); | 164 AddInstruction(store_context); |
| 157 } | 165 } |
| 158 | 166 |
| 159 | 167 |
| 160 | 168 |
| 161 void TestGraphVisitor::ReturnValue(Value* value) { | 169 void TestGraphVisitor::ReturnValue(Value* value) { |
| 162 if (FLAG_enable_type_checks) { | 170 if (FLAG_enable_type_checks) { |
| 163 BindInstr* assert_boolean = | 171 BindInstr* assert_boolean = |
| 164 new BindInstr(temp_index(), | 172 new BindInstr(new AssertBooleanComp(condition_token_index(), |
| 165 new AssertBooleanComp(condition_token_index(), | |
| 166 owner()->try_index(), | 173 owner()->try_index(), |
| 167 value)); | 174 value)); |
| 168 AddInstruction(assert_boolean); | 175 AddInstruction(assert_boolean); |
| 169 value = new UseVal(assert_boolean); | 176 value = new UseVal(assert_boolean); |
| 170 } | 177 } |
| 171 BranchInstr* branch = new BranchInstr(value); | 178 BranchInstr* branch = new BranchInstr(value); |
| 172 AddInstruction(branch); | 179 AddInstruction(branch); |
| 173 CloseFragment(); | 180 CloseFragment(); |
| 174 true_successor_address_ = branch->true_successor_address(); | 181 true_successor_address_ = branch->true_successor_address(); |
| 175 false_successor_address_ = branch->false_successor_address(); | 182 false_successor_address_ = branch->false_successor_address(); |
| 176 } | 183 } |
| 177 | 184 |
| 178 | 185 |
| 179 void EffectGraphVisitor::Bailout(const char* reason) { | 186 void EffectGraphVisitor::Bailout(const char* reason) { |
| 180 owner()->Bailout(reason); | 187 owner()->Bailout(reason); |
| 181 } | 188 } |
| 182 | 189 |
| 183 | 190 |
| 184 // <Statement> ::= Return { value: <Expression> | 191 // <Statement> ::= Return { value: <Expression> |
| 185 // inlined_finally_list: <InlinedFinally>* } | 192 // inlined_finally_list: <InlinedFinally>* } |
| 186 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { | 193 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| 187 ValueGraphVisitor for_value(owner(), temp_index()); | 194 ValueGraphVisitor for_value(owner(), temp_index()); |
| 188 node->value()->Visit(&for_value); | 195 node->value()->Visit(&for_value); |
| 189 Append(for_value); | 196 Append(for_value); |
| 190 | 197 |
| 191 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 198 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 192 EffectGraphVisitor for_effect(owner(), for_value.temp_index()); | 199 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 193 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 200 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 194 Append(for_effect); | 201 Append(for_effect); |
| 195 if (!is_open()) return; | 202 if (!is_open()) return; |
| 196 } | 203 } |
| 197 | 204 |
| 198 Value* return_value = for_value.value(); | 205 Value* return_value = for_value.value(); |
| 199 if (FLAG_enable_type_checks) { | 206 if (FLAG_enable_type_checks) { |
| 200 const RawFunction::Kind kind = owner()->parsed_function().function().kind(); | 207 const RawFunction::Kind kind = owner()->parsed_function().function().kind(); |
| 201 const bool is_implicit_getter = | 208 const bool is_implicit_getter = |
| 202 (kind == RawFunction::kImplicitGetter) || | 209 (kind == RawFunction::kImplicitGetter) || |
| 203 (kind == RawFunction::kConstImplicitGetter); | 210 (kind == RawFunction::kConstImplicitGetter); |
| 204 const bool is_static = owner()->parsed_function().function().is_static(); | 211 const bool is_static = owner()->parsed_function().function().is_static(); |
| 205 // Implicit getters do not need a type check at return, unless they compute | 212 // Implicit getters do not need a type check at return, unless they compute |
| 206 // the initial value of a static field. | 213 // the initial value of a static field. |
| 207 if (is_static || !is_implicit_getter) { | 214 if (is_static || !is_implicit_getter) { |
| 208 const AbstractType& dst_type = | 215 const AbstractType& dst_type = |
| 209 AbstractType::ZoneHandle( | 216 AbstractType::ZoneHandle( |
| 210 owner()->parsed_function().function().result_type()); | 217 owner()->parsed_function().function().result_type()); |
| 211 const String& dst_name = | 218 const String& dst_name = |
| 212 String::ZoneHandle(String::NewSymbol("function result")); | 219 String::ZoneHandle(String::NewSymbol("function result")); |
| 213 return_value = BuildAssignableValue(node->value(), | 220 return_value = BuildAssignableValue(node->value(), |
| 214 return_value, | 221 return_value, |
| 215 dst_type, | 222 dst_type, |
| 216 dst_name, | 223 dst_name); |
| 217 temp_index()); | |
| 218 } | 224 } |
| 219 } | 225 } |
| 220 | 226 |
| 221 intptr_t current_context_level = owner()->context_level(); | 227 intptr_t current_context_level = owner()->context_level(); |
| 222 ASSERT(current_context_level >= 0); | 228 ASSERT(current_context_level >= 0); |
| 223 if (owner()->parsed_function().saved_context_var() != NULL) { | 229 if (owner()->parsed_function().saved_context_var() != NULL) { |
| 224 // CTX on entry was saved, but not linked as context parent. | 230 // CTX on entry was saved, but not linked as context parent. |
| 225 BuildLoadContext(*owner()->parsed_function().saved_context_var()); | 231 BuildLoadContext(*owner()->parsed_function().saved_context_var()); |
| 226 } else { | 232 } else { |
| 227 while (current_context_level-- > 0) { | 233 while (current_context_level-- > 0) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 } | 317 } |
| 312 | 318 |
| 313 | 319 |
| 314 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 320 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 315 ValueGraphVisitor for_value(owner(), temp_index()); | 321 ValueGraphVisitor for_value(owner(), temp_index()); |
| 316 node->expr()->Visit(&for_value); | 322 node->expr()->Visit(&for_value); |
| 317 Append(for_value); | 323 Append(for_value); |
| 318 ReturnValue(BuildAssignableValue(node->expr(), | 324 ReturnValue(BuildAssignableValue(node->expr(), |
| 319 for_value.value(), | 325 for_value.value(), |
| 320 node->type(), | 326 node->type(), |
| 321 node->dst_name(), | 327 node->dst_name())); |
| 322 temp_index())); | |
| 323 } | 328 } |
| 324 | 329 |
| 325 | 330 |
| 326 // <Expression> :: BinaryOp { kind: Token::Kind | 331 // <Expression> :: BinaryOp { kind: Token::Kind |
| 327 // left: <Expression> | 332 // left: <Expression> |
| 328 // right: <Expression> } | 333 // right: <Expression> } |
| 329 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 334 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 330 // Operators "&&" and "||" cannot be overloaded therefore do not call | 335 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 331 // operator. | 336 // operator. |
| 332 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 337 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 333 // See ValueGraphVisitor::VisitBinaryOpNode. | 338 // See ValueGraphVisitor::VisitBinaryOpNode. |
| 334 TestGraphVisitor for_left(owner(), | 339 TestGraphVisitor for_left(owner(), |
| 335 temp_index(), | 340 temp_index(), |
| 336 node->left()->token_index()); | 341 node->left()->token_index()); |
| 337 node->left()->Visit(&for_left); | 342 node->left()->Visit(&for_left); |
| 338 EffectGraphVisitor for_right(owner(), temp_index()); | 343 EffectGraphVisitor for_right(owner(), temp_index()); |
| 339 node->right()->Visit(&for_right); | 344 node->right()->Visit(&for_right); |
| 340 EffectGraphVisitor empty(owner(), temp_index()); | 345 EffectGraphVisitor empty(owner(), temp_index()); |
| 341 if (node->kind() == Token::kAND) { | 346 if (node->kind() == Token::kAND) { |
| 342 Join(for_left, for_right, empty); | 347 Join(for_left, for_right, empty); |
| 343 } else { | 348 } else { |
| 344 Join(for_left, empty, for_right); | 349 Join(for_left, empty, for_right); |
| 345 } | 350 } |
| 346 return; | 351 return; |
| 347 } | 352 } |
| 348 ValueGraphVisitor for_left_value(owner(), temp_index()); | 353 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 349 node->left()->Visit(&for_left_value); | 354 node->left()->Visit(&for_left_value); |
| 350 Append(for_left_value); | 355 Append(for_left_value); |
| 351 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 356 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 352 node->right()->Visit(&for_right_value); | 357 node->right()->Visit(&for_right_value); |
| 353 Append(for_right_value); | 358 Append(for_right_value); |
| 354 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 359 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 355 arguments->Add(for_left_value.value()); | 360 arguments->Add(for_left_value.value()); |
| 356 arguments->Add(for_right_value.value()); | 361 arguments->Add(for_right_value.value()); |
| 357 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); | 362 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 358 InstanceCallComp* call = new InstanceCallComp(node->token_index(), | 363 InstanceCallComp* call = new InstanceCallComp(node->token_index(), |
| 359 owner()->try_index(), | 364 owner()->try_index(), |
| 360 name, | 365 name, |
| 361 arguments, | 366 arguments, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 380 TestGraphVisitor for_test(owner(), | 385 TestGraphVisitor for_test(owner(), |
| 381 temp_index(), | 386 temp_index(), |
| 382 node->left()->token_index()); | 387 node->left()->token_index()); |
| 383 node->left()->Visit(&for_test); | 388 node->left()->Visit(&for_test); |
| 384 | 389 |
| 385 ValueGraphVisitor for_right(owner(), temp_index()); | 390 ValueGraphVisitor for_right(owner(), temp_index()); |
| 386 node->right()->Visit(&for_right); | 391 node->right()->Visit(&for_right); |
| 387 Value* right_value = for_right.value(); | 392 Value* right_value = for_right.value(); |
| 388 if (FLAG_enable_type_checks) { | 393 if (FLAG_enable_type_checks) { |
| 389 BindInstr* assert_boolean = | 394 BindInstr* assert_boolean = |
| 390 new BindInstr(temp_index(), | 395 new BindInstr(new AssertBooleanComp(node->right()->token_index(), |
| 391 new AssertBooleanComp(node->right()->token_index(), | |
| 392 owner()->try_index(), | 396 owner()->try_index(), |
| 393 right_value)); | 397 right_value)); |
| 394 for_right.AddInstruction(assert_boolean); | 398 for_right.AddInstruction(assert_boolean); |
| 395 right_value = new UseVal(assert_boolean); | 399 right_value = new UseVal(assert_boolean); |
| 396 } | 400 } |
| 397 BindInstr* constant_true = | 401 BindInstr* constant_true = new BindInstr(new ConstantVal(bool_true)); |
| 398 new BindInstr(temp_index(), new ConstantVal(bool_true)); | |
| 399 for_right.AddInstruction(constant_true); | 402 for_right.AddInstruction(constant_true); |
| 400 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT, | 403 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT, |
| 401 right_value, new UseVal(constant_true)); | 404 right_value, new UseVal(constant_true)); |
| 402 for_right.AddInstruction(new BindInstr(temp_index(), comp)); | 405 for_right.AddInstruction(new BindInstr(comp)); |
| 403 | 406 |
| 404 if (node->kind() == Token::kAND) { | 407 if (node->kind() == Token::kAND) { |
| 405 ValueGraphVisitor for_false(owner(), temp_index()); | 408 ValueGraphVisitor for_false(owner(), temp_index()); |
| 406 for_false.ReturnComputation(new ConstantVal(bool_false)); | 409 for_false.ReturnComputation(new ConstantVal(bool_false)); |
| 407 Join(for_test, for_right, for_false); | 410 Join(for_test, for_right, for_false); |
| 408 } else { | 411 } else { |
| 409 ASSERT(node->kind() == Token::kOR); | 412 ASSERT(node->kind() == Token::kOR); |
| 410 ValueGraphVisitor for_true(owner(), temp_index()); | 413 ValueGraphVisitor for_true(owner(), temp_index()); |
| 411 for_true.ReturnComputation(new ConstantVal(bool_true)); | 414 for_true.ReturnComputation(new ConstantVal(bool_true)); |
| 412 Join(for_test, for_true, for_right); | 415 Join(for_test, for_true, for_right); |
| 413 } | 416 } |
| 414 ReturnValue(new TempVal(AllocateTempIndex())); | 417 ReturnValue(new TempVal(temp_index() - 1)); |
| 415 return; | 418 return; |
| 416 } | 419 } |
| 417 EffectGraphVisitor::VisitBinaryOpNode(node); | 420 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 418 } | 421 } |
| 419 | 422 |
| 420 | 423 |
| 421 void EffectGraphVisitor::CompiletimeStringInterpolation( | 424 void EffectGraphVisitor::CompiletimeStringInterpolation( |
| 422 const Function& interpol_func, const Array& literals) { | 425 const Function& interpol_func, const Array& literals) { |
| 423 // Do nothing. | 426 // Do nothing. |
| 424 } | 427 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 } | 480 } |
| 478 if (compile_time_interpolation) { | 481 if (compile_time_interpolation) { |
| 479 // Not needed for effect, only for value | 482 // Not needed for effect, only for value |
| 480 CompiletimeStringInterpolation(interpol_func, literals); | 483 CompiletimeStringInterpolation(interpol_func, literals); |
| 481 return; | 484 return; |
| 482 } | 485 } |
| 483 // Runtime string interpolation. | 486 // Runtime string interpolation. |
| 484 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); | 487 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); |
| 485 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); | 488 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); |
| 486 interpol_arg->Add(node->values()); | 489 interpol_arg->Add(node->values()); |
| 487 TranslateArgumentList(*interpol_arg, temp_index(), values); | 490 TranslateArgumentList(*interpol_arg, values); |
| 488 StaticCallComp* call = | 491 StaticCallComp* call = |
| 489 new StaticCallComp(node->token_index(), | 492 new StaticCallComp(node->token_index(), |
| 490 owner()->try_index(), | 493 owner()->try_index(), |
| 491 interpol_func, | 494 interpol_func, |
| 492 interpol_arg->names(), | 495 interpol_arg->names(), |
| 493 values); | 496 values); |
| 494 ReturnComputation(call); | 497 ReturnComputation(call); |
| 495 } | 498 } |
| 496 | 499 |
| 497 | 500 |
| 498 void EffectGraphVisitor::BuildAssertAssignable(intptr_t token_index, | 501 void EffectGraphVisitor::BuildAssertAssignable(intptr_t token_index, |
| 499 Value* value, | 502 Value* value, |
| 500 const AbstractType& dst_type, | 503 const AbstractType& dst_type, |
| 501 const String& dst_name, | 504 const String& dst_name) { |
| 502 intptr_t start_index) { | |
| 503 // Build the type check computation. | 505 // Build the type check computation. |
| 504 Value* instantiator_type_arguments = NULL; | 506 Value* instantiator_type_arguments = NULL; |
| 505 if (!dst_type.IsInstantiated()) { | 507 if (!dst_type.IsInstantiated()) { |
| 506 instantiator_type_arguments = | 508 instantiator_type_arguments = |
| 507 BuildInstantiatorTypeArguments(token_index, start_index + 1); | 509 BuildInstantiatorTypeArguments(token_index); |
| 508 } | 510 } |
| 509 AssertAssignableComp* assert_assignable = | 511 AssertAssignableComp* assert_assignable = |
| 510 new AssertAssignableComp(token_index, | 512 new AssertAssignableComp(token_index, |
| 511 owner()->try_index(), | 513 owner()->try_index(), |
| 512 value, | 514 value, |
| 513 instantiator_type_arguments, | 515 instantiator_type_arguments, |
| 514 dst_type, | 516 dst_type, |
| 515 dst_name); | 517 dst_name); |
| 516 AddInstruction(new DoInstr(assert_assignable)); | 518 AddInstruction(new DoInstr(assert_assignable)); |
| 517 } | 519 } |
| 518 | 520 |
| 519 | 521 |
| 520 Value* EffectGraphVisitor::BuildAssignableValue(AstNode* value_node, | 522 Value* EffectGraphVisitor::BuildAssignableValue(AstNode* value_node, |
| 521 Value* value, | 523 Value* value, |
| 522 const AbstractType& dst_type, | 524 const AbstractType& dst_type, |
| 523 const String& dst_name, | 525 const String& dst_name) { |
| 524 intptr_t start_index) { | |
| 525 if (CanSkipTypeCheck(value_node, dst_type)) { | 526 if (CanSkipTypeCheck(value_node, dst_type)) { |
| 526 return value; | 527 return value; |
| 527 } | 528 } |
| 528 | 529 |
| 529 // Build the type check computation. | 530 // Build the type check computation. |
| 530 Value* instantiator_type_arguments = NULL; | 531 Value* instantiator_type_arguments = NULL; |
| 531 if (!dst_type.IsInstantiated()) { | 532 if (!dst_type.IsInstantiated()) { |
| 532 instantiator_type_arguments = | 533 instantiator_type_arguments = |
| 533 BuildInstantiatorTypeArguments(value_node->token_index(), | 534 BuildInstantiatorTypeArguments(value_node->token_index()); |
| 534 start_index + 1); | |
| 535 } | 535 } |
| 536 BindInstr* assert_assignable = | 536 BindInstr* assert_assignable = |
| 537 new BindInstr(start_index, | 537 new BindInstr(new AssertAssignableComp(value_node->token_index(), |
| 538 new AssertAssignableComp(value_node->token_index(), | |
| 539 owner()->try_index(), | 538 owner()->try_index(), |
| 540 value, | 539 value, |
| 541 instantiator_type_arguments, | 540 instantiator_type_arguments, |
| 542 dst_type, | 541 dst_type, |
| 543 dst_name)); | 542 dst_name)); |
| 544 AddInstruction(assert_assignable); | 543 AddInstruction(assert_assignable); |
| 545 return new UseVal(assert_assignable); | 544 return new UseVal(assert_assignable); |
| 546 } | 545 } |
| 547 | 546 |
| 548 | 547 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 ReturnComputation(result); | 601 ReturnComputation(result); |
| 603 return; | 602 return; |
| 604 } | 603 } |
| 605 | 604 |
| 606 ValueGraphVisitor for_left_value(owner(), temp_index()); | 605 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 607 node->left()->Visit(&for_left_value); | 606 node->left()->Visit(&for_left_value); |
| 608 Append(for_left_value); | 607 Append(for_left_value); |
| 609 Value* type_arguments = NULL; | 608 Value* type_arguments = NULL; |
| 610 if (!type.IsInstantiated()) { | 609 if (!type.IsInstantiated()) { |
| 611 type_arguments = | 610 type_arguments = |
| 612 BuildInstantiatorTypeArguments(node->token_index(), | 611 BuildInstantiatorTypeArguments(node->token_index()); |
| 613 for_left_value.temp_index()); | |
| 614 } | 612 } |
| 615 InstanceOfComp* instance_of = | 613 InstanceOfComp* instance_of = |
| 616 new InstanceOfComp(node->token_index(), | 614 new InstanceOfComp(node->token_index(), |
| 617 owner()->try_index(), | 615 owner()->try_index(), |
| 618 for_left_value.value(), | 616 for_left_value.value(), |
| 619 type_arguments, | 617 type_arguments, |
| 620 node->right()->AsTypeNode()->type(), | 618 node->right()->AsTypeNode()->type(), |
| 621 (node->kind() == Token::kISNOT)); | 619 (node->kind() == Token::kISNOT)); |
| 622 ReturnComputation(instance_of); | 620 ReturnComputation(instance_of); |
| 623 } | 621 } |
| 624 | 622 |
| 625 | 623 |
| 626 // <Expression> :: Comparison { kind: Token::Kind | 624 // <Expression> :: Comparison { kind: Token::Kind |
| 627 // left: <Expression> | 625 // left: <Expression> |
| 628 // right: <Expression> } | 626 // right: <Expression> } |
| 629 // TODO(srdjan): Implement new equality. | 627 // TODO(srdjan): Implement new equality. |
| 630 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 628 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 631 if (Token::IsInstanceofOperator(node->kind())) { | 629 if (Token::IsInstanceofOperator(node->kind())) { |
| 632 BuildInstanceOf(node); | 630 BuildInstanceOf(node); |
| 633 return; | 631 return; |
| 634 } | 632 } |
| 635 if ((node->kind() == Token::kEQ_STRICT) || | 633 if ((node->kind() == Token::kEQ_STRICT) || |
| 636 (node->kind() == Token::kNE_STRICT)) { | 634 (node->kind() == Token::kNE_STRICT)) { |
| 637 ValueGraphVisitor for_left_value(owner(), temp_index()); | 635 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 638 node->left()->Visit(&for_left_value); | 636 node->left()->Visit(&for_left_value); |
| 639 Append(for_left_value); | 637 Append(for_left_value); |
| 640 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 638 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 641 node->right()->Visit(&for_right_value); | 639 node->right()->Visit(&for_right_value); |
| 642 Append(for_right_value); | 640 Append(for_right_value); |
| 643 StrictCompareComp* comp = new StrictCompareComp( | 641 StrictCompareComp* comp = new StrictCompareComp( |
| 644 node->kind(), for_left_value.value(), for_right_value.value()); | 642 node->kind(), for_left_value.value(), for_right_value.value()); |
| 645 ReturnComputation(comp); | 643 ReturnComputation(comp); |
| 646 return; | 644 return; |
| 647 } | 645 } |
| 648 | 646 |
| 649 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { | 647 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { |
| 650 ValueGraphVisitor for_left_value(owner(), temp_index()); | 648 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 651 node->left()->Visit(&for_left_value); | 649 node->left()->Visit(&for_left_value); |
| 652 Append(for_left_value); | 650 Append(for_left_value); |
| 653 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 651 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 654 node->right()->Visit(&for_right_value); | 652 node->right()->Visit(&for_right_value); |
| 655 Append(for_right_value); | 653 Append(for_right_value); |
| 656 EqualityCompareComp* comp = new EqualityCompareComp( | 654 EqualityCompareComp* comp = new EqualityCompareComp( |
| 657 node->token_index(), owner()->try_index(), | 655 node->token_index(), owner()->try_index(), |
| 658 for_left_value.value(), for_right_value.value()); | 656 for_left_value.value(), for_right_value.value()); |
| 659 if (node->kind() == Token::kEQ) { | 657 if (node->kind() == Token::kEQ) { |
| 660 ReturnComputation(comp); | 658 ReturnComputation(comp); |
| 661 } else { | 659 } else { |
| 662 Definition* eq_result = new BindInstr(temp_index(), comp); | 660 Definition* eq_result = new BindInstr(comp); |
| 663 AddInstruction(eq_result); | 661 AddInstruction(eq_result); |
| 664 if (FLAG_enable_type_checks) { | 662 if (FLAG_enable_type_checks) { |
| 665 eq_result = | 663 eq_result = |
| 666 new BindInstr(temp_index(), | 664 new BindInstr(new AssertBooleanComp(node->token_index(), |
| 667 new AssertBooleanComp(node->token_index(), | |
| 668 owner()->try_index(), | 665 owner()->try_index(), |
| 669 new UseVal(eq_result))); | 666 new UseVal(eq_result))); |
| 670 AddInstruction(eq_result); | 667 AddInstruction(eq_result); |
| 671 } | 668 } |
| 672 BooleanNegateComp* negate = new BooleanNegateComp(new UseVal(eq_result)); | 669 BooleanNegateComp* negate = new BooleanNegateComp(new UseVal(eq_result)); |
| 673 ReturnComputation(negate); | 670 ReturnComputation(negate); |
| 674 } | 671 } |
| 675 return; | 672 return; |
| 676 } | 673 } |
| 677 | 674 |
| 678 ValueGraphVisitor for_left_value(owner(), temp_index()); | 675 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 679 node->left()->Visit(&for_left_value); | 676 node->left()->Visit(&for_left_value); |
| 680 Append(for_left_value); | 677 Append(for_left_value); |
| 681 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 678 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 682 node->right()->Visit(&for_right_value); | 679 node->right()->Visit(&for_right_value); |
| 683 Append(for_right_value); | 680 Append(for_right_value); |
| 684 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 681 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 685 arguments->Add(for_left_value.value()); | 682 arguments->Add(for_left_value.value()); |
| 686 arguments->Add(for_right_value.value()); | 683 arguments->Add(for_right_value.value()); |
| 687 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); | 684 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 688 InstanceCallComp* call = new InstanceCallComp( | 685 InstanceCallComp* call = new InstanceCallComp( |
| 689 node->token_index(), owner()->try_index(), name, | 686 node->token_index(), owner()->try_index(), name, |
| 690 arguments, Array::ZoneHandle(), 2); | 687 arguments, Array::ZoneHandle(), 2); |
| 691 ReturnComputation(call); | 688 ReturnComputation(call); |
| 692 } | 689 } |
| 693 | 690 |
| 694 | 691 |
| 695 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 692 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| 696 // "!" cannot be overloaded, therefore do not call operator. | 693 // "!" cannot be overloaded, therefore do not call operator. |
| 697 if (node->kind() == Token::kNOT) { | 694 if (node->kind() == Token::kNOT) { |
| 698 ValueGraphVisitor for_value(owner(), temp_index()); | 695 ValueGraphVisitor for_value(owner(), temp_index()); |
| 699 node->operand()->Visit(&for_value); | 696 node->operand()->Visit(&for_value); |
| 700 Append(for_value); | 697 Append(for_value); |
| 701 Value* value = for_value.value(); | 698 Value* value = for_value.value(); |
| 702 if (FLAG_enable_type_checks) { | 699 if (FLAG_enable_type_checks) { |
| 703 BindInstr* assert_boolean = | 700 BindInstr* assert_boolean = |
| 704 new BindInstr(temp_index(), | 701 new BindInstr(new AssertBooleanComp(node->operand()->token_index(), |
| 705 new AssertBooleanComp(node->operand()->token_index(), | |
| 706 owner()->try_index(), | 702 owner()->try_index(), |
| 707 value)); | 703 value)); |
| 708 AddInstruction(assert_boolean); | 704 AddInstruction(assert_boolean); |
| 709 value = new UseVal(assert_boolean); | 705 value = new UseVal(assert_boolean); |
| 710 } | 706 } |
| 711 BooleanNegateComp* negate = new BooleanNegateComp(value); | 707 BooleanNegateComp* negate = new BooleanNegateComp(value); |
| 712 ReturnComputation(negate); | 708 ReturnComputation(negate); |
| 713 return; | 709 return; |
| 714 } | 710 } |
| 715 ValueGraphVisitor for_value(owner(), temp_index()); | 711 ValueGraphVisitor for_value(owner(), temp_index()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 728 } | 724 } |
| 729 | 725 |
| 730 | 726 |
| 731 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { | 727 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
| 732 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 728 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 733 // In an effect context, treat postincrement as if it were preincrement | 729 // In an effect context, treat postincrement as if it were preincrement |
| 734 // because its value is not needed. | 730 // because its value is not needed. |
| 735 | 731 |
| 736 // 1. Load the value. | 732 // 1. Load the value. |
| 737 BindInstr* load = | 733 BindInstr* load = |
| 738 new BindInstr(temp_index(), | 734 new BindInstr(new LoadLocalComp(node->local(), owner()->context_level())); |
| 739 new LoadLocalComp(node->local(), owner()->context_level())); | |
| 740 AddInstruction(load); | 735 AddInstruction(load); |
| 741 AllocateTempIndex(); | |
| 742 // 2. Increment. | 736 // 2. Increment. |
| 743 Definition* incr = | 737 Definition* incr = |
| 744 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); | 738 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); |
| 745 // 3. Perform the store, resulting in the new value. | 739 // 3. Perform the store, resulting in the new value. |
| 746 DeallocateTempIndex(); // Consuming incr. | |
| 747 StoreLocalComp* store = new StoreLocalComp( | 740 StoreLocalComp* store = new StoreLocalComp( |
| 748 node->local(), new UseVal(incr), owner()->context_level()); | 741 node->local(), new UseVal(incr), owner()->context_level()); |
| 749 ReturnComputation(store); | 742 ReturnComputation(store); |
| 750 } | 743 } |
| 751 | 744 |
| 752 | 745 |
| 753 void ValueGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { | 746 void ValueGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
| 754 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 747 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 755 if (node->prefix()) { | 748 if (node->prefix()) { |
| 756 // Base class handles preincrement. | 749 // Base class handles preincrement. |
| 757 EffectGraphVisitor::VisitIncrOpLocalNode(node); | 750 EffectGraphVisitor::VisitIncrOpLocalNode(node); |
| 758 return; | 751 return; |
| 759 } | 752 } |
| 760 // For postincrement, duplicate the original value to use one copy as the | 753 // For postincrement, duplicate the original value to use one copy as the |
| 761 // result. | 754 // result. |
| 762 // | 755 // |
| 763 // 1. Load the value. | 756 // 1. Load the value. |
| 764 BindInstr* load = | 757 BindInstr* load = |
| 765 new BindInstr(temp_index(), | 758 new BindInstr(new LoadLocalComp(node->local(), owner()->context_level())); |
| 766 new LoadLocalComp(node->local(), owner()->context_level())); | |
| 767 AddInstruction(load); | 759 AddInstruction(load); |
| 768 AllocateTempIndex(); | |
| 769 // 2. Duplicate it to increment. | 760 // 2. Duplicate it to increment. |
| 770 PickTempInstr* duplicate = | 761 PickTempInstr* duplicate = new PickTempInstr(load->temp_index()); |
| 771 new PickTempInstr(temp_index(), load->temp_index()); | |
| 772 AddInstruction(duplicate); | 762 AddInstruction(duplicate); |
| 773 AllocateTempIndex(); | |
| 774 // 3. Increment. | 763 // 3. Increment. |
| 775 Definition* incr = | 764 Definition* incr = |
| 776 BuildIncrOpIncrement(node->kind(), node->token_index(), | 765 BuildIncrOpIncrement(node->kind(), node->token_index(), |
| 777 new UseVal(duplicate)); | 766 new UseVal(duplicate)); |
| 778 // 4. Perform the store and return the original value. | 767 // 4. Perform the store and return the original value. |
| 779 DeallocateTempIndex(); // Consuming incr. | |
| 780 StoreLocalComp* store = new StoreLocalComp( | 768 StoreLocalComp* store = new StoreLocalComp( |
| 781 node->local(), new UseVal(incr), owner()->context_level()); | 769 node->local(), new UseVal(incr), owner()->context_level()); |
| 782 AddInstruction(new DoInstr(store)); | 770 AddInstruction(new DoInstr(store)); |
| 783 ReturnValue(new UseVal(load)); | 771 ReturnValue(new UseVal(load)); |
| 784 } | 772 } |
| 785 | 773 |
| 786 | 774 |
| 787 Definition* EffectGraphVisitor::BuildIncrOpFieldLoad( | 775 Definition* EffectGraphVisitor::BuildIncrOpFieldLoad( |
| 788 IncrOpInstanceFieldNode* node, | 776 IncrOpInstanceFieldNode* node, |
| 789 Value** receiver) { | 777 Value** receiver) { |
| 790 // Evaluate the receiver and duplicate it (it has two uses). | 778 // Evaluate the receiver and duplicate it (it has two uses). |
| 791 // t_n <- ... receiver ... | 779 // t_n <- ... receiver ... |
| 792 // t_n+1 <- Pick(t_n) | 780 // t_n+1 <- Pick(t_n) |
| 793 ValueGraphVisitor for_receiver(owner(), temp_index()); | 781 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 794 node->receiver()->Visit(&for_receiver); | 782 node->receiver()->Visit(&for_receiver); |
| 795 Append(for_receiver); | 783 Append(for_receiver); |
| 796 AllocateTempIndex(); | |
| 797 ASSERT(temp_index() == for_receiver.temp_index()); | 784 ASSERT(temp_index() == for_receiver.temp_index()); |
| 798 PickTempInstr* duplicate = | 785 PickTempInstr* duplicate = new PickTempInstr(temp_index() - 1); |
| 799 new PickTempInstr(temp_index(), temp_index() - 1); | |
| 800 AddInstruction(duplicate); | 786 AddInstruction(duplicate); |
| 801 | 787 |
| 802 // Load the value. | 788 // Load the value. |
| 803 // t_n+1 <- InstanceCall(get:name, t_n+1) | 789 // t_n+1 <- InstanceCall(get:name, t_n+1) |
| 804 const String& getter_name = | 790 const String& getter_name = |
| 805 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 791 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 806 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); | 792 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
| 807 arguments->Add(new UseVal(duplicate)); | 793 arguments->Add(new UseVal(duplicate)); |
| 808 BindInstr* load = | 794 BindInstr* load = |
| 809 new BindInstr(temp_index(), | 795 new BindInstr(new InstanceCallComp( |
| 810 new InstanceCallComp( | |
| 811 node->token_index(), | 796 node->token_index(), |
| 812 owner()->try_index(), getter_name, arguments, | 797 owner()->try_index(), getter_name, arguments, |
| 813 Array::ZoneHandle(), 1)); | 798 Array::ZoneHandle(), 1)); |
| 814 AddInstruction(load); | 799 AddInstruction(load); |
| 815 AllocateTempIndex(); | |
| 816 | 800 |
| 817 *receiver = for_receiver.value(); | 801 *receiver = for_receiver.value(); |
| 818 return load; | 802 return load; |
| 819 } | 803 } |
| 820 | 804 |
| 821 | 805 |
| 822 Definition* EffectGraphVisitor::BuildIncrOpIncrement(Token::Kind kind, | 806 Definition* EffectGraphVisitor::BuildIncrOpIncrement(Token::Kind kind, |
| 823 intptr_t token_index, | 807 intptr_t token_index, |
| 824 Value* original) { | 808 Value* original) { |
| 825 ASSERT((kind == Token::kINCR) || (kind == Token::kDECR)); | 809 ASSERT((kind == Token::kINCR) || (kind == Token::kDECR)); |
| 826 // Assumed that t_n-1 (where n is start_index) is the field value. | 810 // Assumed that t_n-1 (where n is start_index) is the field value. |
| 827 // t_n <- #1 | 811 // t_n <- #1 |
| 828 // t_n-1 <- InstanceCall(op, t_n-1, t_n) | 812 // t_n-1 <- InstanceCall(op, t_n-1, t_n) |
| 829 BindInstr* one = | 813 BindInstr* one = |
| 830 new BindInstr(temp_index(), | 814 new BindInstr(new ConstantVal(Smi::ZoneHandle(Smi::New(1)))); |
| 831 new ConstantVal(Smi::ZoneHandle(Smi::New(1)))); | |
| 832 AddInstruction(one); | 815 AddInstruction(one); |
| 833 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 816 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 834 arguments->Add(original); | 817 arguments->Add(original); |
| 835 arguments->Add(new UseVal(one)); | 818 arguments->Add(new UseVal(one)); |
| 836 const String& op_name = | 819 const String& op_name = |
| 837 String::ZoneHandle(String::NewSymbol((kind == Token::kINCR) ? "+" : "-")); | 820 String::ZoneHandle(String::NewSymbol((kind == Token::kINCR) ? "+" : "-")); |
| 838 DeallocateTempIndex(); // Consuming original. | |
| 839 BindInstr* add = | 821 BindInstr* add = |
| 840 new BindInstr(temp_index(), | 822 new BindInstr(new InstanceCallComp( |
| 841 new InstanceCallComp( | |
| 842 token_index, owner()->try_index(), op_name, | 823 token_index, owner()->try_index(), op_name, |
| 843 arguments, Array::ZoneHandle(), 2)); | 824 arguments, Array::ZoneHandle(), 2)); |
| 844 AddInstruction(add); | 825 AddInstruction(add); |
| 845 AllocateTempIndex(); | |
| 846 return add; | 826 return add; |
| 847 } | 827 } |
| 848 | 828 |
| 849 | 829 |
| 850 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode( | 830 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode( |
| 851 IncrOpInstanceFieldNode* node) { | 831 IncrOpInstanceFieldNode* node) { |
| 852 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 832 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 853 // In an effect context, treat postincrement as if it were preincrement | 833 // In an effect context, treat postincrement as if it were preincrement |
| 854 // because its value is not needed. | 834 // because its value is not needed. |
| 855 | 835 |
| 856 // 1. Load the value. | 836 // 1. Load the value. |
| 857 Value* receiver = NULL; | 837 Value* receiver = NULL; |
| 858 Definition* load = BuildIncrOpFieldLoad(node, &receiver); | 838 Definition* load = BuildIncrOpFieldLoad(node, &receiver); |
| 859 // 2. Increment. | 839 // 2. Increment. |
| 860 Definition* incr = | 840 Definition* incr = |
| 861 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); | 841 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); |
| 862 // 3. Perform the store, returning the stored value. | 842 // 3. Perform the store, returning the stored value. |
| 863 InstanceSetterComp* store = | 843 InstanceSetterComp* store = |
| 864 new InstanceSetterComp(node->token_index(), | 844 new InstanceSetterComp(node->token_index(), |
| 865 owner()->try_index(), | 845 owner()->try_index(), |
| 866 node->field_name(), | 846 node->field_name(), |
| 867 receiver, | 847 receiver, |
| 868 new UseVal(incr)); | 848 new UseVal(incr)); |
| 869 DeallocateTempIndex(); // Consuming incr. | |
| 870 DeallocateTempIndex(); // Consuming receiver. | |
| 871 ReturnComputation(store); | 849 ReturnComputation(store); |
| 872 } | 850 } |
| 873 | 851 |
| 874 | 852 |
| 875 void ValueGraphVisitor::VisitIncrOpInstanceFieldNode( | 853 void ValueGraphVisitor::VisitIncrOpInstanceFieldNode( |
| 876 IncrOpInstanceFieldNode* node) { | 854 IncrOpInstanceFieldNode* node) { |
| 877 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 855 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 878 if (node->prefix()) { | 856 if (node->prefix()) { |
| 879 // Base class handles preincrement. | 857 // Base class handles preincrement. |
| 880 EffectGraphVisitor::VisitIncrOpInstanceFieldNode(node); | 858 EffectGraphVisitor::VisitIncrOpInstanceFieldNode(node); |
| 881 return; | 859 return; |
| 882 } | 860 } |
| 883 // For postincrement, preallocate a temporary to preserve the original | 861 // For postincrement, preallocate a temporary to preserve the original |
| 884 // value. | 862 // value. |
| 885 // | 863 // |
| 886 // 1. Name a placeholder. | 864 // 1. Name a placeholder. |
| 887 BindInstr* placeholder = | 865 BindInstr* placeholder = |
| 888 new BindInstr(temp_index(), | 866 new BindInstr(new ConstantVal(Smi::ZoneHandle(Smi::New(0)))); |
| 889 new ConstantVal(Smi::ZoneHandle(Smi::New(0)))); | |
| 890 AddInstruction(placeholder); | 867 AddInstruction(placeholder); |
| 891 AllocateTempIndex(); | |
| 892 // 2. Load the value. | 868 // 2. Load the value. |
| 893 Value* receiver = NULL; | 869 Value* receiver = NULL; |
| 894 Definition* load = BuildIncrOpFieldLoad(node, &receiver); | 870 Definition* load = BuildIncrOpFieldLoad(node, &receiver); |
| 895 // 3. Preserve the original value. | 871 // 3. Preserve the original value. |
| 896 AddInstruction(new TuckTempInstr(placeholder->temp_index(), | 872 AddInstruction(new TuckTempInstr(placeholder->temp_index(), |
| 897 load->temp_index())); | 873 load->temp_index())); |
| 898 // 4. Increment. | 874 // 4. Increment. |
| 899 Definition* incr = | 875 Definition* incr = |
| 900 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); | 876 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); |
| 901 // 5. Perform the store and return the original value. | 877 // 5. Perform the store and return the original value. |
| 902 const String& setter_name = | 878 const String& setter_name = |
| 903 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 879 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 904 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 880 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 905 arguments->Add(receiver); | 881 arguments->Add(receiver); |
| 906 arguments->Add(new UseVal(incr)); | 882 arguments->Add(new UseVal(incr)); |
| 907 InstanceCallComp* store = new InstanceCallComp( | 883 InstanceCallComp* store = new InstanceCallComp( |
| 908 node->token_index(), owner()->try_index(), | 884 node->token_index(), owner()->try_index(), |
| 909 setter_name, arguments, Array::ZoneHandle(), 1); | 885 setter_name, arguments, Array::ZoneHandle(), 1); |
| 910 DeallocateTempIndex(); // Consuming incr. | |
| 911 DeallocateTempIndex(); // Consuming receiver. | |
| 912 AddInstruction(new DoInstr(store)); | 886 AddInstruction(new DoInstr(store)); |
| 913 ReturnValue(new UseVal(placeholder)); | 887 ReturnValue(new UseVal(placeholder)); |
| 914 } | 888 } |
| 915 | 889 |
| 916 | 890 |
| 917 Definition* EffectGraphVisitor::BuildIncrOpIndexedLoad( | 891 Definition* EffectGraphVisitor::BuildIncrOpIndexedLoad( |
| 918 IncrOpIndexedNode* node, | 892 IncrOpIndexedNode* node, |
| 919 Value** receiver, | 893 Value** receiver, |
| 920 Value** index) { | 894 Value** index) { |
| 921 // Evaluate the receiver and index. | 895 // Evaluate the receiver and index. |
| 922 // t_n <- ... receiver ... | 896 // t_n <- ... receiver ... |
| 923 // t_n+1 <- ... index ... | 897 // t_n+1 <- ... index ... |
| 924 ValueGraphVisitor for_receiver(owner(), temp_index()); | 898 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 925 node->array()->Visit(&for_receiver); | 899 node->array()->Visit(&for_receiver); |
| 926 Append(for_receiver); | 900 Append(for_receiver); |
| 927 AllocateTempIndex(); | |
| 928 ASSERT(temp_index() == for_receiver.temp_index()); | 901 ASSERT(temp_index() == for_receiver.temp_index()); |
| 929 | 902 |
| 930 ValueGraphVisitor for_index(owner(), temp_index()); | 903 ValueGraphVisitor for_index(owner(), temp_index()); |
| 931 node->index()->Visit(&for_index); | 904 node->index()->Visit(&for_index); |
| 932 Append(for_index); | 905 Append(for_index); |
| 933 AllocateTempIndex(); | |
| 934 ASSERT(temp_index() == for_index.temp_index()); | 906 ASSERT(temp_index() == for_index.temp_index()); |
| 935 | 907 |
| 936 // Duplicate the receiver and index values, load the value. | 908 // Duplicate the receiver and index values, load the value. |
| 937 // t_n+2 <- Pick(t_n) | 909 // t_n+2 <- Pick(t_n) |
| 938 // t_n+3 <- Pick(t_n+1) | 910 // t_n+3 <- Pick(t_n+1) |
| 939 // t_n+2 <- InstanceCall([], t_n+2, t_n+3) | 911 // t_n+2 <- InstanceCall([], t_n+2, t_n+3) |
| 940 PickTempInstr* duplicate_receiver = | 912 PickTempInstr* duplicate_receiver = new PickTempInstr(temp_index() - 2); |
| 941 new PickTempInstr(temp_index(), temp_index() - 2); | |
| 942 AddInstruction(duplicate_receiver); | 913 AddInstruction(duplicate_receiver); |
| 943 PickTempInstr* duplicate_index = | 914 PickTempInstr* duplicate_index = new PickTempInstr(temp_index() - 2); |
| 944 new PickTempInstr(temp_index() + 1, temp_index() - 1); | |
| 945 AddInstruction(duplicate_index); | 915 AddInstruction(duplicate_index); |
| 946 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 916 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 947 arguments->Add(new UseVal(duplicate_receiver)); | 917 arguments->Add(new UseVal(duplicate_receiver)); |
| 948 arguments->Add(new UseVal(duplicate_index)); | 918 arguments->Add(new UseVal(duplicate_index)); |
| 949 const String& load_name = | 919 const String& load_name = |
| 950 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); | 920 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); |
| 951 BindInstr* load = | 921 BindInstr* load = |
| 952 new BindInstr(temp_index(), | 922 new BindInstr(new InstanceCallComp( |
| 953 new InstanceCallComp( | |
| 954 node->token_index(), | 923 node->token_index(), |
| 955 owner()->try_index(), load_name, arguments, | 924 owner()->try_index(), load_name, arguments, |
| 956 Array::ZoneHandle(), 1)); | 925 Array::ZoneHandle(), 1)); |
| 957 AddInstruction(load); | 926 AddInstruction(load); |
| 958 AllocateTempIndex(); | |
| 959 | 927 |
| 960 *receiver = for_receiver.value(); | 928 *receiver = for_receiver.value(); |
| 961 *index = for_index.value(); | 929 *index = for_index.value(); |
| 962 return load; | 930 return load; |
| 963 } | 931 } |
| 964 | 932 |
| 965 | 933 |
| 966 void EffectGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { | 934 void EffectGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { |
| 967 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 935 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 968 // In an effect context, treat postincrement as if it were preincrement | 936 // In an effect context, treat postincrement as if it were preincrement |
| 969 // because its value is not needed. | 937 // because its value is not needed. |
| 970 | 938 |
| 971 // 1. Load the value. | 939 // 1. Load the value. |
| 972 Value* receiver = NULL; | 940 Value* receiver = NULL; |
| 973 Value* index = NULL; | 941 Value* index = NULL; |
| 974 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index); | 942 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index); |
| 975 // 2. Increment. | 943 // 2. Increment. |
| 976 Definition* incr = | 944 Definition* incr = |
| 977 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); | 945 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); |
| 978 // 3. Perform the store, returning the stored value. | 946 // 3. Perform the store, returning the stored value. |
| 979 StoreIndexedComp* store = new StoreIndexedComp(node->token_index(), | 947 StoreIndexedComp* store = new StoreIndexedComp(node->token_index(), |
| 980 owner()->try_index(), | 948 owner()->try_index(), |
| 981 receiver, | 949 receiver, |
| 982 index, | 950 index, |
| 983 new UseVal(incr)); | 951 new UseVal(incr)); |
| 984 DeallocateTempIndex(); // Consuming incr. | |
| 985 DeallocateTempIndex(); // Consuming index. | |
| 986 DeallocateTempIndex(); // Consuming receiver. | |
| 987 ReturnComputation(store); | 952 ReturnComputation(store); |
| 988 } | 953 } |
| 989 | 954 |
| 990 | 955 |
| 991 void ValueGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { | 956 void ValueGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { |
| 992 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 957 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 993 if (node->prefix()) { | 958 if (node->prefix()) { |
| 994 // Base class handles preincrement. | 959 // Base class handles preincrement. |
| 995 EffectGraphVisitor::VisitIncrOpIndexedNode(node); | 960 EffectGraphVisitor::VisitIncrOpIndexedNode(node); |
| 996 return; | 961 return; |
| 997 } | 962 } |
| 998 // For postincrement, preallocate a temporary to preserve the original | 963 // For postincrement, preallocate a temporary to preserve the original |
| 999 // value. | 964 // value. |
| 1000 // | 965 // |
| 1001 // 1. Name a placeholder. | 966 // 1. Name a placeholder. |
| 1002 BindInstr* placeholder = | 967 BindInstr* placeholder = |
| 1003 new BindInstr(temp_index(), | 968 new BindInstr(new ConstantVal(Smi::ZoneHandle(Smi::New(0)))); |
| 1004 new ConstantVal(Smi::ZoneHandle(Smi::New(0)))); | |
| 1005 AddInstruction(placeholder); | 969 AddInstruction(placeholder); |
| 1006 AllocateTempIndex(); | |
| 1007 // 2. Load the value. | 970 // 2. Load the value. |
| 1008 Value* receiver = NULL; | 971 Value* receiver = NULL; |
| 1009 Value* index = NULL; | 972 Value* index = NULL; |
| 1010 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index); | 973 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index); |
| 1011 // 3. Preserve the original value. | 974 // 3. Preserve the original value. |
| 1012 AddInstruction(new TuckTempInstr(placeholder->temp_index(), | 975 AddInstruction(new TuckTempInstr(placeholder->temp_index(), |
| 1013 load->temp_index())); | 976 load->temp_index())); |
| 1014 // 4. Increment. | 977 // 4. Increment. |
| 1015 Definition* incr = | 978 Definition* incr = |
| 1016 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); | 979 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); |
| 1017 // 5. Perform the store and return the original value. | 980 // 5. Perform the store and return the original value. |
| 1018 const String& store_name = | 981 const String& store_name = |
| 1019 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 982 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
| 1020 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(3); | 983 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(3); |
| 1021 arguments->Add(receiver); | 984 arguments->Add(receiver); |
| 1022 arguments->Add(index); | 985 arguments->Add(index); |
| 1023 arguments->Add(new UseVal(incr)); | 986 arguments->Add(new UseVal(incr)); |
| 1024 InstanceCallComp* store = new InstanceCallComp( | 987 InstanceCallComp* store = new InstanceCallComp( |
| 1025 node->token_index(), owner()->try_index(), | 988 node->token_index(), owner()->try_index(), |
| 1026 store_name, arguments, Array::ZoneHandle(), 1); | 989 store_name, arguments, Array::ZoneHandle(), 1); |
| 1027 DeallocateTempIndex(); // Consuming incr. | |
| 1028 DeallocateTempIndex(); // Consuming index. | |
| 1029 DeallocateTempIndex(); // Consuming receiver. | |
| 1030 AddInstruction(new DoInstr(store)); | 990 AddInstruction(new DoInstr(store)); |
| 1031 ReturnValue(new UseVal(placeholder)); | 991 ReturnValue(new UseVal(placeholder)); |
| 1032 } | 992 } |
| 1033 | 993 |
| 1034 | 994 |
| 1035 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 995 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 1036 TestGraphVisitor for_test(owner(), | 996 TestGraphVisitor for_test(owner(), |
| 1037 temp_index(), | 997 temp_index(), |
| 1038 node->condition()->token_index()); | 998 node->condition()->token_index()); |
| 1039 node->condition()->Visit(&for_test); | 999 node->condition()->Visit(&for_test); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1052 TestGraphVisitor for_test(owner(), | 1012 TestGraphVisitor for_test(owner(), |
| 1053 temp_index(), | 1013 temp_index(), |
| 1054 node->condition()->token_index()); | 1014 node->condition()->token_index()); |
| 1055 node->condition()->Visit(&for_test); | 1015 node->condition()->Visit(&for_test); |
| 1056 | 1016 |
| 1057 // Ensure that the value of the true/false subexpressions are named with | 1017 // Ensure that the value of the true/false subexpressions are named with |
| 1058 // the same temporary name. | 1018 // the same temporary name. |
| 1059 ValueGraphVisitor for_true(owner(), temp_index()); | 1019 ValueGraphVisitor for_true(owner(), temp_index()); |
| 1060 node->true_expr()->Visit(&for_true); | 1020 node->true_expr()->Visit(&for_true); |
| 1061 ASSERT(for_true.is_open()); | 1021 ASSERT(for_true.is_open()); |
| 1062 if (for_true.value()->IsTemp()) { | 1022 ASSERT(for_true.value()->IsTemp() || for_true.value()->IsUse()); |
| 1063 ASSERT(for_true.value()->AsTemp()->index() == temp_index()); | |
| 1064 } else { | |
| 1065 for_true.AddInstruction(new BindInstr(temp_index(), for_true.value())); | |
| 1066 } | |
| 1067 | 1023 |
| 1068 ValueGraphVisitor for_false(owner(), temp_index()); | 1024 ValueGraphVisitor for_false(owner(), temp_index()); |
| 1069 node->false_expr()->Visit(&for_false); | 1025 node->false_expr()->Visit(&for_false); |
| 1070 ASSERT(for_false.is_open()); | 1026 ASSERT(for_false.is_open()); |
| 1071 if (for_false.value()->IsTemp()) { | 1027 ASSERT(for_false.value()->IsTemp() || for_false.value()->IsUse()); |
| 1072 ASSERT(for_false.value()->AsTemp()->index() == temp_index()); | |
| 1073 } else { | |
| 1074 for_false.AddInstruction(new BindInstr(temp_index(), for_false.value())); | |
| 1075 } | |
| 1076 | 1028 |
| 1077 Join(for_test, for_true, for_false); | 1029 Join(for_test, for_true, for_false); |
| 1078 ReturnValue(new TempVal(AllocateTempIndex())); | 1030 ReturnValue(new TempVal(temp_index() - 1)); |
| 1079 } | 1031 } |
| 1080 | 1032 |
| 1081 | 1033 |
| 1082 // <Statement> ::= If { condition: <Expression> | 1034 // <Statement> ::= If { condition: <Expression> |
| 1083 // true_branch: <Sequence> | 1035 // true_branch: <Sequence> |
| 1084 // false_branch: <Sequence> } | 1036 // false_branch: <Sequence> } |
| 1085 void EffectGraphVisitor::VisitIfNode(IfNode* node) { | 1037 void EffectGraphVisitor::VisitIfNode(IfNode* node) { |
| 1086 TestGraphVisitor for_test(owner(), | 1038 TestGraphVisitor for_test(owner(), |
| 1087 temp_index(), | 1039 temp_index(), |
| 1088 node->condition()->token_index()); | 1040 node->condition()->token_index()); |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1470 | 1422 |
| 1471 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { | 1423 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { |
| 1472 UNREACHABLE(); | 1424 UNREACHABLE(); |
| 1473 } | 1425 } |
| 1474 | 1426 |
| 1475 | 1427 |
| 1476 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 1428 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 1477 // Translate the array elements and collect their values. | 1429 // Translate the array elements and collect their values. |
| 1478 ZoneGrowableArray<Value*>* values = | 1430 ZoneGrowableArray<Value*>* values = |
| 1479 new ZoneGrowableArray<Value*>(node->length()); | 1431 new ZoneGrowableArray<Value*>(node->length()); |
| 1480 int index = temp_index(); | |
| 1481 for (int i = 0; i < node->length(); ++i) { | 1432 for (int i = 0; i < node->length(); ++i) { |
| 1482 ValueGraphVisitor for_value(owner(), index); | 1433 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1483 node->ElementAt(i)->Visit(&for_value); | 1434 node->ElementAt(i)->Visit(&for_value); |
| 1484 Append(for_value); | 1435 Append(for_value); |
| 1485 values->Add(for_value.value()); | 1436 values->Add(for_value.value()); |
| 1486 index = for_value.temp_index(); | |
| 1487 } | 1437 } |
| 1488 CreateArrayComp* create = new CreateArrayComp(node, | 1438 CreateArrayComp* create = new CreateArrayComp(node, |
| 1489 owner()->try_index(), | 1439 owner()->try_index(), |
| 1490 values); | 1440 values); |
| 1491 ReturnComputation(create); | 1441 ReturnComputation(create); |
| 1492 } | 1442 } |
| 1493 | 1443 |
| 1494 | 1444 |
| 1495 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 1445 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 1496 const Function& function = node->function(); | 1446 const Function& function = node->function(); |
| 1497 | 1447 |
| 1498 int next_index = temp_index(); | |
| 1499 if (function.IsNonImplicitClosureFunction()) { | 1448 if (function.IsNonImplicitClosureFunction()) { |
| 1500 const ContextScope& context_scope = ContextScope::ZoneHandle( | 1449 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| 1501 node->scope()->PreserveOuterScope(owner()->context_level())); | 1450 node->scope()->PreserveOuterScope(owner()->context_level())); |
| 1502 ASSERT(!function.HasCode()); | 1451 ASSERT(!function.HasCode()); |
| 1503 ASSERT(function.context_scope() == ContextScope::null()); | 1452 ASSERT(function.context_scope() == ContextScope::null()); |
| 1504 function.set_context_scope(context_scope); | 1453 function.set_context_scope(context_scope); |
| 1505 } else if (function.IsImplicitInstanceClosureFunction()) { | 1454 } else if (function.IsImplicitInstanceClosureFunction()) { |
| 1506 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1455 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1507 node->receiver()->Visit(&for_receiver); | 1456 node->receiver()->Visit(&for_receiver); |
| 1508 Append(for_receiver); | 1457 Append(for_receiver); |
| 1509 if (!for_receiver.value()->IsTemp()) { | |
| 1510 AddInstruction(new BindInstr(temp_index(), for_receiver.value())); | |
| 1511 } | |
| 1512 ++next_index; | |
| 1513 } | 1458 } |
| 1514 ASSERT(function.context_scope() != ContextScope::null()); | 1459 ASSERT(function.context_scope() != ContextScope::null()); |
| 1515 | 1460 |
| 1516 // The function type of a closure may have type arguments. In that case, pass | 1461 // The function type of a closure may have type arguments. In that case, pass |
| 1517 // the type arguments of the instantiator. | 1462 // the type arguments of the instantiator. |
| 1518 const Class& cls = Class::Handle(function.signature_class()); | 1463 const Class& cls = Class::Handle(function.signature_class()); |
| 1519 ASSERT(!cls.IsNull()); | 1464 ASSERT(!cls.IsNull()); |
| 1520 const bool requires_type_arguments = cls.HasTypeArguments(); | 1465 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1521 Value* type_arguments = NULL; | 1466 Value* type_arguments = NULL; |
| 1522 if (requires_type_arguments) { | 1467 if (requires_type_arguments) { |
| 1523 ASSERT(!function.IsImplicitStaticClosureFunction()); | 1468 ASSERT(!function.IsImplicitStaticClosureFunction()); |
| 1524 type_arguments = | 1469 type_arguments = |
| 1525 BuildInstantiatorTypeArguments(node->token_index(), temp_index()); | 1470 BuildInstantiatorTypeArguments(node->token_index()); |
| 1526 } | 1471 } |
| 1527 | 1472 |
| 1528 CreateClosureComp* create = | 1473 CreateClosureComp* create = |
| 1529 new CreateClosureComp(node, owner()->try_index(), type_arguments); | 1474 new CreateClosureComp(node, owner()->try_index(), type_arguments); |
| 1530 ReturnComputation(create); | 1475 ReturnComputation(create); |
| 1531 } | 1476 } |
| 1532 | 1477 |
| 1533 | 1478 |
| 1534 void EffectGraphVisitor::TranslateArgumentList( | 1479 void EffectGraphVisitor::TranslateArgumentList( |
| 1535 const ArgumentListNode& node, | 1480 const ArgumentListNode& node, |
| 1536 intptr_t next_temp_index, | |
| 1537 ZoneGrowableArray<Value*>* values) { | 1481 ZoneGrowableArray<Value*>* values) { |
| 1538 for (intptr_t i = 0; i < node.length(); ++i) { | 1482 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1539 ValueGraphVisitor for_argument(owner(), next_temp_index); | 1483 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 1540 node.NodeAt(i)->Visit(&for_argument); | 1484 node.NodeAt(i)->Visit(&for_argument); |
| 1541 Append(for_argument); | 1485 Append(for_argument); |
| 1542 next_temp_index = for_argument.temp_index(); | |
| 1543 values->Add(for_argument.value()); | 1486 values->Add(for_argument.value()); |
| 1544 } | 1487 } |
| 1545 } | 1488 } |
| 1546 | 1489 |
| 1547 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 1490 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 1548 ArgumentListNode* arguments = node->arguments(); | 1491 ArgumentListNode* arguments = node->arguments(); |
| 1549 int length = arguments->length(); | 1492 int length = arguments->length(); |
| 1550 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1); | 1493 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1); |
| 1551 | 1494 |
| 1552 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1495 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1553 node->receiver()->Visit(&for_receiver); | 1496 node->receiver()->Visit(&for_receiver); |
| 1554 Append(for_receiver); | 1497 Append(for_receiver); |
| 1555 values->Add(for_receiver.value()); | 1498 values->Add(for_receiver.value()); |
| 1556 | 1499 |
| 1557 TranslateArgumentList(*arguments, for_receiver.temp_index(), values); | 1500 TranslateArgumentList(*arguments, values); |
| 1558 InstanceCallComp* call = new InstanceCallComp( | 1501 InstanceCallComp* call = new InstanceCallComp( |
| 1559 node->token_index(), owner()->try_index(), | 1502 node->token_index(), owner()->try_index(), |
| 1560 node->function_name(), values, | 1503 node->function_name(), values, |
| 1561 arguments->names(), 1); | 1504 arguments->names(), 1); |
| 1562 ReturnComputation(call); | 1505 ReturnComputation(call); |
| 1563 } | 1506 } |
| 1564 | 1507 |
| 1565 | 1508 |
| 1566 // <Expression> ::= StaticCall { function: Function | 1509 // <Expression> ::= StaticCall { function: Function |
| 1567 // arguments: <ArgumentList> } | 1510 // arguments: <ArgumentList> } |
| 1568 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 1511 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 1569 int length = node->arguments()->length(); | 1512 int length = node->arguments()->length(); |
| 1570 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length); | 1513 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length); |
| 1571 TranslateArgumentList(*node->arguments(), temp_index(), values); | 1514 TranslateArgumentList(*node->arguments(), values); |
| 1572 StaticCallComp* call = | 1515 StaticCallComp* call = |
| 1573 new StaticCallComp(node->token_index(), | 1516 new StaticCallComp(node->token_index(), |
| 1574 owner()->try_index(), | 1517 owner()->try_index(), |
| 1575 node->function(), | 1518 node->function(), |
| 1576 node->arguments()->names(), | 1519 node->arguments()->names(), |
| 1577 values); | 1520 values); |
| 1578 ReturnComputation(call); | 1521 ReturnComputation(call); |
| 1579 } | 1522 } |
| 1580 | 1523 |
| 1581 | 1524 |
| 1582 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1525 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1583 // Context is saved around the call, it's treated as an extra operand | 1526 // Context is saved around the call, it's treated as an extra operand |
| 1584 // consumed by the call (but not an argument). | 1527 // consumed by the call (but not an argument). |
| 1585 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); | 1528 BindInstr* context = new BindInstr(new CurrentContextComp()); |
| 1586 AddInstruction(context); | 1529 AddInstruction(context); |
| 1587 | 1530 |
| 1588 ValueGraphVisitor for_closure(owner(), temp_index() + 1); | 1531 ValueGraphVisitor for_closure(owner(), temp_index()); |
| 1589 node->closure()->Visit(&for_closure); | 1532 node->closure()->Visit(&for_closure); |
| 1590 Append(for_closure); | 1533 Append(for_closure); |
| 1591 | 1534 |
| 1592 ZoneGrowableArray<Value*>* arguments = | 1535 ZoneGrowableArray<Value*>* arguments = |
| 1593 new ZoneGrowableArray<Value*>(node->arguments()->length()); | 1536 new ZoneGrowableArray<Value*>(node->arguments()->length()); |
| 1594 arguments->Add(for_closure.value()); | 1537 arguments->Add(for_closure.value()); |
| 1595 TranslateArgumentList(*node->arguments(), temp_index() + 2, arguments); | 1538 TranslateArgumentList(*node->arguments(), arguments); |
| 1596 // First operand is the saved context, consumed by the call. | 1539 // First operand is the saved context, consumed by the call. |
| 1597 ClosureCallComp* call = new ClosureCallComp(node, | 1540 ClosureCallComp* call = new ClosureCallComp(node, |
| 1598 owner()->try_index(), | 1541 owner()->try_index(), |
| 1599 new UseVal(context), | 1542 new UseVal(context), |
| 1600 arguments); | 1543 arguments); |
| 1601 ReturnComputation(call); | 1544 ReturnComputation(call); |
| 1602 } | 1545 } |
| 1603 | 1546 |
| 1604 | 1547 |
| 1605 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 1548 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 1606 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); | 1549 BindInstr* context = new BindInstr(new CurrentContextComp()); |
| 1607 AddInstruction(context); | 1550 AddInstruction(context); |
| 1608 BindInstr* clone = | 1551 BindInstr* clone = |
| 1609 new BindInstr(temp_index(), | 1552 new BindInstr(new CloneContextComp(node->token_index(), |
| 1610 new CloneContextComp(node->token_index(), | |
| 1611 owner()->try_index(), | 1553 owner()->try_index(), |
| 1612 new UseVal(context))); | 1554 new UseVal(context))); |
| 1613 AddInstruction(clone); | 1555 AddInstruction(clone); |
| 1614 ReturnComputation(new StoreContextComp(new UseVal(clone))); | 1556 ReturnComputation(new StoreContextComp(new UseVal(clone))); |
| 1615 } | 1557 } |
| 1616 | 1558 |
| 1617 | 1559 |
| 1618 Definition* EffectGraphVisitor::BuildObjectAllocation( | 1560 Definition* EffectGraphVisitor::BuildObjectAllocation( |
| 1619 ConstructorCallNode* node) { | 1561 ConstructorCallNode* node) { |
| 1620 const Class& cls = Class::ZoneHandle(node->constructor().owner()); | 1562 const Class& cls = Class::ZoneHandle(node->constructor().owner()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1642 // may represent the identity vector and may be replaced by the instantiated | 1584 // may represent the identity vector and may be replaced by the instantiated |
| 1643 // type arguments of the instantiator at run time. | 1585 // type arguments of the instantiator at run time. |
| 1644 allocate_comp = new AllocateObjectWithBoundsCheckComp(node, | 1586 allocate_comp = new AllocateObjectWithBoundsCheckComp(node, |
| 1645 owner()->try_index(), | 1587 owner()->try_index(), |
| 1646 allocate_arguments); | 1588 allocate_arguments); |
| 1647 } else { | 1589 } else { |
| 1648 allocate_comp = new AllocateObjectComp(node, | 1590 allocate_comp = new AllocateObjectComp(node, |
| 1649 owner()->try_index(), | 1591 owner()->try_index(), |
| 1650 allocate_arguments); | 1592 allocate_arguments); |
| 1651 } | 1593 } |
| 1652 BindInstr* allocate = new BindInstr(temp_index(), allocate_comp); | 1594 BindInstr* allocate = new BindInstr(allocate_comp); |
| 1653 AddInstruction(allocate); | 1595 AddInstruction(allocate); |
| 1654 AllocateTempIndex(); | |
| 1655 return allocate; | 1596 return allocate; |
| 1656 } | 1597 } |
| 1657 | 1598 |
| 1658 | 1599 |
| 1659 void EffectGraphVisitor::BuildConstructorCall(ConstructorCallNode* node, | 1600 void EffectGraphVisitor::BuildConstructorCall(ConstructorCallNode* node, |
| 1660 Value* alloc_value) { | 1601 Value* alloc_value) { |
| 1661 BindInstr* ctor_arg = | 1602 BindInstr* ctor_arg = |
| 1662 new BindInstr(temp_index(), | 1603 new BindInstr(new ConstantVal( |
| 1663 new ConstantVal( | |
| 1664 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 1604 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
| 1665 AddInstruction(ctor_arg); | 1605 AddInstruction(ctor_arg); |
| 1666 AllocateTempIndex(); | |
| 1667 | 1606 |
| 1668 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); | 1607 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); |
| 1669 values->Add(alloc_value); | 1608 values->Add(alloc_value); |
| 1670 values->Add(new UseVal(ctor_arg)); | 1609 values->Add(new UseVal(ctor_arg)); |
| 1671 | 1610 |
| 1672 TranslateArgumentList(*node->arguments(), temp_index(), values); | 1611 TranslateArgumentList(*node->arguments(), values); |
| 1673 StaticCallComp* call = | 1612 StaticCallComp* call = |
| 1674 new StaticCallComp(node->token_index(), | 1613 new StaticCallComp(node->token_index(), |
| 1675 owner()->try_index(), | 1614 owner()->try_index(), |
| 1676 node->constructor(), | 1615 node->constructor(), |
| 1677 node->arguments()->names(), | 1616 node->arguments()->names(), |
| 1678 values); | 1617 values); |
| 1679 DeallocateTempIndex(); // Consuming ctor_arg. | |
| 1680 DeallocateTempIndex(); // Consuming alloc_value. | |
| 1681 AddInstruction(new DoInstr(call)); | 1618 AddInstruction(new DoInstr(call)); |
| 1682 } | 1619 } |
| 1683 | 1620 |
| 1684 | 1621 |
| 1685 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1622 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1686 if (node->constructor().IsFactory()) { | 1623 if (node->constructor().IsFactory()) { |
| 1687 ZoneGrowableArray<Value*>* factory_arguments = | 1624 ZoneGrowableArray<Value*>* factory_arguments = |
| 1688 new ZoneGrowableArray<Value*>(); | 1625 new ZoneGrowableArray<Value*>(); |
| 1689 factory_arguments->Add(new UseVal(BuildFactoryTypeArguments(node))); | 1626 factory_arguments->Add(new UseVal(BuildFactoryTypeArguments(node))); |
| 1690 ASSERT(factory_arguments->length() == 1); | 1627 ASSERT(factory_arguments->length() == 1); |
| 1691 TranslateArgumentList(*node->arguments(), | 1628 TranslateArgumentList(*node->arguments(), factory_arguments); |
| 1692 temp_index(), | |
| 1693 factory_arguments); | |
| 1694 StaticCallComp* call = | 1629 StaticCallComp* call = |
| 1695 new StaticCallComp(node->token_index(), | 1630 new StaticCallComp(node->token_index(), |
| 1696 owner()->try_index(), | 1631 owner()->try_index(), |
| 1697 node->constructor(), | 1632 node->constructor(), |
| 1698 node->arguments()->names(), | 1633 node->arguments()->names(), |
| 1699 factory_arguments); | 1634 factory_arguments); |
| 1700 DeallocateTempIndex(); // Consuming type arguments. | |
| 1701 ReturnComputation(call); | 1635 ReturnComputation(call); |
| 1702 return; | 1636 return; |
| 1703 } | 1637 } |
| 1704 // t_n contains the allocated and initialized object. | 1638 // t_n contains the allocated and initialized object. |
| 1705 // t_n <- AllocateObject(class) | 1639 // t_n <- AllocateObject(class) |
| 1706 // t_n+1 <- ctor-arg | 1640 // t_n+1 <- ctor-arg |
| 1707 // t_n+2... <- constructor arguments start here | 1641 // t_n+2... <- constructor arguments start here |
| 1708 // StaticCall(constructor, t_n+1, t_n+2, ...) | 1642 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 1709 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 1643 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 1710 Definition* allocate = BuildObjectAllocation(node); | 1644 Definition* allocate = BuildObjectAllocation(node); |
| 1711 BuildConstructorCall(node, new UseVal(allocate)); | 1645 BuildConstructorCall(node, new UseVal(allocate)); |
| 1712 } | 1646 } |
| 1713 | 1647 |
| 1714 | 1648 |
| 1715 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 1649 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 1716 intptr_t token_index, intptr_t start_index) { | 1650 intptr_t token_index) { |
| 1717 const Class& instantiator_class = Class::Handle( | 1651 const Class& instantiator_class = Class::Handle( |
| 1718 owner()->parsed_function().function().owner()); | 1652 owner()->parsed_function().function().owner()); |
| 1719 if (instantiator_class.NumTypeParameters() == 0) { | 1653 if (instantiator_class.NumTypeParameters() == 0) { |
| 1720 // The type arguments are compile time constants. | 1654 // The type arguments are compile time constants. |
| 1721 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 1655 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 1722 // TODO(regis): Temporary type should be allocated in new gen heap. | 1656 // TODO(regis): Temporary type should be allocated in new gen heap. |
| 1723 Type& type = Type::Handle( | 1657 Type& type = Type::Handle( |
| 1724 Type::New(instantiator_class, type_arguments, token_index)); | 1658 Type::New(instantiator_class, type_arguments, token_index)); |
| 1725 type ^= ClassFinalizer::FinalizeType( | 1659 type ^= ClassFinalizer::FinalizeType( |
| 1726 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed); | 1660 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed); |
| 1727 type_arguments = type.arguments(); | 1661 type_arguments = type.arguments(); |
| 1728 BindInstr* args = | 1662 BindInstr* args = new BindInstr(new ConstantVal(type_arguments)); |
| 1729 new BindInstr(temp_index(), new ConstantVal(type_arguments)); | |
| 1730 AddInstruction(args); | 1663 AddInstruction(args); |
| 1731 return new UseVal(args); | 1664 return new UseVal(args); |
| 1732 } | 1665 } |
| 1733 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1666 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1734 ValueGraphVisitor for_instantiator(owner(), start_index); | 1667 ValueGraphVisitor for_instantiator(owner(), temp_index()); |
| 1735 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1668 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1736 Append(for_instantiator); | 1669 Append(for_instantiator); |
| 1737 Function& outer_function = | 1670 Function& outer_function = |
| 1738 Function::Handle(owner()->parsed_function().function().raw()); | 1671 Function::Handle(owner()->parsed_function().function().raw()); |
| 1739 while (outer_function.IsLocalFunction()) { | 1672 while (outer_function.IsLocalFunction()) { |
| 1740 outer_function = outer_function.parent_function(); | 1673 outer_function = outer_function.parent_function(); |
| 1741 } | 1674 } |
| 1742 if (outer_function.IsFactory()) { | 1675 if (outer_function.IsFactory()) { |
| 1743 // All OK. | 1676 // All OK. |
| 1744 return for_instantiator.value(); | 1677 return for_instantiator.value(); |
| 1745 } | 1678 } |
| 1746 | 1679 |
| 1747 // The instantiator is the receiver of the caller, which is not a factory. | 1680 // The instantiator is the receiver of the caller, which is not a factory. |
| 1748 // The receiver cannot be null; extract its AbstractTypeArguments object. | 1681 // The receiver cannot be null; extract its AbstractTypeArguments object. |
| 1749 // Note that in the factory case, the instantiator is the first parameter | 1682 // Note that in the factory case, the instantiator is the first parameter |
| 1750 // of the factory, i.e. already an AbstractTypeArguments object. | 1683 // of the factory, i.e. already an AbstractTypeArguments object. |
| 1751 intptr_t type_arguments_instance_field_offset = | 1684 intptr_t type_arguments_instance_field_offset = |
| 1752 instantiator_class.type_arguments_instance_field_offset(); | 1685 instantiator_class.type_arguments_instance_field_offset(); |
| 1753 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); | 1686 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); |
| 1754 | 1687 |
| 1755 BindInstr* load = | 1688 BindInstr* load = |
| 1756 new BindInstr(start_index, | 1689 new BindInstr(new NativeLoadFieldComp( |
| 1757 new NativeLoadFieldComp( | |
| 1758 for_instantiator.value(), | 1690 for_instantiator.value(), |
| 1759 type_arguments_instance_field_offset)); | 1691 type_arguments_instance_field_offset)); |
| 1760 AddInstruction(load); | 1692 AddInstruction(load); |
| 1761 return new UseVal(load); | 1693 return new UseVal(load); |
| 1762 } | 1694 } |
| 1763 | 1695 |
| 1764 | 1696 |
| 1765 Definition* EffectGraphVisitor::BuildFactoryTypeArguments( | 1697 Definition* EffectGraphVisitor::BuildFactoryTypeArguments( |
| 1766 ConstructorCallNode* node) { | 1698 ConstructorCallNode* node) { |
| 1767 ASSERT(node->constructor().IsFactory()); | 1699 ASSERT(node->constructor().IsFactory()); |
| 1768 if (node->type_arguments().IsNull() || | 1700 if (node->type_arguments().IsNull() || |
| 1769 node->type_arguments().IsInstantiated()) { | 1701 node->type_arguments().IsInstantiated()) { |
| 1770 BindInstr* type_args = | 1702 BindInstr* type_args = |
| 1771 new BindInstr(temp_index(), new ConstantVal(node->type_arguments())); | 1703 new BindInstr(new ConstantVal(node->type_arguments())); |
| 1772 AddInstruction(type_args); | 1704 AddInstruction(type_args); |
| 1773 AllocateTempIndex(); | |
| 1774 return type_args; | 1705 return type_args; |
| 1775 } | 1706 } |
| 1776 // The type arguments are uninstantiated. | 1707 // The type arguments are uninstantiated. |
| 1777 Value* instantiator_value = | 1708 Value* instantiator_value = |
| 1778 BuildInstantiatorTypeArguments(node->token_index(), temp_index()); | 1709 BuildInstantiatorTypeArguments(node->token_index()); |
| 1779 BindInstr* extract = | 1710 BindInstr* extract = |
| 1780 new BindInstr(temp_index(), | 1711 new BindInstr(new ExtractFactoryTypeArgumentsComp(node, |
| 1781 new ExtractFactoryTypeArgumentsComp(node, | |
| 1782 owner()->try_index(), | 1712 owner()->try_index(), |
| 1783 instantiator_value)); | 1713 instantiator_value)); |
| 1784 AddInstruction(extract); | 1714 AddInstruction(extract); |
| 1785 AllocateTempIndex(); | |
| 1786 return extract; | 1715 return extract; |
| 1787 } | 1716 } |
| 1788 | 1717 |
| 1789 | 1718 |
| 1790 void EffectGraphVisitor::BuildConstructorTypeArguments( | 1719 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| 1791 ConstructorCallNode* node, | 1720 ConstructorCallNode* node, |
| 1792 ZoneGrowableArray<Value*>* args) { | 1721 ZoneGrowableArray<Value*>* args) { |
| 1793 const Class& cls = Class::ZoneHandle(node->constructor().owner()); | 1722 const Class& cls = Class::ZoneHandle(node->constructor().owner()); |
| 1794 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); | 1723 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); |
| 1795 if (node->type_arguments().IsNull() || | 1724 if (node->type_arguments().IsNull() || |
| 1796 node->type_arguments().IsInstantiated()) { | 1725 node->type_arguments().IsInstantiated()) { |
| 1797 BindInstr* type_args = | 1726 BindInstr* type_args = |
| 1798 new BindInstr(temp_index(), new ConstantVal(node->type_arguments())); | 1727 new BindInstr(new ConstantVal(node->type_arguments())); |
| 1799 AddInstruction(type_args); | 1728 AddInstruction(type_args); |
| 1800 // No instantiator required. | 1729 // No instantiator required. |
| 1801 BindInstr* no_instantiator = | 1730 BindInstr* no_instantiator = |
| 1802 new BindInstr(temp_index() + 1, | 1731 new BindInstr(new ConstantVal( |
| 1803 new ConstantVal( | |
| 1804 Smi::ZoneHandle(Smi::New( | 1732 Smi::ZoneHandle(Smi::New( |
| 1805 StubCode::kNoInstantiator)))); | 1733 StubCode::kNoInstantiator)))); |
| 1806 AddInstruction(no_instantiator); | 1734 AddInstruction(no_instantiator); |
| 1807 args->Add(new UseVal(type_args)); | 1735 args->Add(new UseVal(type_args)); |
| 1808 args->Add(new UseVal(no_instantiator)); | 1736 args->Add(new UseVal(no_instantiator)); |
| 1809 return; | 1737 return; |
| 1810 } | 1738 } |
| 1811 // The type arguments are uninstantiated. | 1739 // The type arguments are uninstantiated. |
| 1812 // Place holder to hold uninstantiated constructor type arguments. | 1740 // Place holder to hold uninstantiated constructor type arguments. |
| 1813 BindInstr* placeholder = | 1741 BindInstr* placeholder = |
| 1814 new BindInstr(temp_index(), | 1742 new BindInstr(new ConstantVal(Object::ZoneHandle())); |
| 1815 new ConstantVal(Object::ZoneHandle())); | |
| 1816 AddInstruction(placeholder); | 1743 AddInstruction(placeholder); |
| 1817 Value* instantiator = | 1744 Value* instantiator = |
| 1818 BuildInstantiatorTypeArguments(node->token_index(), temp_index() + 1); | 1745 BuildInstantiatorTypeArguments(node->token_index()); |
| 1819 ASSERT(instantiator->IsUse()); | 1746 ASSERT(instantiator->IsUse()); |
| 1820 PickTempInstr* duplicate_instantiator = | 1747 PickTempInstr* duplicate_instantiator = |
| 1821 new PickTempInstr(temp_index() + 2, | 1748 new PickTempInstr(instantiator->AsUse()->definition()->temp_index()); |
| 1822 instantiator->AsUse()->definition()->temp_index()); | |
| 1823 AddInstruction(duplicate_instantiator); | 1749 AddInstruction(duplicate_instantiator); |
| 1824 BindInstr* extract_type_arguments = | 1750 BindInstr* extract_type_arguments = |
| 1825 new BindInstr(temp_index() + 2, | 1751 new BindInstr(new ExtractConstructorTypeArgumentsComp( |
| 1826 new ExtractConstructorTypeArgumentsComp( | |
| 1827 node, new UseVal(duplicate_instantiator))); | 1752 node, new UseVal(duplicate_instantiator))); |
| 1828 AddInstruction(extract_type_arguments); | 1753 AddInstruction(extract_type_arguments); |
| 1829 AddInstruction(new TuckTempInstr(placeholder->temp_index(), | 1754 AddInstruction(new TuckTempInstr(placeholder->temp_index(), |
| 1830 extract_type_arguments->temp_index())); | 1755 extract_type_arguments->temp_index())); |
| 1831 BindInstr* extract_instantiator = | 1756 BindInstr* extract_instantiator = |
| 1832 new BindInstr(temp_index() + 1, | 1757 new BindInstr(new ExtractConstructorInstantiatorComp( |
| 1833 new ExtractConstructorInstantiatorComp( | |
| 1834 node, | 1758 node, |
| 1835 instantiator, | 1759 instantiator, |
| 1836 new UseVal(extract_type_arguments))); | 1760 new UseVal(extract_type_arguments))); |
| 1837 AddInstruction(extract_instantiator); | 1761 AddInstruction(extract_instantiator); |
| 1838 args->Add(new UseVal(placeholder)); | 1762 args->Add(new UseVal(placeholder)); |
| 1839 args->Add(new UseVal(extract_instantiator)); | 1763 args->Add(new UseVal(extract_instantiator)); |
| 1840 } | 1764 } |
| 1841 | 1765 |
| 1842 | 1766 |
| 1843 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1767 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1844 if (node->constructor().IsFactory()) { | 1768 if (node->constructor().IsFactory()) { |
| 1845 EffectGraphVisitor::VisitConstructorCallNode(node); | 1769 EffectGraphVisitor::VisitConstructorCallNode(node); |
| 1846 return; | 1770 return; |
| 1847 } | 1771 } |
| 1848 | 1772 |
| 1849 // t_n contains the allocated and initialized object. | 1773 // t_n contains the allocated and initialized object. |
| 1850 // t_n <- AllocateObject(class) | 1774 // t_n <- AllocateObject(class) |
| 1851 // t_n+1 <- Pick(t_n) | 1775 // t_n+1 <- Pick(t_n) |
| 1852 // t_n+2 <- ctor-arg | 1776 // t_n+2 <- ctor-arg |
| 1853 // t_n+3... <- constructor arguments start here | 1777 // t_n+3... <- constructor arguments start here |
| 1854 // StaticCall(constructor, t_n+1, t_n+2, ...) | 1778 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 1855 | 1779 |
| 1856 Definition* allocate = BuildObjectAllocation(node); | 1780 Definition* allocate = BuildObjectAllocation(node); |
| 1857 PickTempInstr* duplicate = | 1781 PickTempInstr* duplicate = new PickTempInstr(allocate->temp_index()); |
| 1858 new PickTempInstr(temp_index(), allocate->temp_index()); | |
| 1859 AddInstruction(duplicate); | 1782 AddInstruction(duplicate); |
| 1860 AllocateTempIndex(); | |
| 1861 BuildConstructorCall(node, new UseVal(duplicate)); | 1783 BuildConstructorCall(node, new UseVal(duplicate)); |
| 1862 ReturnValue(new UseVal(allocate)); | 1784 ReturnValue(new UseVal(allocate)); |
| 1863 } | 1785 } |
| 1864 | 1786 |
| 1865 | 1787 |
| 1866 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 1788 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 1867 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1789 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1868 node->receiver()->Visit(&for_receiver); | 1790 node->receiver()->Visit(&for_receiver); |
| 1869 Append(for_receiver); | 1791 Append(for_receiver); |
| 1870 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); | 1792 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1963 // value: <Expression> } | 1885 // value: <Expression> } |
| 1964 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 1886 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 1965 ValueGraphVisitor for_value(owner(), temp_index()); | 1887 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1966 node->value()->Visit(&for_value); | 1888 node->value()->Visit(&for_value); |
| 1967 Append(for_value); | 1889 Append(for_value); |
| 1968 Value* store_value = for_value.value(); | 1890 Value* store_value = for_value.value(); |
| 1969 if (FLAG_enable_type_checks) { | 1891 if (FLAG_enable_type_checks) { |
| 1970 store_value = BuildAssignableValue(node->value(), | 1892 store_value = BuildAssignableValue(node->value(), |
| 1971 store_value, | 1893 store_value, |
| 1972 node->local().type(), | 1894 node->local().type(), |
| 1973 node->local().name(), | 1895 node->local().name()); |
| 1974 temp_index()); | |
| 1975 } | 1896 } |
| 1976 StoreLocalComp* store = | 1897 StoreLocalComp* store = |
| 1977 new StoreLocalComp(node->local(), store_value, owner()->context_level()); | 1898 new StoreLocalComp(node->local(), store_value, owner()->context_level()); |
| 1978 ReturnComputation(store); | 1899 ReturnComputation(store); |
| 1979 } | 1900 } |
| 1980 | 1901 |
| 1981 | 1902 |
| 1982 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 1903 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 1983 LoadInstanceFieldNode* node) { | 1904 LoadInstanceFieldNode* node) { |
| 1984 ValueGraphVisitor for_instance(owner(), temp_index()); | 1905 ValueGraphVisitor for_instance(owner(), temp_index()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1998 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 1919 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); |
| 1999 node->value()->Visit(&for_value); | 1920 node->value()->Visit(&for_value); |
| 2000 Append(for_value); | 1921 Append(for_value); |
| 2001 Value* store_value = for_value.value(); | 1922 Value* store_value = for_value.value(); |
| 2002 if (FLAG_enable_type_checks) { | 1923 if (FLAG_enable_type_checks) { |
| 2003 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 1924 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2004 const String& dst_name = String::ZoneHandle(node->field().name()); | 1925 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2005 store_value = BuildAssignableValue(node->value(), | 1926 store_value = BuildAssignableValue(node->value(), |
| 2006 store_value, | 1927 store_value, |
| 2007 type, | 1928 type, |
| 2008 dst_name, | 1929 dst_name); |
| 2009 for_instance.temp_index()); | |
| 2010 } | 1930 } |
| 2011 StoreInstanceFieldComp* store = | 1931 StoreInstanceFieldComp* store = |
| 2012 new StoreInstanceFieldComp(node, for_instance.value(), store_value); | 1932 new StoreInstanceFieldComp(node, for_instance.value(), store_value); |
| 2013 ReturnComputation(store); | 1933 ReturnComputation(store); |
| 2014 } | 1934 } |
| 2015 | 1935 |
| 2016 | 1936 |
| 2017 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 1937 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 2018 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); | 1938 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); |
| 2019 ReturnComputation(load); | 1939 ReturnComputation(load); |
| 2020 } | 1940 } |
| 2021 | 1941 |
| 2022 | 1942 |
| 2023 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 1943 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 2024 ValueGraphVisitor for_value(owner(), temp_index()); | 1944 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2025 node->value()->Visit(&for_value); | 1945 node->value()->Visit(&for_value); |
| 2026 Append(for_value); | 1946 Append(for_value); |
| 2027 Value* store_value = for_value.value(); | 1947 Value* store_value = for_value.value(); |
| 2028 if (FLAG_enable_type_checks) { | 1948 if (FLAG_enable_type_checks) { |
| 2029 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 1949 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2030 const String& dst_name = String::ZoneHandle(node->field().name()); | 1950 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2031 store_value = BuildAssignableValue(node->value(), | 1951 store_value = BuildAssignableValue(node->value(), |
| 2032 store_value, | 1952 store_value, |
| 2033 type, | 1953 type, |
| 2034 dst_name, | 1954 dst_name); |
| 2035 temp_index()); | |
| 2036 } | 1955 } |
| 2037 StoreStaticFieldComp* store = | 1956 StoreStaticFieldComp* store = |
| 2038 new StoreStaticFieldComp(node->field(), store_value); | 1957 new StoreStaticFieldComp(node->field(), store_value); |
| 2039 ReturnComputation(store); | 1958 ReturnComputation(store); |
| 2040 } | 1959 } |
| 2041 | 1960 |
| 2042 | 1961 |
| 2043 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 1962 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 2044 ValueGraphVisitor for_array(owner(), temp_index()); | 1963 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2045 node->array()->Visit(&for_array); | 1964 node->array()->Visit(&for_array); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2078 } | 1997 } |
| 2079 | 1998 |
| 2080 | 1999 |
| 2081 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { | 2000 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { |
| 2082 return (node == owner()->parsed_function().node_sequence()) && | 2001 return (node == owner()->parsed_function().node_sequence()) && |
| 2083 (owner()->parsed_function().saved_context_var() != NULL); | 2002 (owner()->parsed_function().saved_context_var() != NULL); |
| 2084 } | 2003 } |
| 2085 | 2004 |
| 2086 | 2005 |
| 2087 void EffectGraphVisitor::UnchainContext() { | 2006 void EffectGraphVisitor::UnchainContext() { |
| 2088 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); | 2007 BindInstr* context = new BindInstr(new CurrentContextComp()); |
| 2089 AddInstruction(context); | 2008 AddInstruction(context); |
| 2090 BindInstr* parent = | 2009 BindInstr* parent = |
| 2091 new BindInstr(temp_index(), | 2010 new BindInstr(new NativeLoadFieldComp( |
| 2092 new NativeLoadFieldComp( | |
| 2093 new UseVal(context), Context::parent_offset())); | 2011 new UseVal(context), Context::parent_offset())); |
| 2094 AddInstruction(parent); | 2012 AddInstruction(parent); |
| 2095 AddInstruction(new DoInstr(new StoreContextComp(new UseVal(parent)))); | 2013 AddInstruction(new DoInstr(new StoreContextComp(new UseVal(parent)))); |
| 2096 } | 2014 } |
| 2097 | 2015 |
| 2098 | 2016 |
| 2099 // <Statement> ::= Sequence { scope: LocalScope | 2017 // <Statement> ::= Sequence { scope: LocalScope |
| 2100 // nodes: <Statement>* | 2018 // nodes: <Statement>* |
| 2101 // label: SourceLabel } | 2019 // label: SourceLabel } |
| 2102 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 2020 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| 2103 LocalScope* scope = node->scope(); | 2021 LocalScope* scope = node->scope(); |
| 2104 const intptr_t num_context_variables = | 2022 const intptr_t num_context_variables = |
| 2105 (scope != NULL) ? scope->num_context_variables() : 0; | 2023 (scope != NULL) ? scope->num_context_variables() : 0; |
| 2106 int previous_context_level = owner()->context_level(); | 2024 int previous_context_level = owner()->context_level(); |
| 2107 if (num_context_variables > 0) { | 2025 if (num_context_variables > 0) { |
| 2108 // The loop local scope declares variables that are captured. | 2026 // The loop local scope declares variables that are captured. |
| 2109 // Allocate and chain a new context. | 2027 // Allocate and chain a new context. |
| 2110 // Allocate context computation (uses current CTX) | 2028 // Allocate context computation (uses current CTX) |
| 2111 BindInstr* allocated_context = | 2029 BindInstr* allocated_context = |
| 2112 new BindInstr(temp_index(), | 2030 new BindInstr(new AllocateContextComp(node->token_index(), |
| 2113 new AllocateContextComp(node->token_index(), | |
| 2114 owner()->try_index(), | 2031 owner()->try_index(), |
| 2115 num_context_variables)); | 2032 num_context_variables)); |
| 2116 AddInstruction(allocated_context); | 2033 AddInstruction(allocated_context); |
| 2117 | 2034 |
| 2118 // If this node_sequence is the body of the function being compiled, and if | 2035 // If this node_sequence is the body of the function being compiled, and if |
| 2119 // this function is not a closure, do not link the current context as the | 2036 // this function is not a closure, do not link the current context as the |
| 2120 // parent of the newly allocated context, as it is not accessible. Instead, | 2037 // parent of the newly allocated context, as it is not accessible. Instead, |
| 2121 // save it in a pre-allocated variable and restore it on exit. | 2038 // save it in a pre-allocated variable and restore it on exit. |
| 2122 if (MustSaveRestoreContext(node)) { | 2039 if (MustSaveRestoreContext(node)) { |
| 2123 BindInstr* current_context = | 2040 BindInstr* current_context = new BindInstr(new CurrentContextComp()); |
| 2124 new BindInstr(temp_index() + 1, new CurrentContextComp()); | |
| 2125 AddInstruction(current_context); | 2041 AddInstruction(current_context); |
| 2126 StoreLocalComp* store_local = new StoreLocalComp( | 2042 StoreLocalComp* store_local = new StoreLocalComp( |
| 2127 *owner()->parsed_function().saved_context_var(), | 2043 *owner()->parsed_function().saved_context_var(), |
| 2128 new UseVal(current_context), | 2044 new UseVal(current_context), |
| 2129 0); | 2045 0); |
| 2130 AddInstruction(new DoInstr(store_local)); | 2046 AddInstruction(new DoInstr(store_local)); |
| 2131 BindInstr* null_context = | 2047 BindInstr* null_context = |
| 2132 new BindInstr(temp_index() + 1, | 2048 new BindInstr(new ConstantVal(Object::ZoneHandle())); |
| 2133 new ConstantVal(Object::ZoneHandle())); | |
| 2134 AddInstruction(null_context); | 2049 AddInstruction(null_context); |
| 2135 StoreContextComp* store_context = | 2050 StoreContextComp* store_context = |
| 2136 new StoreContextComp(new UseVal(null_context)); | 2051 new StoreContextComp(new UseVal(null_context)); |
| 2137 AddInstruction(new DoInstr(store_context)); | 2052 AddInstruction(new DoInstr(store_context)); |
| 2138 } | 2053 } |
| 2139 | 2054 |
| 2140 ChainContextComp* chain_context = | 2055 ChainContextComp* chain_context = |
| 2141 new ChainContextComp(new UseVal(allocated_context)); | 2056 new ChainContextComp(new UseVal(allocated_context)); |
| 2142 AddInstruction(new DoInstr(chain_context)); | 2057 AddInstruction(new DoInstr(chain_context)); |
| 2143 owner()->set_context_level(scope->context_level()); | 2058 owner()->set_context_level(scope->context_level()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2158 const String& temp_name = String::ZoneHandle(String::Concat( | 2073 const String& temp_name = String::ZoneHandle(String::Concat( |
| 2159 parameter.name(), String::Handle(String::NewSymbol("-orig")))); | 2074 parameter.name(), String::Handle(String::NewSymbol("-orig")))); |
| 2160 LocalVariable* temp_local = new LocalVariable( | 2075 LocalVariable* temp_local = new LocalVariable( |
| 2161 0, // Token index. | 2076 0, // Token index. |
| 2162 temp_name, | 2077 temp_name, |
| 2163 Type::ZoneHandle(Type::DynamicType())); // Type. | 2078 Type::ZoneHandle(Type::DynamicType())); // Type. |
| 2164 temp_local->set_index(param_frame_index); | 2079 temp_local->set_index(param_frame_index); |
| 2165 | 2080 |
| 2166 // Copy parameter from local frame to current context. | 2081 // Copy parameter from local frame to current context. |
| 2167 BindInstr* load = | 2082 BindInstr* load = |
| 2168 new BindInstr(temp_index(), | 2083 new BindInstr(new LoadLocalComp(*temp_local, |
| 2169 new LoadLocalComp(*temp_local, | |
| 2170 owner()->context_level())); | 2084 owner()->context_level())); |
| 2171 AddInstruction(load); | 2085 AddInstruction(load); |
| 2172 StoreLocalComp* store_local = new StoreLocalComp( | 2086 StoreLocalComp* store_local = new StoreLocalComp( |
| 2173 parameter, | 2087 parameter, |
| 2174 new UseVal(load), | 2088 new UseVal(load), |
| 2175 owner()->context_level()); | 2089 owner()->context_level()); |
| 2176 AddInstruction(new DoInstr(store_local)); | 2090 AddInstruction(new DoInstr(store_local)); |
| 2177 // Write NULL to the source location to detect buggy accesses and | 2091 // Write NULL to the source location to detect buggy accesses and |
| 2178 // allow GC of passed value if it gets overwritten by a new value in | 2092 // allow GC of passed value if it gets overwritten by a new value in |
| 2179 // the function. | 2093 // the function. |
| 2180 BindInstr* null_constant = | 2094 BindInstr* null_constant = |
| 2181 new BindInstr(temp_index(), | 2095 new BindInstr(new ConstantVal(Object::ZoneHandle())); |
| 2182 new ConstantVal(Object::ZoneHandle())); | |
| 2183 AddInstruction(null_constant); | 2096 AddInstruction(null_constant); |
| 2184 StoreLocalComp* clear_local = new StoreLocalComp( | 2097 StoreLocalComp* clear_local = new StoreLocalComp( |
| 2185 *temp_local, | 2098 *temp_local, |
| 2186 new UseVal(null_constant), | 2099 new UseVal(null_constant), |
| 2187 owner()->context_level()); | 2100 owner()->context_level()); |
| 2188 AddInstruction(new DoInstr(clear_local)); | 2101 AddInstruction(new DoInstr(clear_local)); |
| 2189 } | 2102 } |
| 2190 } | 2103 } |
| 2191 } | 2104 } |
| 2192 } | 2105 } |
| 2193 | 2106 |
| 2194 if (FLAG_enable_type_checks && | 2107 if (FLAG_enable_type_checks && |
| 2195 (node == owner()->parsed_function().node_sequence())) { | 2108 (node == owner()->parsed_function().node_sequence())) { |
| 2196 const int num_params = | 2109 const int num_params = |
| 2197 owner()->parsed_function().function().NumberOfParameters(); | 2110 owner()->parsed_function().function().NumberOfParameters(); |
| 2198 for (int pos = 0; pos < num_params; pos++) { | 2111 for (int pos = 0; pos < num_params; pos++) { |
| 2199 const LocalVariable& parameter = *scope->VariableAt(pos); | 2112 const LocalVariable& parameter = *scope->VariableAt(pos); |
| 2200 ASSERT(parameter.owner() == scope); | 2113 ASSERT(parameter.owner() == scope); |
| 2201 if (!CanSkipTypeCheck(NULL, parameter.type())) { | 2114 if (!CanSkipTypeCheck(NULL, parameter.type())) { |
| 2202 BindInstr* load = | 2115 BindInstr* load = |
| 2203 new BindInstr(temp_index(), | 2116 new BindInstr(new LoadLocalComp(parameter, |
| 2204 new LoadLocalComp(parameter, | |
| 2205 owner()->context_level())); | 2117 owner()->context_level())); |
| 2206 AddInstruction(load); | 2118 AddInstruction(load); |
| 2207 BuildAssertAssignable(parameter.token_index(), | 2119 BuildAssertAssignable(parameter.token_index(), |
| 2208 new UseVal(load), | 2120 new UseVal(load), |
| 2209 parameter.type(), | 2121 parameter.type(), |
| 2210 parameter.name(), | 2122 parameter.name()); |
| 2211 temp_index()); | |
| 2212 } | 2123 } |
| 2213 } | 2124 } |
| 2214 } | 2125 } |
| 2215 | 2126 |
| 2216 intptr_t i = 0; | 2127 intptr_t i = 0; |
| 2217 while (is_open() && (i < node->length())) { | 2128 while (is_open() && (i < node->length())) { |
| 2218 EffectGraphVisitor for_effect(owner(), temp_index()); | 2129 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 2219 node->NodeAt(i++)->Visit(&for_effect); | 2130 node->NodeAt(i++)->Visit(&for_effect); |
| 2220 Append(for_effect); | 2131 Append(for_effect); |
| 2221 if (!is_open()) { | 2132 if (!is_open()) { |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2928 char* chars = reinterpret_cast<char*>( | 2839 char* chars = reinterpret_cast<char*>( |
| 2929 Isolate::Current()->current_zone()->Allocate(len)); | 2840 Isolate::Current()->current_zone()->Allocate(len)); |
| 2930 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2841 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2931 const Error& error = Error::Handle( | 2842 const Error& error = Error::Handle( |
| 2932 LanguageError::New(String::Handle(String::New(chars)))); | 2843 LanguageError::New(String::Handle(String::New(chars)))); |
| 2933 Isolate::Current()->long_jump_base()->Jump(1, error); | 2844 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2934 } | 2845 } |
| 2935 | 2846 |
| 2936 | 2847 |
| 2937 } // namespace dart | 2848 } // namespace dart |
| OLD | NEW |