| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 entry_ = other_fragment.entry(); | 57 entry_ = other_fragment.entry(); |
| 58 exit_ = other_fragment.exit(); | 58 exit_ = other_fragment.exit(); |
| 59 } else { | 59 } else { |
| 60 exit()->set_next(other_fragment.entry()); | 60 exit()->set_next(other_fragment.entry()); |
| 61 exit_ = other_fragment.exit(); | 61 exit_ = other_fragment.exit(); |
| 62 } | 62 } |
| 63 temp_index_ = other_fragment.temp_index(); | 63 temp_index_ = other_fragment.temp_index(); |
| 64 } | 64 } |
| 65 | 65 |
| 66 | 66 |
| 67 Value* EffectGraphVisitor::Bind(Definition* definition) { | 67 Value* EffectGraphVisitor::Bind(Computation* computation) { |
| 68 ASSERT(is_open()); | 68 ASSERT(is_open()); |
| 69 DeallocateTempIndex(definition->InputCount()); | 69 DeallocateTempIndex(computation->InputCount()); |
| 70 definition->set_use_kind(Definition::kValue); | 70 BindInstr* bind_instr = new BindInstr(Definition::kValue, computation); |
| 71 definition->set_temp_index(AllocateTempIndex()); | 71 bind_instr->set_temp_index(AllocateTempIndex()); |
| 72 if (is_empty()) { | 72 if (is_empty()) { |
| 73 entry_ = definition; | 73 entry_ = bind_instr; |
| 74 } else { | 74 } else { |
| 75 exit()->set_next(definition); | 75 exit()->set_next(bind_instr); |
| 76 } | 76 } |
| 77 exit_ = definition; | 77 exit_ = bind_instr; |
| 78 return new Value(definition); | 78 return new Value(bind_instr); |
| 79 } | 79 } |
| 80 | 80 |
| 81 | 81 |
| 82 void EffectGraphVisitor::Do(Definition* definition) { | 82 void EffectGraphVisitor::Do(Computation* computation) { |
| 83 ASSERT(is_open()); | 83 ASSERT(is_open()); |
| 84 DeallocateTempIndex(definition->InputCount()); | 84 DeallocateTempIndex(computation->InputCount()); |
| 85 definition->set_use_kind(Definition::kEffect); | 85 BindInstr* do_instr = new BindInstr(Definition::kEffect, computation); |
| 86 if (is_empty()) { | 86 if (is_empty()) { |
| 87 entry_ = definition; | 87 entry_ = do_instr; |
| 88 } else { | 88 } else { |
| 89 exit()->set_next(definition); | 89 exit()->set_next(do_instr); |
| 90 } | 90 } |
| 91 exit_ = definition; | 91 exit_ = do_instr; |
| 92 } | 92 } |
| 93 | 93 |
| 94 | 94 |
| 95 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { | 95 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { |
| 96 ASSERT(is_open()); | 96 ASSERT(is_open()); |
| 97 ASSERT(instruction->IsPushArgument() || !instruction->IsDefinition()); | 97 ASSERT(!instruction->IsBind()); |
| 98 ASSERT(!instruction->IsBlockEntry()); | 98 ASSERT(!instruction->IsBlockEntry()); |
| 99 DeallocateTempIndex(instruction->InputCount()); | 99 DeallocateTempIndex(instruction->InputCount()); |
| 100 if (is_empty()) { | 100 if (is_empty()) { |
| 101 entry_ = exit_ = instruction; | 101 entry_ = exit_ = instruction; |
| 102 } else { | 102 } else { |
| 103 exit()->set_next(instruction); | 103 exit()->set_next(instruction); |
| 104 exit_ = instruction; | 104 exit_ = instruction; |
| 105 } | 105 } |
| 106 } | 106 } |
| 107 | 107 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 } | 204 } |
| 205 | 205 |
| 206 | 206 |
| 207 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { | 207 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { |
| 208 PushArgumentInstr* result = new PushArgumentInstr(value); | 208 PushArgumentInstr* result = new PushArgumentInstr(value); |
| 209 AddInstruction(result); | 209 AddInstruction(result); |
| 210 return result; | 210 return result; |
| 211 } | 211 } |
| 212 | 212 |
| 213 | 213 |
| 214 Definition* EffectGraphVisitor::BuildStoreLocal( | 214 Computation* EffectGraphVisitor::BuildStoreLocal( |
| 215 const LocalVariable& local, Value* value) { | 215 const LocalVariable& local, Value* value) { |
| 216 if (local.is_captured()) { | 216 if (local.is_captured()) { |
| 217 intptr_t delta = | 217 intptr_t delta = owner()->context_level() - |
| 218 owner()->context_level() - local.owner()->context_level(); | 218 local.owner()->context_level(); |
| 219 ASSERT(delta >= 0); | 219 ASSERT(delta >= 0); |
| 220 Value* context = Bind(new CurrentContextInstr()); | 220 Value* context = Bind(new CurrentContextComp()); |
| 221 while (delta-- > 0) { | 221 while (delta-- > 0) { |
| 222 context = Bind(new LoadVMFieldInstr( | 222 context = Bind(new LoadVMFieldComp( |
| 223 context, Context::parent_offset(), Type::ZoneHandle())); | 223 context, Context::parent_offset(), Type::ZoneHandle())); |
| 224 } | 224 } |
| 225 return new StoreVMFieldInstr( | 225 return new StoreVMFieldComp( |
| 226 context, | 226 context, |
| 227 Context::variable_offset(local.index()), | 227 Context::variable_offset(local.index()), |
| 228 value, | 228 value, |
| 229 local.type()); | 229 local.type()); |
| 230 } else { | 230 } else { |
| 231 return new StoreLocalInstr(local, value, owner()->context_level()); | 231 return new StoreLocalComp(local, value, owner()->context_level()); |
| 232 } | 232 } |
| 233 } | 233 } |
| 234 | 234 |
| 235 | 235 |
| 236 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { | 236 Computation* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { |
| 237 if (local.is_captured()) { | 237 if (local.is_captured()) { |
| 238 intptr_t delta = | 238 intptr_t delta = owner()->context_level() - |
| 239 owner()->context_level() - local.owner()->context_level(); | 239 local.owner()->context_level(); |
| 240 ASSERT(delta >= 0); | 240 ASSERT(delta >= 0); |
| 241 Value* context = Bind(new CurrentContextInstr()); | 241 Value* context = Bind(new CurrentContextComp()); |
| 242 while (delta-- > 0) { | 242 while (delta-- > 0) { |
| 243 context = Bind(new LoadVMFieldInstr( | 243 context = Bind(new LoadVMFieldComp( |
| 244 context, Context::parent_offset(), Type::ZoneHandle())); | 244 context, Context::parent_offset(), Type::ZoneHandle())); |
| 245 } | 245 } |
| 246 return new LoadVMFieldInstr(context, | 246 return new LoadVMFieldComp(context, |
| 247 Context::variable_offset(local.index()), | 247 Context::variable_offset(local.index()), |
| 248 local.type()); | 248 local.type()); |
| 249 } else { | 249 } else { |
| 250 return new LoadLocalInstr(local, owner()->context_level()); | 250 return new LoadLocalComp(local, owner()->context_level()); |
| 251 } | 251 } |
| 252 } | 252 } |
| 253 | 253 |
| 254 | 254 |
| 255 // Stores current context into the 'variable' | 255 // Stores current context into the 'variable' |
| 256 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) { | 256 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) { |
| 257 Value* context = Bind(new CurrentContextInstr()); | 257 Value* context = Bind(new CurrentContextComp()); |
| 258 Do(BuildStoreLocal(variable, context)); | 258 Do(BuildStoreLocal(variable, context)); |
| 259 } | 259 } |
| 260 | 260 |
| 261 | 261 |
| 262 // Loads context saved in 'context_variable' into the current context. | 262 // Loads context saved in 'context_variable' into the current context. |
| 263 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { | 263 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { |
| 264 Value* load_saved_context = Bind(BuildLoadLocal(variable)); | 264 Value* load_saved_context = Bind(BuildLoadLocal(variable)); |
| 265 Do(new StoreContextInstr(load_saved_context)); | 265 Do(new StoreContextComp(load_saved_context)); |
| 266 } | 266 } |
| 267 | 267 |
| 268 | 268 |
| 269 void TestGraphVisitor::ReturnValue(Value* value) { | 269 void TestGraphVisitor::ReturnValue(Value* value) { |
| 270 if (FLAG_enable_type_checks) { | 270 if (FLAG_enable_type_checks) { |
| 271 value = Bind(new AssertBooleanInstr(condition_token_pos(), value)); | 271 value = Bind(new AssertBooleanComp(condition_token_pos(), value)); |
| 272 } | 272 } |
| 273 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 273 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 274 Value* constant_true = Bind(new ConstantInstr(bool_true)); | 274 Value* constant_true = Bind(new ConstantComp(bool_true)); |
| 275 StrictCompareInstr* comp = | 275 StrictCompareComp* comp = |
| 276 new StrictCompareInstr(Token::kEQ_STRICT, value, constant_true); | 276 new StrictCompareComp(Token::kEQ_STRICT, value, constant_true); |
| 277 BranchInstr* branch = new BranchInstr(comp); | 277 BranchInstr* branch = new BranchInstr(comp); |
| 278 AddInstruction(branch); | 278 AddInstruction(branch); |
| 279 CloseFragment(); | 279 CloseFragment(); |
| 280 true_successor_address_ = branch->true_successor_address(); | 280 true_successor_address_ = branch->true_successor_address(); |
| 281 false_successor_address_ = branch->false_successor_address(); | 281 false_successor_address_ = branch->false_successor_address(); |
| 282 } | 282 } |
| 283 | 283 |
| 284 | 284 |
| 285 void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) { | 285 void TestGraphVisitor::MergeBranchWithComparison(ComparisonComp* comp) { |
| 286 ASSERT(!FLAG_enable_type_checks); | 286 ASSERT(!FLAG_enable_type_checks); |
| 287 ControlInstruction* branch; | 287 ControlInstruction* branch; |
| 288 if (Token::IsStrictEqualityOperator(comp->kind())) { | 288 if (Token::IsStrictEqualityOperator(comp->kind())) { |
| 289 branch = new BranchInstr(new StrictCompareInstr(comp->kind(), | 289 branch = new BranchInstr(new StrictCompareComp(comp->kind(), |
| 290 comp->left(), | 290 comp->left(), |
| 291 comp->right())); | 291 comp->right())); |
| 292 } else if (Token::IsEqualityOperator(comp->kind()) && | 292 } else if (Token::IsEqualityOperator(comp->kind()) && |
| 293 (comp->left()->BindsToConstantNull() || | 293 (comp->left()->BindsToConstantNull() || |
| 294 comp->right()->BindsToConstantNull())) { | 294 comp->right()->BindsToConstantNull())) { |
| 295 branch = new BranchInstr(new StrictCompareInstr( | 295 branch = new BranchInstr(new StrictCompareComp( |
| 296 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, | 296 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, |
| 297 comp->left(), | 297 comp->left(), |
| 298 comp->right())); | 298 comp->right())); |
| 299 } else { | 299 } else { |
| 300 branch = new BranchInstr(comp); | 300 branch = new BranchInstr(comp); |
| 301 } | 301 } |
| 302 AddInstruction(branch); | 302 AddInstruction(branch); |
| 303 CloseFragment(); | 303 CloseFragment(); |
| 304 true_successor_address_ = branch->true_successor_address(); | 304 true_successor_address_ = branch->true_successor_address(); |
| 305 false_successor_address_ = branch->false_successor_address(); | 305 false_successor_address_ = branch->false_successor_address(); |
| 306 } | 306 } |
| 307 | 307 |
| 308 | 308 |
| 309 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { | 309 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateComp* comp) { |
| 310 ASSERT(!FLAG_enable_type_checks); | 310 ASSERT(!FLAG_enable_type_checks); |
| 311 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 311 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 312 Value* constant_true = Bind(new ConstantInstr(bool_true)); | 312 Value* constant_true = Bind(new ConstantComp(bool_true)); |
| 313 BranchInstr* branch = new BranchInstr( | 313 BranchInstr* branch = new BranchInstr( |
| 314 new StrictCompareInstr(Token::kNE_STRICT, neg->value(), constant_true)); | 314 new StrictCompareComp(Token::kNE_STRICT, |
| 315 comp->value(), |
| 316 constant_true)); |
| 315 AddInstruction(branch); | 317 AddInstruction(branch); |
| 316 CloseFragment(); | 318 CloseFragment(); |
| 317 true_successor_address_ = branch->true_successor_address(); | 319 true_successor_address_ = branch->true_successor_address(); |
| 318 false_successor_address_ = branch->false_successor_address(); | 320 false_successor_address_ = branch->false_successor_address(); |
| 319 } | 321 } |
| 320 | 322 |
| 321 | 323 |
| 322 void TestGraphVisitor::ReturnDefinition(Definition* definition) { | 324 void TestGraphVisitor::ReturnComputation(Computation* computation) { |
| 323 if (!FLAG_enable_type_checks) { | 325 if (!FLAG_enable_type_checks) { |
| 324 ComparisonInstr* comp = definition->AsComparison(); | 326 if (computation->AsComparison() != NULL) { |
| 325 if (comp != NULL) { | 327 MergeBranchWithComparison(computation->AsComparison()); |
| 326 MergeBranchWithComparison(comp); | |
| 327 return; | 328 return; |
| 328 } | 329 } |
| 329 BooleanNegateInstr* neg = definition->AsBooleanNegate(); | 330 if (computation->IsBooleanNegate()) { |
| 330 if (neg != NULL) { | 331 MergeBranchWithNegate(computation->AsBooleanNegate()); |
| 331 MergeBranchWithNegate(neg); | |
| 332 return; | 332 return; |
| 333 } | 333 } |
| 334 } | 334 } |
| 335 ReturnValue(Bind(definition)); | 335 ReturnValue(Bind(computation)); |
| 336 } | 336 } |
| 337 | 337 |
| 338 | 338 |
| 339 void EffectGraphVisitor::Bailout(const char* reason) { | 339 void EffectGraphVisitor::Bailout(const char* reason) { |
| 340 owner()->Bailout(reason); | 340 owner()->Bailout(reason); |
| 341 } | 341 } |
| 342 | 342 |
| 343 | 343 |
| 344 void EffectGraphVisitor::InlineBailout(const char* reason) { | 344 void EffectGraphVisitor::InlineBailout(const char* reason) { |
| 345 if (owner()->InInliningContext()) owner()->Bailout(reason); | 345 if (owner()->InInliningContext()) owner()->Bailout(reason); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 } | 405 } |
| 406 | 406 |
| 407 | 407 |
| 408 // <Expression> ::= Literal { literal: Instance } | 408 // <Expression> ::= Literal { literal: Instance } |
| 409 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 409 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 410 return; | 410 return; |
| 411 } | 411 } |
| 412 | 412 |
| 413 | 413 |
| 414 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 414 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 415 ReturnDefinition(new ConstantInstr(node->literal())); | 415 ReturnComputation(new ConstantComp(node->literal())); |
| 416 } | 416 } |
| 417 | 417 |
| 418 | 418 |
| 419 // Type nodes only occur as the right-hand side of instanceof comparisons, | 419 // Type nodes only occur as the right-hand side of instanceof comparisons, |
| 420 // and they are handled specially in that context. | 420 // and they are handled specially in that context. |
| 421 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } | 421 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
| 422 | 422 |
| 423 | 423 |
| 424 // Returns true if the type check can be skipped, for example, if the | 424 // Returns true if the type check can be skipped, for example, if the |
| 425 // destination type is Dynamic or if the compile type of the value is a subtype | 425 // destination type is Dynamic or if the compile type of the value is a subtype |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 ValueGraphVisitor for_right_value(owner(), temp_index()); | 524 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 525 node->right()->Visit(&for_right_value); | 525 node->right()->Visit(&for_right_value); |
| 526 Append(for_right_value); | 526 Append(for_right_value); |
| 527 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 527 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 528 | 528 |
| 529 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 529 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 530 new ZoneGrowableArray<PushArgumentInstr*>(2); | 530 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 531 arguments->Add(push_left); | 531 arguments->Add(push_left); |
| 532 arguments->Add(push_right); | 532 arguments->Add(push_right); |
| 533 const String& name = String::ZoneHandle(Symbols::New(node->Name())); | 533 const String& name = String::ZoneHandle(Symbols::New(node->Name())); |
| 534 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 534 InstanceCallComp* call = new InstanceCallComp(node->token_pos(), |
| 535 name, | 535 name, |
| 536 node->kind(), | 536 node->kind(), |
| 537 arguments, | 537 arguments, |
| 538 Array::ZoneHandle(), | 538 Array::ZoneHandle(), |
| 539 2); | 539 2); |
| 540 ReturnDefinition(call); | 540 ReturnComputation(call); |
| 541 } | 541 } |
| 542 | 542 |
| 543 | 543 |
| 544 // Special handling for AND/OR. | 544 // Special handling for AND/OR. |
| 545 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 545 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 546 InlineBailout("ValueGraphVisitor::VisitBinaryOpNode"); | 546 InlineBailout("ValueGraphVisitor::VisitBinaryOpNode"); |
| 547 // Operators "&&" and "||" cannot be overloaded therefore do not call | 547 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 548 // operator. | 548 // operator. |
| 549 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 549 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 550 // Implement short-circuit logic: do not evaluate right if evaluation | 550 // Implement short-circuit logic: do not evaluate right if evaluation |
| 551 // of left is sufficient. | 551 // of left is sufficient. |
| 552 // AND: left ? right === true : false; | 552 // AND: left ? right === true : false; |
| 553 // OR: left ? true : right === true; | 553 // OR: left ? true : right === true; |
| 554 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 554 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 555 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 555 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 556 | 556 |
| 557 TestGraphVisitor for_test(owner(), | 557 TestGraphVisitor for_test(owner(), |
| 558 temp_index(), | 558 temp_index(), |
| 559 node->left()->token_pos()); | 559 node->left()->token_pos()); |
| 560 node->left()->Visit(&for_test); | 560 node->left()->Visit(&for_test); |
| 561 | 561 |
| 562 ValueGraphVisitor for_right(owner(), temp_index()); | 562 ValueGraphVisitor for_right(owner(), temp_index()); |
| 563 node->right()->Visit(&for_right); | 563 node->right()->Visit(&for_right); |
| 564 Value* right_value = for_right.value(); | 564 Value* right_value = for_right.value(); |
| 565 if (FLAG_enable_type_checks) { | 565 if (FLAG_enable_type_checks) { |
| 566 right_value = | 566 right_value = |
| 567 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), | 567 for_right.Bind(new AssertBooleanComp(node->right()->token_pos(), |
| 568 right_value)); | 568 right_value)); |
| 569 } | 569 } |
| 570 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true)); | 570 Value* constant_true = for_right.Bind(new ConstantComp(bool_true)); |
| 571 Value* compare = | 571 Value* compare = |
| 572 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, | 572 for_right.Bind(new StrictCompareComp(Token::kEQ_STRICT, |
| 573 right_value, | 573 right_value, |
| 574 constant_true)); | 574 constant_true)); |
| 575 for_right.Do(BuildStoreLocal( | 575 for_right.Do(BuildStoreLocal( |
| 576 *owner()->parsed_function().expression_temp_var(), | 576 *owner()->parsed_function().expression_temp_var(), |
| 577 compare)); | 577 compare)); |
| 578 | 578 |
| 579 if (node->kind() == Token::kAND) { | 579 if (node->kind() == Token::kAND) { |
| 580 ValueGraphVisitor for_false(owner(), temp_index()); | 580 ValueGraphVisitor for_false(owner(), temp_index()); |
| 581 Value* constant_false = for_false.Bind(new ConstantInstr(bool_false)); | 581 Value* constant_false = for_false.Bind(new ConstantComp(bool_false)); |
| 582 for_false.Do(BuildStoreLocal( | 582 for_false.Do(BuildStoreLocal( |
| 583 *owner()->parsed_function().expression_temp_var(), | 583 *owner()->parsed_function().expression_temp_var(), |
| 584 constant_false)); | 584 constant_false)); |
| 585 Join(for_test, for_right, for_false); | 585 Join(for_test, for_right, for_false); |
| 586 } else { | 586 } else { |
| 587 ASSERT(node->kind() == Token::kOR); | 587 ASSERT(node->kind() == Token::kOR); |
| 588 ValueGraphVisitor for_true(owner(), temp_index()); | 588 ValueGraphVisitor for_true(owner(), temp_index()); |
| 589 Value* constant_true = for_true.Bind(new ConstantInstr(bool_true)); | 589 Value* constant_true = for_true.Bind(new ConstantComp(bool_true)); |
| 590 for_true.Do(BuildStoreLocal( | 590 for_true.Do(BuildStoreLocal( |
| 591 *owner()->parsed_function().expression_temp_var(), | 591 *owner()->parsed_function().expression_temp_var(), |
| 592 constant_true)); | 592 constant_true)); |
| 593 Join(for_test, for_true, for_right); | 593 Join(for_test, for_true, for_right); |
| 594 } | 594 } |
| 595 ReturnDefinition( | 595 ReturnComputation( |
| 596 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); | 596 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); |
| 597 return; | 597 return; |
| 598 } | 598 } |
| 599 EffectGraphVisitor::VisitBinaryOpNode(node); | 599 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 600 } | 600 } |
| 601 | 601 |
| 602 | 602 |
| 603 void EffectGraphVisitor::BuildTypecheckArguments( | 603 void EffectGraphVisitor::BuildTypecheckArguments( |
| 604 intptr_t token_pos, | 604 intptr_t token_pos, |
| 605 Value** instantiator_result, | 605 Value** instantiator_result, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 626 instantiator_type_arguments = | 626 instantiator_type_arguments = |
| 627 BuildInstantiatorTypeArguments(token_pos, loaded); | 627 BuildInstantiatorTypeArguments(token_pos, loaded); |
| 628 } | 628 } |
| 629 *instantiator_result = instantiator; | 629 *instantiator_result = instantiator; |
| 630 *instantiator_type_arguments_result = instantiator_type_arguments; | 630 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 631 } | 631 } |
| 632 | 632 |
| 633 | 633 |
| 634 Value* EffectGraphVisitor::BuildNullValue() { | 634 Value* EffectGraphVisitor::BuildNullValue() { |
| 635 InlineBailout("EffectGraphVisitor::BuildNullValue"); | 635 InlineBailout("EffectGraphVisitor::BuildNullValue"); |
| 636 return Bind(new ConstantInstr(Object::ZoneHandle())); | 636 return Bind(new ConstantComp(Object::ZoneHandle())); |
| 637 } | 637 } |
| 638 | 638 |
| 639 | 639 |
| 640 // Used for testing incoming arguments. | 640 // Used for testing incoming arguments. |
| 641 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( | 641 AssertAssignableComp* EffectGraphVisitor::BuildAssertAssignable( |
| 642 intptr_t token_pos, | 642 intptr_t token_pos, |
| 643 Value* value, | 643 Value* value, |
| 644 const AbstractType& dst_type, | 644 const AbstractType& dst_type, |
| 645 const String& dst_name) { | 645 const String& dst_name) { |
| 646 InlineBailout("EffectGraphVisitor::BuildAssertAssignable"); | 646 InlineBailout("EffectGraphVisitor::BuildAssertAssignable"); |
| 647 // Build the type check computation. | 647 // Build the type check computation. |
| 648 Value* instantiator = NULL; | 648 Value* instantiator = NULL; |
| 649 Value* instantiator_type_arguments = NULL; | 649 Value* instantiator_type_arguments = NULL; |
| 650 if (dst_type.IsInstantiated()) { | 650 if (dst_type.IsInstantiated()) { |
| 651 instantiator = BuildNullValue(); | 651 instantiator = BuildNullValue(); |
| 652 instantiator_type_arguments = BuildNullValue(); | 652 instantiator_type_arguments = BuildNullValue(); |
| 653 } else { | 653 } else { |
| 654 BuildTypecheckArguments(token_pos, | 654 BuildTypecheckArguments(token_pos, |
| 655 &instantiator, | 655 &instantiator, |
| 656 &instantiator_type_arguments); | 656 &instantiator_type_arguments); |
| 657 } | 657 } |
| 658 return new AssertAssignableInstr(token_pos, | 658 return new AssertAssignableComp(token_pos, |
| 659 value, | 659 value, |
| 660 instantiator, | 660 instantiator, |
| 661 instantiator_type_arguments, | 661 instantiator_type_arguments, |
| 662 dst_type, | 662 dst_type, |
| 663 dst_name); | 663 dst_name); |
| 664 } | 664 } |
| 665 | 665 |
| 666 | 666 |
| 667 // Used for type casts and to test assignments. | 667 // Used for type casts and to test assignments. |
| 668 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, | 668 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, |
| 669 Value* value, | 669 Value* value, |
| 670 const AbstractType& dst_type, | 670 const AbstractType& dst_type, |
| 671 const String& dst_name) { | 671 const String& dst_name) { |
| 672 InlineBailout("EffectGraphVisitor::BuildAssignableValue"); | 672 InlineBailout("EffectGraphVisitor::BuildAssignableValue"); |
| 673 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { | 673 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 const AbstractType& type = node->right()->AsTypeNode()->type(); | 711 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 712 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 712 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 713 const bool negate_result = (node->kind() == Token::kISNOT); | 713 const bool negate_result = (node->kind() == Token::kISNOT); |
| 714 // All objects are instances of type T if Object type is a subtype of type T. | 714 // All objects are instances of type T if Object type is a subtype of type T. |
| 715 const Type& object_type = Type::Handle(Type::ObjectType()); | 715 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 716 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 716 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 717 // Must evaluate left side. | 717 // Must evaluate left side. |
| 718 EffectGraphVisitor for_left_value(owner(), temp_index()); | 718 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 719 node->left()->Visit(&for_left_value); | 719 node->left()->Visit(&for_left_value); |
| 720 Append(for_left_value); | 720 Append(for_left_value); |
| 721 ReturnDefinition(new ConstantInstr(negate_result ? bool_false : bool_true)); | 721 ReturnComputation(new ConstantComp(negate_result ? bool_false : bool_true)); |
| 722 return; | 722 return; |
| 723 } | 723 } |
| 724 | 724 |
| 725 // Eliminate the test if it can be performed successfully at compile time. | 725 // Eliminate the test if it can be performed successfully at compile time. |
| 726 if ((node->left() != NULL) && | 726 if ((node->left() != NULL) && |
| 727 node->left()->IsLiteralNode() && | 727 node->left()->IsLiteralNode() && |
| 728 type.IsInstantiated()) { | 728 type.IsInstantiated()) { |
| 729 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); | 729 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); |
| 730 const Class& cls = Class::Handle(literal_value.clazz()); | 730 const Class& cls = Class::Handle(literal_value.clazz()); |
| 731 ConstantInstr* result = NULL; | 731 ConstantComp* result = NULL; |
| 732 if (cls.IsNullClass()) { | 732 if (cls.IsNullClass()) { |
| 733 // A null object is only an instance of Object and Dynamic, which has | 733 // A null object is only an instance of Object and Dynamic, which has |
| 734 // already been checked above (if the type is instantiated). So we can | 734 // already been checked above (if the type is instantiated). So we can |
| 735 // return false here if the instance is null (and if the type is | 735 // return false here if the instance is null (and if the type is |
| 736 // instantiated). | 736 // instantiated). |
| 737 result = new ConstantInstr(negate_result ? bool_true : bool_false); | 737 result = new ConstantComp(negate_result ? bool_true : bool_false); |
| 738 } else { | 738 } else { |
| 739 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { | 739 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { |
| 740 result = new ConstantInstr(negate_result ? bool_false : bool_true); | 740 result = new ConstantComp(negate_result ? bool_false : bool_true); |
| 741 } else { | 741 } else { |
| 742 result = new ConstantInstr(negate_result ? bool_true : bool_false); | 742 result = new ConstantComp(negate_result ? bool_true : bool_false); |
| 743 } | 743 } |
| 744 } | 744 } |
| 745 ReturnDefinition(result); | 745 ReturnComputation(result); |
| 746 return; | 746 return; |
| 747 } | 747 } |
| 748 | 748 |
| 749 ValueGraphVisitor for_left_value(owner(), temp_index()); | 749 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 750 node->left()->Visit(&for_left_value); | 750 node->left()->Visit(&for_left_value); |
| 751 Append(for_left_value); | 751 Append(for_left_value); |
| 752 Value* instantiator = NULL; | 752 Value* instantiator = NULL; |
| 753 Value* instantiator_type_arguments = NULL; | 753 Value* instantiator_type_arguments = NULL; |
| 754 if (type.IsInstantiated()) { | 754 if (type.IsInstantiated()) { |
| 755 instantiator = BuildNullValue(); | 755 instantiator = BuildNullValue(); |
| 756 instantiator_type_arguments = BuildNullValue(); | 756 instantiator_type_arguments = BuildNullValue(); |
| 757 } else { | 757 } else { |
| 758 BuildTypecheckArguments(node->token_pos(), | 758 BuildTypecheckArguments(node->token_pos(), |
| 759 &instantiator, | 759 &instantiator, |
| 760 &instantiator_type_arguments); | 760 &instantiator_type_arguments); |
| 761 } | 761 } |
| 762 InstanceOfInstr* instance_of = | 762 InstanceOfComp* instance_of = |
| 763 new InstanceOfInstr(node->token_pos(), | 763 new InstanceOfComp(node->token_pos(), |
| 764 for_left_value.value(), | 764 for_left_value.value(), |
| 765 instantiator, | 765 instantiator, |
| 766 instantiator_type_arguments, | 766 instantiator_type_arguments, |
| 767 node->right()->AsTypeNode()->type(), | 767 node->right()->AsTypeNode()->type(), |
| 768 (node->kind() == Token::kISNOT)); | 768 (node->kind() == Token::kISNOT)); |
| 769 ReturnDefinition(instance_of); | 769 ReturnComputation(instance_of); |
| 770 } | 770 } |
| 771 | 771 |
| 772 | 772 |
| 773 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 773 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 774 InlineBailout("ValueGraphVisitor::BuildTypeCast"); | 774 InlineBailout("ValueGraphVisitor::BuildTypeCast"); |
| 775 ASSERT(Token::IsTypeCastOperator(node->kind())); | 775 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 776 const AbstractType& type = node->right()->AsTypeNode()->type(); | 776 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 777 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 777 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 778 ValueGraphVisitor for_value(owner(), temp_index()); | 778 ValueGraphVisitor for_value(owner(), temp_index()); |
| 779 node->left()->Visit(&for_value); | 779 node->left()->Visit(&for_value); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 802 return; | 802 return; |
| 803 } | 803 } |
| 804 if ((node->kind() == Token::kEQ_STRICT) || | 804 if ((node->kind() == Token::kEQ_STRICT) || |
| 805 (node->kind() == Token::kNE_STRICT)) { | 805 (node->kind() == Token::kNE_STRICT)) { |
| 806 ValueGraphVisitor for_left_value(owner(), temp_index()); | 806 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 807 node->left()->Visit(&for_left_value); | 807 node->left()->Visit(&for_left_value); |
| 808 Append(for_left_value); | 808 Append(for_left_value); |
| 809 ValueGraphVisitor for_right_value(owner(), temp_index()); | 809 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 810 node->right()->Visit(&for_right_value); | 810 node->right()->Visit(&for_right_value); |
| 811 Append(for_right_value); | 811 Append(for_right_value); |
| 812 StrictCompareInstr* comp = new StrictCompareInstr( | 812 StrictCompareComp* comp = new StrictCompareComp( |
| 813 node->kind(), for_left_value.value(), for_right_value.value()); | 813 node->kind(), for_left_value.value(), for_right_value.value()); |
| 814 ReturnDefinition(comp); | 814 ReturnComputation(comp); |
| 815 return; | 815 return; |
| 816 } | 816 } |
| 817 | 817 |
| 818 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { | 818 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { |
| 819 ValueGraphVisitor for_left_value(owner(), temp_index()); | 819 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 820 node->left()->Visit(&for_left_value); | 820 node->left()->Visit(&for_left_value); |
| 821 Append(for_left_value); | 821 Append(for_left_value); |
| 822 ValueGraphVisitor for_right_value(owner(), temp_index()); | 822 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 823 node->right()->Visit(&for_right_value); | 823 node->right()->Visit(&for_right_value); |
| 824 Append(for_right_value); | 824 Append(for_right_value); |
| 825 if (FLAG_enable_type_checks) { | 825 if (FLAG_enable_type_checks) { |
| 826 EqualityCompareInstr* comp = new EqualityCompareInstr( | 826 EqualityCompareComp* comp = new EqualityCompareComp( |
| 827 node->token_pos(), | 827 node->token_pos(), |
| 828 Token::kEQ, | 828 Token::kEQ, |
| 829 for_left_value.value(), | 829 for_left_value.value(), |
| 830 for_right_value.value()); | 830 for_right_value.value()); |
| 831 if (node->kind() == Token::kEQ) { | 831 if (node->kind() == Token::kEQ) { |
| 832 ReturnDefinition(comp); | 832 ReturnComputation(comp); |
| 833 } else { | 833 } else { |
| 834 Value* eq_result = Bind(comp); | 834 Value* eq_result = Bind(comp); |
| 835 eq_result = Bind(new AssertBooleanInstr(node->token_pos(), eq_result)); | 835 eq_result = Bind(new AssertBooleanComp(node->token_pos(), eq_result)); |
| 836 ReturnDefinition(new BooleanNegateInstr(eq_result)); | 836 ReturnComputation(new BooleanNegateComp(eq_result)); |
| 837 } | 837 } |
| 838 } else { | 838 } else { |
| 839 EqualityCompareInstr* comp = new EqualityCompareInstr( | 839 EqualityCompareComp* comp = new EqualityCompareComp( |
| 840 node->token_pos(), | 840 node->token_pos(), |
| 841 node->kind(), | 841 node->kind(), |
| 842 for_left_value.value(), | 842 for_left_value.value(), |
| 843 for_right_value.value()); | 843 for_right_value.value()); |
| 844 ReturnDefinition(comp); | 844 ReturnComputation(comp); |
| 845 } | 845 } |
| 846 return; | 846 return; |
| 847 } | 847 } |
| 848 | 848 |
| 849 ValueGraphVisitor for_left_value(owner(), temp_index()); | 849 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 850 node->left()->Visit(&for_left_value); | 850 node->left()->Visit(&for_left_value); |
| 851 Append(for_left_value); | 851 Append(for_left_value); |
| 852 ValueGraphVisitor for_right_value(owner(), temp_index()); | 852 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 853 node->right()->Visit(&for_right_value); | 853 node->right()->Visit(&for_right_value); |
| 854 Append(for_right_value); | 854 Append(for_right_value); |
| 855 RelationalOpInstr* comp = new RelationalOpInstr(node->token_pos(), | 855 RelationalOpComp* comp = new RelationalOpComp(node->token_pos(), |
| 856 node->kind(), | 856 node->kind(), |
| 857 for_left_value.value(), | 857 for_left_value.value(), |
| 858 for_right_value.value()); | 858 for_right_value.value()); |
| 859 ReturnDefinition(comp); | 859 ReturnComputation(comp); |
| 860 } | 860 } |
| 861 | 861 |
| 862 | 862 |
| 863 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 863 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| 864 InlineBailout("EffectGraphVisitor::VisitUnaryOpNode"); | 864 InlineBailout("EffectGraphVisitor::VisitUnaryOpNode"); |
| 865 // "!" cannot be overloaded, therefore do not call operator. | 865 // "!" cannot be overloaded, therefore do not call operator. |
| 866 if (node->kind() == Token::kNOT) { | 866 if (node->kind() == Token::kNOT) { |
| 867 ValueGraphVisitor for_value(owner(), temp_index()); | 867 ValueGraphVisitor for_value(owner(), temp_index()); |
| 868 node->operand()->Visit(&for_value); | 868 node->operand()->Visit(&for_value); |
| 869 Append(for_value); | 869 Append(for_value); |
| 870 Value* value = for_value.value(); | 870 Value* value = for_value.value(); |
| 871 if (FLAG_enable_type_checks) { | 871 if (FLAG_enable_type_checks) { |
| 872 value = | 872 value = |
| 873 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); | 873 Bind(new AssertBooleanComp(node->operand()->token_pos(), value)); |
| 874 } | 874 } |
| 875 BooleanNegateInstr* negate = new BooleanNegateInstr(value); | 875 BooleanNegateComp* negate = new BooleanNegateComp(value); |
| 876 ReturnDefinition(negate); | 876 ReturnComputation(negate); |
| 877 return; | 877 return; |
| 878 } | 878 } |
| 879 ValueGraphVisitor for_value(owner(), temp_index()); | 879 ValueGraphVisitor for_value(owner(), temp_index()); |
| 880 node->operand()->Visit(&for_value); | 880 node->operand()->Visit(&for_value); |
| 881 Append(for_value); | 881 Append(for_value); |
| 882 PushArgumentInstr* push_value = PushArgument(for_value.value()); | 882 PushArgumentInstr* push_value = PushArgument(for_value.value()); |
| 883 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 883 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 884 new ZoneGrowableArray<PushArgumentInstr*>(1); | 884 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 885 arguments->Add(push_value); | 885 arguments->Add(push_value); |
| 886 String& name = String::ZoneHandle(); | 886 String& name = String::ZoneHandle(); |
| 887 if (node->kind() == Token::kSUB) { | 887 if (node->kind() == Token::kSUB) { |
| 888 name = Symbols::New("unary-"); | 888 name = Symbols::New("unary-"); |
| 889 } else { | 889 } else { |
| 890 name = Symbols::New(Token::Str(node->kind())); | 890 name = Symbols::New(Token::Str(node->kind())); |
| 891 } | 891 } |
| 892 InstanceCallInstr* call = new InstanceCallInstr( | 892 InstanceCallComp* call = new InstanceCallComp( |
| 893 node->token_pos(), name, node->kind(), | 893 node->token_pos(), name, node->kind(), |
| 894 arguments, Array::ZoneHandle(), 1); | 894 arguments, Array::ZoneHandle(), 1); |
| 895 ReturnDefinition(call); | 895 ReturnComputation(call); |
| 896 } | 896 } |
| 897 | 897 |
| 898 | 898 |
| 899 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 899 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 900 InlineBailout("EffectGraphVisitor::VisitConditionalExprNode"); | 900 InlineBailout("EffectGraphVisitor::VisitConditionalExprNode"); |
| 901 TestGraphVisitor for_test(owner(), | 901 TestGraphVisitor for_test(owner(), |
| 902 temp_index(), | 902 temp_index(), |
| 903 node->condition()->token_pos()); | 903 node->condition()->token_pos()); |
| 904 node->condition()->Visit(&for_test); | 904 node->condition()->Visit(&for_test); |
| 905 | 905 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 926 for_true.Do(BuildStoreLocal( | 926 for_true.Do(BuildStoreLocal( |
| 927 *owner()->parsed_function().expression_temp_var(), for_true.value())); | 927 *owner()->parsed_function().expression_temp_var(), for_true.value())); |
| 928 | 928 |
| 929 ValueGraphVisitor for_false(owner(), temp_index()); | 929 ValueGraphVisitor for_false(owner(), temp_index()); |
| 930 node->false_expr()->Visit(&for_false); | 930 node->false_expr()->Visit(&for_false); |
| 931 ASSERT(for_false.is_open()); | 931 ASSERT(for_false.is_open()); |
| 932 for_false.Do(BuildStoreLocal( | 932 for_false.Do(BuildStoreLocal( |
| 933 *owner()->parsed_function().expression_temp_var(), for_false.value())); | 933 *owner()->parsed_function().expression_temp_var(), for_false.value())); |
| 934 | 934 |
| 935 Join(for_test, for_true, for_false); | 935 Join(for_test, for_true, for_false); |
| 936 ReturnDefinition( | 936 ReturnComputation( |
| 937 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); | 937 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); |
| 938 } | 938 } |
| 939 | 939 |
| 940 | 940 |
| 941 // <Statement> ::= If { condition: <Expression> | 941 // <Statement> ::= If { condition: <Expression> |
| 942 // true_branch: <Sequence> | 942 // true_branch: <Sequence> |
| 943 // false_branch: <Sequence> } | 943 // false_branch: <Sequence> } |
| 944 void EffectGraphVisitor::VisitIfNode(IfNode* node) { | 944 void EffectGraphVisitor::VisitIfNode(IfNode* node) { |
| 945 TestGraphVisitor for_test(owner(), | 945 TestGraphVisitor for_test(owner(), |
| 946 temp_index(), | 946 temp_index(), |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1097 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { | 1097 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
| 1098 InlineBailout("EffectGraphVisitor::VisitWhileNode"); | 1098 InlineBailout("EffectGraphVisitor::VisitWhileNode"); |
| 1099 TestGraphVisitor for_test(owner(), | 1099 TestGraphVisitor for_test(owner(), |
| 1100 temp_index(), | 1100 temp_index(), |
| 1101 node->condition()->token_pos()); | 1101 node->condition()->token_pos()); |
| 1102 node->condition()->Visit(&for_test); | 1102 node->condition()->Visit(&for_test); |
| 1103 ASSERT(!for_test.is_empty()); // Language spec. | 1103 ASSERT(!for_test.is_empty()); // Language spec. |
| 1104 | 1104 |
| 1105 EffectGraphVisitor for_body(owner(), temp_index()); | 1105 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1106 for_body.Do( | 1106 for_body.Do( |
| 1107 new CheckStackOverflowInstr(node->token_pos())); | 1107 new CheckStackOverflowComp(node->token_pos())); |
| 1108 node->body()->Visit(&for_body); | 1108 node->body()->Visit(&for_body); |
| 1109 | 1109 |
| 1110 // Labels are set after body traversal. | 1110 // Labels are set after body traversal. |
| 1111 SourceLabel* lbl = node->label(); | 1111 SourceLabel* lbl = node->label(); |
| 1112 ASSERT(lbl != NULL); | 1112 ASSERT(lbl != NULL); |
| 1113 JoinEntryInstr* join = lbl->join_for_continue(); | 1113 JoinEntryInstr* join = lbl->join_for_continue(); |
| 1114 if (join != NULL) { | 1114 if (join != NULL) { |
| 1115 if (for_body.is_open()) for_body.Goto(join); | 1115 if (for_body.is_open()) for_body.Goto(join); |
| 1116 for_body.exit_ = join; | 1116 for_body.exit_ = join; |
| 1117 } | 1117 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1130 // c) test-entry (continue-join or body-exit-target) | 1130 // c) test-entry (continue-join or body-exit-target) |
| 1131 // d) [ test-entry ] -> (back-target, loop-exit-target) | 1131 // d) [ test-entry ] -> (back-target, loop-exit-target) |
| 1132 // e) back-target -> (body-entry-join) | 1132 // e) back-target -> (body-entry-join) |
| 1133 // f) loop-exit-target | 1133 // f) loop-exit-target |
| 1134 // g) break-join | 1134 // g) break-join |
| 1135 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { | 1135 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
| 1136 InlineBailout("EffectGraphVisitor::VisitDoWhileNode"); | 1136 InlineBailout("EffectGraphVisitor::VisitDoWhileNode"); |
| 1137 // Traverse body first in order to generate continue and break labels. | 1137 // Traverse body first in order to generate continue and break labels. |
| 1138 EffectGraphVisitor for_body(owner(), temp_index()); | 1138 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1139 for_body.Do( | 1139 for_body.Do( |
| 1140 new CheckStackOverflowInstr(node->token_pos())); | 1140 new CheckStackOverflowComp(node->token_pos())); |
| 1141 node->body()->Visit(&for_body); | 1141 node->body()->Visit(&for_body); |
| 1142 | 1142 |
| 1143 TestGraphVisitor for_test(owner(), | 1143 TestGraphVisitor for_test(owner(), |
| 1144 temp_index(), | 1144 temp_index(), |
| 1145 node->condition()->token_pos()); | 1145 node->condition()->token_pos()); |
| 1146 node->condition()->Visit(&for_test); | 1146 node->condition()->Visit(&for_test); |
| 1147 ASSERT(is_open()); | 1147 ASSERT(is_open()); |
| 1148 | 1148 |
| 1149 // Tie do-while loop (test is after the body). | 1149 // Tie do-while loop (test is after the body). |
| 1150 JoinEntryInstr* body_entry_join = new JoinEntryInstr(owner()->try_index()); | 1150 JoinEntryInstr* body_entry_join = new JoinEntryInstr(owner()->try_index()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1191 void EffectGraphVisitor::VisitForNode(ForNode* node) { | 1191 void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| 1192 InlineBailout("EffectGraphVisitor::VisitForNode"); | 1192 InlineBailout("EffectGraphVisitor::VisitForNode"); |
| 1193 EffectGraphVisitor for_initializer(owner(), temp_index()); | 1193 EffectGraphVisitor for_initializer(owner(), temp_index()); |
| 1194 node->initializer()->Visit(&for_initializer); | 1194 node->initializer()->Visit(&for_initializer); |
| 1195 Append(for_initializer); | 1195 Append(for_initializer); |
| 1196 ASSERT(is_open()); | 1196 ASSERT(is_open()); |
| 1197 | 1197 |
| 1198 // Compose body to set any jump labels. | 1198 // Compose body to set any jump labels. |
| 1199 EffectGraphVisitor for_body(owner(), temp_index()); | 1199 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1200 for_body.Do( | 1200 for_body.Do( |
| 1201 new CheckStackOverflowInstr(node->token_pos())); | 1201 new CheckStackOverflowComp(node->token_pos())); |
| 1202 node->body()->Visit(&for_body); | 1202 node->body()->Visit(&for_body); |
| 1203 | 1203 |
| 1204 // Join loop body, increment and compute their end instruction. | 1204 // Join loop body, increment and compute their end instruction. |
| 1205 ASSERT(!for_body.is_empty()); | 1205 ASSERT(!for_body.is_empty()); |
| 1206 Instruction* loop_increment_end = NULL; | 1206 Instruction* loop_increment_end = NULL; |
| 1207 EffectGraphVisitor for_increment(owner(), temp_index()); | 1207 EffectGraphVisitor for_increment(owner(), temp_index()); |
| 1208 node->increment()->Visit(&for_increment); | 1208 node->increment()->Visit(&for_increment); |
| 1209 JoinEntryInstr* join = node->label()->join_for_continue(); | 1209 JoinEntryInstr* join = node->label()->join_for_continue(); |
| 1210 if (join != NULL) { | 1210 if (join != NULL) { |
| 1211 // Insert the join between the body and increment. | 1211 // Insert the join between the body and increment. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 | 1317 |
| 1318 | 1318 |
| 1319 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { | 1319 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { |
| 1320 InlineBailout("EffectGraphVisitor::VisitArgumentListNode"); | 1320 InlineBailout("EffectGraphVisitor::VisitArgumentListNode"); |
| 1321 UNREACHABLE(); | 1321 UNREACHABLE(); |
| 1322 } | 1322 } |
| 1323 | 1323 |
| 1324 | 1324 |
| 1325 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( | 1325 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( |
| 1326 ArgumentDefinitionTestNode* node) { | 1326 ArgumentDefinitionTestNode* node) { |
| 1327 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); | 1327 Computation* load = BuildLoadLocal(node->saved_arguments_descriptor()); |
| 1328 Value* arguments_descriptor = Bind(load); | 1328 Value* arguments_descriptor = Bind(load); |
| 1329 ArgumentDefinitionTestInstr* arg_def_test = | 1329 ArgumentDefinitionTestComp* arg_def_test = |
| 1330 new ArgumentDefinitionTestInstr(node, arguments_descriptor); | 1330 new ArgumentDefinitionTestComp(node, arguments_descriptor); |
| 1331 ReturnDefinition(arg_def_test); | 1331 ReturnComputation(arg_def_test); |
| 1332 } | 1332 } |
| 1333 | 1333 |
| 1334 | 1334 |
| 1335 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 1335 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 1336 InlineBailout("EffectGraphVisitor::VisitArrayNode"); | 1336 InlineBailout("EffectGraphVisitor::VisitArrayNode"); |
| 1337 // Translate the array elements and collect their values. | 1337 // Translate the array elements and collect their values. |
| 1338 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1338 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1339 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); | 1339 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); |
| 1340 for (int i = 0; i < node->length(); ++i) { | 1340 for (int i = 0; i < node->length(); ++i) { |
| 1341 ValueGraphVisitor for_value(owner(), temp_index()); | 1341 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1342 node->ElementAt(i)->Visit(&for_value); | 1342 node->ElementAt(i)->Visit(&for_value); |
| 1343 Append(for_value); | 1343 Append(for_value); |
| 1344 arguments->Add(PushArgument(for_value.value())); | 1344 arguments->Add(PushArgument(for_value.value())); |
| 1345 } | 1345 } |
| 1346 const AbstractTypeArguments& type_args = | 1346 const AbstractTypeArguments& type_args = |
| 1347 AbstractTypeArguments::ZoneHandle(node->type().arguments()); | 1347 AbstractTypeArguments::ZoneHandle(node->type().arguments()); |
| 1348 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 1348 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
| 1349 type_args); | 1349 type_args); |
| 1350 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), | 1350 CreateArrayComp* create = new CreateArrayComp(node->token_pos(), |
| 1351 arguments, | 1351 arguments, |
| 1352 node->type(), | 1352 node->type(), |
| 1353 element_type); | 1353 element_type); |
| 1354 ReturnDefinition(create); | 1354 ReturnComputation(create); |
| 1355 } | 1355 } |
| 1356 | 1356 |
| 1357 | 1357 |
| 1358 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 1358 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 1359 InlineBailout("EffectGraphVisitor::VisitClosureNode"); | 1359 InlineBailout("EffectGraphVisitor::VisitClosureNode"); |
| 1360 const Function& function = node->function(); | 1360 const Function& function = node->function(); |
| 1361 | 1361 |
| 1362 Value* receiver = NULL; | 1362 Value* receiver = NULL; |
| 1363 if (function.IsNonImplicitClosureFunction()) { | 1363 if (function.IsNonImplicitClosureFunction()) { |
| 1364 // The context scope may have already been set by the non-optimizing | 1364 // The context scope may have already been set by the non-optimizing |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1393 const bool requires_type_arguments = cls.HasTypeArguments(); | 1393 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1394 Value* type_arguments = NULL; | 1394 Value* type_arguments = NULL; |
| 1395 if (requires_type_arguments) { | 1395 if (requires_type_arguments) { |
| 1396 ASSERT(!function.IsImplicitStaticClosureFunction()); | 1396 ASSERT(!function.IsImplicitStaticClosureFunction()); |
| 1397 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), NULL); | 1397 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), NULL); |
| 1398 } else { | 1398 } else { |
| 1399 type_arguments = BuildNullValue(); | 1399 type_arguments = BuildNullValue(); |
| 1400 } | 1400 } |
| 1401 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); | 1401 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); |
| 1402 arguments->Add(push_type_arguments); | 1402 arguments->Add(push_type_arguments); |
| 1403 ReturnDefinition(new CreateClosureInstr(node, arguments)); | 1403 ReturnComputation(new CreateClosureComp(node, arguments)); |
| 1404 } | 1404 } |
| 1405 | 1405 |
| 1406 | 1406 |
| 1407 void EffectGraphVisitor::TranslateArgumentList( | 1407 void EffectGraphVisitor::TranslateArgumentList( |
| 1408 const ArgumentListNode& node, | 1408 const ArgumentListNode& node, |
| 1409 ZoneGrowableArray<Value*>* values) { | 1409 ZoneGrowableArray<Value*>* values) { |
| 1410 InlineBailout("EffectGraphVisitor::TranslateArgumentList"); | 1410 InlineBailout("EffectGraphVisitor::TranslateArgumentList"); |
| 1411 for (intptr_t i = 0; i < node.length(); ++i) { | 1411 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1412 ValueGraphVisitor for_argument(owner(), temp_index()); | 1412 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 1413 node.NodeAt(i)->Visit(&for_argument); | 1413 node.NodeAt(i)->Visit(&for_argument); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1436 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1436 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1437 node->receiver()->Visit(&for_receiver); | 1437 node->receiver()->Visit(&for_receiver); |
| 1438 Append(for_receiver); | 1438 Append(for_receiver); |
| 1439 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1439 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1440 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1440 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1441 new ZoneGrowableArray<PushArgumentInstr*>( | 1441 new ZoneGrowableArray<PushArgumentInstr*>( |
| 1442 node->arguments()->length() + 1); | 1442 node->arguments()->length() + 1); |
| 1443 arguments->Add(push_receiver); | 1443 arguments->Add(push_receiver); |
| 1444 | 1444 |
| 1445 BuildPushArguments(*node->arguments(), arguments); | 1445 BuildPushArguments(*node->arguments(), arguments); |
| 1446 InstanceCallInstr* call = new InstanceCallInstr( | 1446 InstanceCallComp* call = new InstanceCallComp( |
| 1447 node->token_pos(), | 1447 node->token_pos(), |
| 1448 node->function_name(), Token::kILLEGAL, arguments, | 1448 node->function_name(), Token::kILLEGAL, arguments, |
| 1449 node->arguments()->names(), 1); | 1449 node->arguments()->names(), 1); |
| 1450 ReturnDefinition(call); | 1450 ReturnComputation(call); |
| 1451 } | 1451 } |
| 1452 | 1452 |
| 1453 | 1453 |
| 1454 // <Expression> ::= StaticCall { function: Function | 1454 // <Expression> ::= StaticCall { function: Function |
| 1455 // arguments: <ArgumentList> } | 1455 // arguments: <ArgumentList> } |
| 1456 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 1456 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 1457 InlineBailout("EffectGraphVisitor::VisitStaticCallNode"); | 1457 InlineBailout("EffectGraphVisitor::VisitStaticCallNode"); |
| 1458 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1458 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1459 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1459 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1460 BuildPushArguments(*node->arguments(), arguments); | 1460 BuildPushArguments(*node->arguments(), arguments); |
| 1461 StaticCallInstr* call = | 1461 StaticCallComp* call = |
| 1462 new StaticCallInstr(node->token_pos(), | 1462 new StaticCallComp(node->token_pos(), |
| 1463 node->function(), | 1463 node->function(), |
| 1464 node->arguments()->names(), | 1464 node->arguments()->names(), |
| 1465 arguments); | 1465 arguments); |
| 1466 ReturnDefinition(call); | 1466 ReturnComputation(call); |
| 1467 } | 1467 } |
| 1468 | 1468 |
| 1469 | 1469 |
| 1470 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( | 1470 ClosureCallComp* EffectGraphVisitor::BuildClosureCall( |
| 1471 ClosureCallNode* node) { | 1471 ClosureCallNode* node) { |
| 1472 InlineBailout("EffectGraphVisitor::BuildClosureCall"); | 1472 InlineBailout("EffectGraphVisitor::BuildClosureCall"); |
| 1473 ValueGraphVisitor for_closure(owner(), temp_index()); | 1473 ValueGraphVisitor for_closure(owner(), temp_index()); |
| 1474 node->closure()->Visit(&for_closure); | 1474 node->closure()->Visit(&for_closure); |
| 1475 Append(for_closure); | 1475 Append(for_closure); |
| 1476 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); | 1476 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); |
| 1477 | 1477 |
| 1478 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1478 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1479 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1479 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1480 arguments->Add(push_closure); | 1480 arguments->Add(push_closure); |
| 1481 BuildPushArguments(*node->arguments(), arguments); | 1481 BuildPushArguments(*node->arguments(), arguments); |
| 1482 | 1482 |
| 1483 // Save context around the call. | 1483 // Save context around the call. |
| 1484 BuildStoreContext(*owner()->parsed_function().expression_temp_var()); | 1484 BuildStoreContext(*owner()->parsed_function().expression_temp_var()); |
| 1485 return new ClosureCallInstr(node, arguments); | 1485 return new ClosureCallComp(node, arguments); |
| 1486 } | 1486 } |
| 1487 | 1487 |
| 1488 | 1488 |
| 1489 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1489 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1490 InlineBailout("EffectGraphVisitor::VisitClosureCallNode"); | 1490 InlineBailout("EffectGraphVisitor::VisitClosureCallNode"); |
| 1491 Do(BuildClosureCall(node)); | 1491 Do(BuildClosureCall(node)); |
| 1492 // Restore context from saved location. | 1492 // Restore context from saved location. |
| 1493 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); | 1493 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); |
| 1494 } | 1494 } |
| 1495 | 1495 |
| 1496 | 1496 |
| 1497 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1497 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1498 InlineBailout("ValueGraphVisitor::VisitClosureCallNode"); | 1498 InlineBailout("ValueGraphVisitor::VisitClosureCallNode"); |
| 1499 Value* result = Bind(BuildClosureCall(node)); | 1499 Value* result = Bind(BuildClosureCall(node)); |
| 1500 // Restore context from temp. | 1500 // Restore context from temp. |
| 1501 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); | 1501 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); |
| 1502 ReturnValue(result); | 1502 ReturnValue(result); |
| 1503 } | 1503 } |
| 1504 | 1504 |
| 1505 | 1505 |
| 1506 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 1506 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 1507 InlineBailout("EffectGraphVisitor::VisitCloneContextNode"); | 1507 InlineBailout("EffectGraphVisitor::VisitCloneContextNode"); |
| 1508 Value* context = Bind(new CurrentContextInstr()); | 1508 Value* context = Bind(new CurrentContextComp()); |
| 1509 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); | 1509 Value* clone = Bind(new CloneContextComp(node->token_pos(), context)); |
| 1510 ReturnDefinition(new StoreContextInstr(clone)); | 1510 ReturnComputation(new StoreContextComp(clone)); |
| 1511 } | 1511 } |
| 1512 | 1512 |
| 1513 | 1513 |
| 1514 Value* EffectGraphVisitor::BuildObjectAllocation( | 1514 Value* EffectGraphVisitor::BuildObjectAllocation( |
| 1515 ConstructorCallNode* node) { | 1515 ConstructorCallNode* node) { |
| 1516 InlineBailout("EffectGraphVisitor::BuildObjectAllocation"); | 1516 InlineBailout("EffectGraphVisitor::BuildObjectAllocation"); |
| 1517 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 1517 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 1518 const bool requires_type_arguments = cls.HasTypeArguments(); | 1518 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1519 | 1519 |
| 1520 // In checked mode, if the type arguments are uninstantiated, they may need to | 1520 // In checked mode, if the type arguments are uninstantiated, they may need to |
| 1521 // be checked against declared bounds at run time. | 1521 // be checked against declared bounds at run time. |
| 1522 Definition* allocate_comp = NULL; | 1522 Computation* allocate_comp = NULL; |
| 1523 if (FLAG_enable_type_checks && | 1523 if (FLAG_enable_type_checks && |
| 1524 requires_type_arguments && | 1524 requires_type_arguments && |
| 1525 !node->type_arguments().IsNull() && | 1525 !node->type_arguments().IsNull() && |
| 1526 !node->type_arguments().IsInstantiated() && | 1526 !node->type_arguments().IsInstantiated() && |
| 1527 !node->type_arguments().IsWithinBoundsOf(cls, | 1527 !node->type_arguments().IsWithinBoundsOf(cls, |
| 1528 node->type_arguments(), | 1528 node->type_arguments(), |
| 1529 NULL)) { | 1529 NULL)) { |
| 1530 Value* type_arguments = NULL; | 1530 Value* type_arguments = NULL; |
| 1531 Value* instantiator = NULL; | 1531 Value* instantiator = NULL; |
| 1532 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); | 1532 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); |
| 1533 | 1533 |
| 1534 // The uninstantiated type arguments cannot be verified to be within their | 1534 // The uninstantiated type arguments cannot be verified to be within their |
| 1535 // bounds at compile time, so verify them at runtime. | 1535 // bounds at compile time, so verify them at runtime. |
| 1536 // Although the type arguments may be uninstantiated at compile time, they | 1536 // Although the type arguments may be uninstantiated at compile time, they |
| 1537 // may represent the identity vector and may be replaced by the instantiated | 1537 // may represent the identity vector and may be replaced by the instantiated |
| 1538 // type arguments of the instantiator at run time. | 1538 // type arguments of the instantiator at run time. |
| 1539 allocate_comp = new AllocateObjectWithBoundsCheckInstr(node, | 1539 allocate_comp = new AllocateObjectWithBoundsCheckComp(node, |
| 1540 type_arguments, | 1540 type_arguments, |
| 1541 instantiator); | 1541 instantiator); |
| 1542 } else { | 1542 } else { |
| 1543 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | 1543 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
| 1544 new ZoneGrowableArray<PushArgumentInstr*>(); | 1544 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1545 | 1545 |
| 1546 if (requires_type_arguments) { | 1546 if (requires_type_arguments) { |
| 1547 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); | 1547 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); |
| 1548 } | 1548 } |
| 1549 | 1549 |
| 1550 allocate_comp = new AllocateObjectInstr(node, allocate_arguments); | 1550 allocate_comp = new AllocateObjectComp(node, allocate_arguments); |
| 1551 } | 1551 } |
| 1552 return Bind(allocate_comp); | 1552 return Bind(allocate_comp); |
| 1553 } | 1553 } |
| 1554 | 1554 |
| 1555 | 1555 |
| 1556 void EffectGraphVisitor::BuildConstructorCall( | 1556 void EffectGraphVisitor::BuildConstructorCall( |
| 1557 ConstructorCallNode* node, | 1557 ConstructorCallNode* node, |
| 1558 PushArgumentInstr* push_alloc_value) { | 1558 PushArgumentInstr* push_alloc_value) { |
| 1559 InlineBailout("EffectGraphVisitor::BuildConstructorCall"); | 1559 InlineBailout("EffectGraphVisitor::BuildConstructorCall"); |
| 1560 Value* ctor_arg = Bind( | 1560 Value* ctor_arg = Bind( |
| 1561 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 1561 new ConstantComp(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
| 1562 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); | 1562 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
| 1563 | 1563 |
| 1564 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1564 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1565 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1565 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1566 arguments->Add(push_alloc_value); | 1566 arguments->Add(push_alloc_value); |
| 1567 arguments->Add(push_ctor_arg); | 1567 arguments->Add(push_ctor_arg); |
| 1568 | 1568 |
| 1569 BuildPushArguments(*node->arguments(), arguments); | 1569 BuildPushArguments(*node->arguments(), arguments); |
| 1570 Do(new StaticCallInstr(node->token_pos(), | 1570 Do(new StaticCallComp(node->token_pos(), |
| 1571 node->constructor(), | 1571 node->constructor(), |
| 1572 node->arguments()->names(), | 1572 node->arguments()->names(), |
| 1573 arguments)); | 1573 arguments)); |
| 1574 } | 1574 } |
| 1575 | 1575 |
| 1576 | 1576 |
| 1577 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1577 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1578 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); | 1578 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); |
| 1579 if (node->constructor().IsFactory()) { | 1579 if (node->constructor().IsFactory()) { |
| 1580 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1580 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1581 new ZoneGrowableArray<PushArgumentInstr*>(); | 1581 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1582 PushArgumentInstr* push_type_arguments = PushArgument( | 1582 PushArgumentInstr* push_type_arguments = PushArgument( |
| 1583 BuildInstantiatedTypeArguments(node->token_pos(), | 1583 BuildInstantiatedTypeArguments(node->token_pos(), |
| 1584 node->type_arguments())); | 1584 node->type_arguments())); |
| 1585 arguments->Add(push_type_arguments); | 1585 arguments->Add(push_type_arguments); |
| 1586 ASSERT(arguments->length() == 1); | 1586 ASSERT(arguments->length() == 1); |
| 1587 BuildPushArguments(*node->arguments(), arguments); | 1587 BuildPushArguments(*node->arguments(), arguments); |
| 1588 StaticCallInstr* call = | 1588 StaticCallComp* call = |
| 1589 new StaticCallInstr(node->token_pos(), | 1589 new StaticCallComp(node->token_pos(), |
| 1590 node->constructor(), | 1590 node->constructor(), |
| 1591 node->arguments()->names(), | 1591 node->arguments()->names(), |
| 1592 arguments); | 1592 arguments); |
| 1593 ReturnDefinition(call); | 1593 ReturnComputation(call); |
| 1594 return; | 1594 return; |
| 1595 } | 1595 } |
| 1596 // t_n contains the allocated and initialized object. | 1596 // t_n contains the allocated and initialized object. |
| 1597 // t_n <- AllocateObject(class) | 1597 // t_n <- AllocateObject(class) |
| 1598 // t_n+1 <- ctor-arg | 1598 // t_n+1 <- ctor-arg |
| 1599 // t_n+2... <- constructor arguments start here | 1599 // t_n+2... <- constructor arguments start here |
| 1600 // StaticCall(constructor, t_n+1, t_n+2, ...) | 1600 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 1601 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 1601 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 1602 Value* allocated_value = BuildObjectAllocation(node); | 1602 Value* allocated_value = BuildObjectAllocation(node); |
| 1603 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 1603 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1640 // The type arguments are compile time constants. | 1640 // The type arguments are compile time constants. |
| 1641 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 1641 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 1642 // Type is temporary. Only its type arguments are preserved. | 1642 // Type is temporary. Only its type arguments are preserved. |
| 1643 Type& type = Type::Handle( | 1643 Type& type = Type::Handle( |
| 1644 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 1644 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
| 1645 type ^= ClassFinalizer::FinalizeType( | 1645 type ^= ClassFinalizer::FinalizeType( |
| 1646 instantiator_class, type, ClassFinalizer::kFinalize); | 1646 instantiator_class, type, ClassFinalizer::kFinalize); |
| 1647 ASSERT(!type.IsMalformed()); | 1647 ASSERT(!type.IsMalformed()); |
| 1648 type_arguments = type.arguments(); | 1648 type_arguments = type.arguments(); |
| 1649 type_arguments = type_arguments.Canonicalize(); | 1649 type_arguments = type_arguments.Canonicalize(); |
| 1650 return Bind(new ConstantInstr(type_arguments)); | 1650 return Bind(new ConstantComp(type_arguments)); |
| 1651 } | 1651 } |
| 1652 Function& outer_function = | 1652 Function& outer_function = |
| 1653 Function::Handle(owner()->parsed_function().function().raw()); | 1653 Function::Handle(owner()->parsed_function().function().raw()); |
| 1654 while (outer_function.IsLocalFunction()) { | 1654 while (outer_function.IsLocalFunction()) { |
| 1655 outer_function = outer_function.parent_function(); | 1655 outer_function = outer_function.parent_function(); |
| 1656 } | 1656 } |
| 1657 if (outer_function.IsFactory()) { | 1657 if (outer_function.IsFactory()) { |
| 1658 // No instantiator for factories. | 1658 // No instantiator for factories. |
| 1659 ASSERT(instantiator == NULL); | 1659 ASSERT(instantiator == NULL); |
| 1660 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1660 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1661 ValueGraphVisitor for_instantiator(owner(), temp_index()); | 1661 ValueGraphVisitor for_instantiator(owner(), temp_index()); |
| 1662 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1662 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1663 Append(for_instantiator); | 1663 Append(for_instantiator); |
| 1664 return for_instantiator.value(); | 1664 return for_instantiator.value(); |
| 1665 } | 1665 } |
| 1666 if (instantiator == NULL) { | 1666 if (instantiator == NULL) { |
| 1667 instantiator = BuildInstantiator(); | 1667 instantiator = BuildInstantiator(); |
| 1668 } | 1668 } |
| 1669 // The instantiator is the receiver of the caller, which is not a factory. | 1669 // The instantiator is the receiver of the caller, which is not a factory. |
| 1670 // The receiver cannot be null; extract its AbstractTypeArguments object. | 1670 // The receiver cannot be null; extract its AbstractTypeArguments object. |
| 1671 // Note that in the factory case, the instantiator is the first parameter | 1671 // Note that in the factory case, the instantiator is the first parameter |
| 1672 // of the factory, i.e. already an AbstractTypeArguments object. | 1672 // of the factory, i.e. already an AbstractTypeArguments object. |
| 1673 intptr_t type_arguments_instance_field_offset = | 1673 intptr_t type_arguments_instance_field_offset = |
| 1674 instantiator_class.type_arguments_instance_field_offset(); | 1674 instantiator_class.type_arguments_instance_field_offset(); |
| 1675 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); | 1675 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); |
| 1676 | 1676 |
| 1677 return Bind(new LoadVMFieldInstr( | 1677 return Bind(new LoadVMFieldComp( |
| 1678 instantiator, | 1678 instantiator, |
| 1679 type_arguments_instance_field_offset, | 1679 type_arguments_instance_field_offset, |
| 1680 Type::ZoneHandle())); // Not an instance, no type. | 1680 Type::ZoneHandle())); // Not an instance, no type. |
| 1681 } | 1681 } |
| 1682 | 1682 |
| 1683 | 1683 |
| 1684 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 1684 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 1685 intptr_t token_pos, | 1685 intptr_t token_pos, |
| 1686 const AbstractTypeArguments& type_arguments) { | 1686 const AbstractTypeArguments& type_arguments) { |
| 1687 InlineBailout("EffectGraphVisitor::BuildInstantiatedTypeArguments"); | 1687 InlineBailout("EffectGraphVisitor::BuildInstantiatedTypeArguments"); |
| 1688 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 1688 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 1689 return Bind(new ConstantInstr(type_arguments)); | 1689 return Bind(new ConstantComp(type_arguments)); |
| 1690 } | 1690 } |
| 1691 // The type arguments are uninstantiated. | 1691 // The type arguments are uninstantiated. |
| 1692 Value* instantiator_value = | 1692 Value* instantiator_value = |
| 1693 BuildInstantiatorTypeArguments(token_pos, NULL); | 1693 BuildInstantiatorTypeArguments(token_pos, NULL); |
| 1694 return Bind(new InstantiateTypeArgumentsInstr(token_pos, | 1694 return Bind(new InstantiateTypeArgumentsComp(token_pos, |
| 1695 type_arguments, | 1695 type_arguments, |
| 1696 instantiator_value)); | 1696 instantiator_value)); |
| 1697 } | 1697 } |
| 1698 | 1698 |
| 1699 | 1699 |
| 1700 void EffectGraphVisitor::BuildConstructorTypeArguments( | 1700 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| 1701 ConstructorCallNode* node, | 1701 ConstructorCallNode* node, |
| 1702 Value** type_arguments, | 1702 Value** type_arguments, |
| 1703 Value** instantiator, | 1703 Value** instantiator, |
| 1704 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { | 1704 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { |
| 1705 InlineBailout("EffectGraphVisitor::BuildConstructorTypeArguments"); | 1705 InlineBailout("EffectGraphVisitor::BuildConstructorTypeArguments"); |
| 1706 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 1706 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 1707 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); | 1707 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); |
| 1708 if (node->type_arguments().IsNull() || | 1708 if (node->type_arguments().IsNull() || |
| 1709 node->type_arguments().IsInstantiated()) { | 1709 node->type_arguments().IsInstantiated()) { |
| 1710 Value* type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); | 1710 Value* type_arguments_val = Bind(new ConstantComp(node->type_arguments())); |
| 1711 if (call_arguments != NULL) { | 1711 if (call_arguments != NULL) { |
| 1712 ASSERT(type_arguments == NULL); | 1712 ASSERT(type_arguments == NULL); |
| 1713 call_arguments->Add(PushArgument(type_arguments_val)); | 1713 call_arguments->Add(PushArgument(type_arguments_val)); |
| 1714 } else { | 1714 } else { |
| 1715 ASSERT(type_arguments != NULL); | 1715 ASSERT(type_arguments != NULL); |
| 1716 *type_arguments = type_arguments_val; | 1716 *type_arguments = type_arguments_val; |
| 1717 } | 1717 } |
| 1718 | 1718 |
| 1719 // No instantiator required. | 1719 // No instantiator required. |
| 1720 Value* instantiator_val = Bind(new ConstantInstr( | 1720 Value* instantiator_val = Bind(new ConstantComp( |
| 1721 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); | 1721 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); |
| 1722 if (call_arguments != NULL) { | 1722 if (call_arguments != NULL) { |
| 1723 ASSERT(instantiator == NULL); | 1723 ASSERT(instantiator == NULL); |
| 1724 call_arguments->Add(PushArgument(instantiator_val)); | 1724 call_arguments->Add(PushArgument(instantiator_val)); |
| 1725 } else { | 1725 } else { |
| 1726 ASSERT(instantiator != NULL); | 1726 ASSERT(instantiator != NULL); |
| 1727 *instantiator = instantiator_val; | 1727 *instantiator = instantiator_val; |
| 1728 } | 1728 } |
| 1729 return; | 1729 return; |
| 1730 } | 1730 } |
| 1731 // The type arguments are uninstantiated. The generated pseudo code: | 1731 // The type arguments are uninstantiated. The generated pseudo code: |
| 1732 // t1 = InstantiatorTypeArguments(); | 1732 // t1 = InstantiatorTypeArguments(); |
| 1733 // t2 = ExtractConstructorTypeArguments(t1); | 1733 // t2 = ExtractConstructorTypeArguments(t1); |
| 1734 // t1 = ExtractConstructorInstantiator(t1); | 1734 // t1 = ExtractConstructorInstantiator(t1); |
| 1735 // t_n <- t2 | 1735 // t_n <- t2 |
| 1736 // t_n+1 <- t1 | 1736 // t_n+1 <- t1 |
| 1737 // Use expression_temp_var and node->allocated_object_var() locals to keep | 1737 // Use expression_temp_var and node->allocated_object_var() locals to keep |
| 1738 // intermediate results around (t1 and t2 above). | 1738 // intermediate results around (t1 and t2 above). |
| 1739 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); | 1739 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); |
| 1740 const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var(); | 1740 const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var(); |
| 1741 const LocalVariable& t2 = node->allocated_object_var(); | 1741 const LocalVariable& t2 = node->allocated_object_var(); |
| 1742 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1742 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments( |
| 1743 node->token_pos(), NULL); | 1743 node->token_pos(), NULL); |
| 1744 Value* stored_instantiator = | 1744 Value* stored_instantiator = |
| 1745 Bind(BuildStoreLocal(t1, instantiator_type_arguments)); | 1745 Bind(BuildStoreLocal(t1, instantiator_type_arguments)); |
| 1746 // t1: instantiator type arguments. | 1746 // t1: instantiator type arguments. |
| 1747 | 1747 |
| 1748 Value* extract_type_arguments = Bind( | 1748 Value* extract_type_arguments = Bind( |
| 1749 new ExtractConstructorTypeArgumentsInstr( | 1749 new ExtractConstructorTypeArgumentsComp( |
| 1750 node->token_pos(), | 1750 node->token_pos(), |
| 1751 node->type_arguments(), | 1751 node->type_arguments(), |
| 1752 stored_instantiator)); | 1752 stored_instantiator)); |
| 1753 | 1753 |
| 1754 Do(BuildStoreLocal(t2, extract_type_arguments)); | 1754 Do(BuildStoreLocal(t2, extract_type_arguments)); |
| 1755 // t2: extracted constructor type arguments. | 1755 // t2: extracted constructor type arguments. |
| 1756 Value* load_instantiator = Bind(BuildLoadLocal(t1)); | 1756 Value* load_instantiator = Bind(BuildLoadLocal(t1)); |
| 1757 | 1757 |
| 1758 Value* extract_instantiator = | 1758 Value* extract_instantiator = |
| 1759 Bind(new ExtractConstructorInstantiatorInstr(node, load_instantiator)); | 1759 Bind(new ExtractConstructorInstantiatorComp(node, load_instantiator)); |
| 1760 Do(BuildStoreLocal(t1, extract_instantiator)); | 1760 Do(BuildStoreLocal(t1, extract_instantiator)); |
| 1761 // t2: extracted constructor type arguments. | 1761 // t2: extracted constructor type arguments. |
| 1762 // t1: extracted constructor instantiator. | 1762 // t1: extracted constructor instantiator. |
| 1763 Value* type_arguments_val = Bind(BuildLoadLocal(t2)); | 1763 Value* type_arguments_val = Bind(BuildLoadLocal(t2)); |
| 1764 if (call_arguments != NULL) { | 1764 if (call_arguments != NULL) { |
| 1765 ASSERT(type_arguments == NULL); | 1765 ASSERT(type_arguments == NULL); |
| 1766 call_arguments->Add(PushArgument(type_arguments_val)); | 1766 call_arguments->Add(PushArgument(type_arguments_val)); |
| 1767 } else { | 1767 } else { |
| 1768 ASSERT(type_arguments != NULL); | 1768 ASSERT(type_arguments != NULL); |
| 1769 *type_arguments = type_arguments_val; | 1769 *type_arguments = type_arguments_val; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1789 | 1789 |
| 1790 // t_n contains the allocated and initialized object. | 1790 // t_n contains the allocated and initialized object. |
| 1791 // t_n <- AllocateObject(class) | 1791 // t_n <- AllocateObject(class) |
| 1792 // t_n <- StoreLocal(temp, t_n); | 1792 // t_n <- StoreLocal(temp, t_n); |
| 1793 // t_n+1 <- ctor-arg | 1793 // t_n+1 <- ctor-arg |
| 1794 // t_n+2... <- constructor arguments start here | 1794 // t_n+2... <- constructor arguments start here |
| 1795 // StaticCall(constructor, t_n, t_n+1, ...) | 1795 // StaticCall(constructor, t_n, t_n+1, ...) |
| 1796 // tn <- LoadLocal(temp) | 1796 // tn <- LoadLocal(temp) |
| 1797 | 1797 |
| 1798 Value* allocate = BuildObjectAllocation(node); | 1798 Value* allocate = BuildObjectAllocation(node); |
| 1799 Definition* store_allocated = BuildStoreLocal( | 1799 Computation* store_allocated = BuildStoreLocal( |
| 1800 node->allocated_object_var(), | 1800 node->allocated_object_var(), |
| 1801 allocate); | 1801 allocate); |
| 1802 Value* allocated_value = Bind(store_allocated); | 1802 Value* allocated_value = Bind(store_allocated); |
| 1803 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 1803 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 1804 BuildConstructorCall(node, push_allocated_value); | 1804 BuildConstructorCall(node, push_allocated_value); |
| 1805 Definition* load_allocated = BuildLoadLocal( | 1805 Computation* load_allocated = BuildLoadLocal( |
| 1806 node->allocated_object_var()); | 1806 node->allocated_object_var()); |
| 1807 allocated_value = Bind(load_allocated); | 1807 allocated_value = Bind(load_allocated); |
| 1808 ReturnValue(allocated_value); | 1808 ReturnValue(allocated_value); |
| 1809 } | 1809 } |
| 1810 | 1810 |
| 1811 | 1811 |
| 1812 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 1812 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 1813 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); | 1813 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); |
| 1814 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1814 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1815 node->receiver()->Visit(&for_receiver); | 1815 node->receiver()->Visit(&for_receiver); |
| 1816 Append(for_receiver); | 1816 Append(for_receiver); |
| 1817 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1817 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1818 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1818 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1819 new ZoneGrowableArray<PushArgumentInstr*>(1); | 1819 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 1820 arguments->Add(push_receiver); | 1820 arguments->Add(push_receiver); |
| 1821 const String& name = | 1821 const String& name = |
| 1822 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 1822 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 1823 InstanceCallInstr* call = new InstanceCallInstr( | 1823 InstanceCallComp* call = new InstanceCallComp( |
| 1824 node->token_pos(), name, Token::kGET, | 1824 node->token_pos(), name, Token::kGET, |
| 1825 arguments, Array::ZoneHandle(), 1); | 1825 arguments, Array::ZoneHandle(), 1); |
| 1826 ReturnDefinition(call); | 1826 ReturnComputation(call); |
| 1827 } | 1827 } |
| 1828 | 1828 |
| 1829 | 1829 |
| 1830 void EffectGraphVisitor::BuildInstanceSetterArguments( | 1830 void EffectGraphVisitor::BuildInstanceSetterArguments( |
| 1831 InstanceSetterNode* node, | 1831 InstanceSetterNode* node, |
| 1832 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 1832 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
| 1833 bool result_is_needed) { | 1833 bool result_is_needed) { |
| 1834 InlineBailout("EffectGraphVisitor::BuildInstanceSetterArguments"); | 1834 InlineBailout("EffectGraphVisitor::BuildInstanceSetterArguments"); |
| 1835 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1835 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1836 node->receiver()->Visit(&for_receiver); | 1836 node->receiver()->Visit(&for_receiver); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1853 } | 1853 } |
| 1854 | 1854 |
| 1855 | 1855 |
| 1856 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1856 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1857 InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode"); | 1857 InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode"); |
| 1858 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1858 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1859 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1859 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1860 BuildInstanceSetterArguments(node, arguments, false); // Value not used. | 1860 BuildInstanceSetterArguments(node, arguments, false); // Value not used. |
| 1861 const String& name = | 1861 const String& name = |
| 1862 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 1862 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 1863 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 1863 InstanceCallComp* call = new InstanceCallComp(node->token_pos(), |
| 1864 name, | 1864 name, |
| 1865 Token::kSET, | 1865 Token::kSET, |
| 1866 arguments, | 1866 arguments, |
| 1867 Array::ZoneHandle(), | 1867 Array::ZoneHandle(), |
| 1868 1); // Checked arg count. | 1868 1); // Checked argument count. |
| 1869 ReturnDefinition(call); | 1869 ReturnComputation(call); |
| 1870 } | 1870 } |
| 1871 | 1871 |
| 1872 | 1872 |
| 1873 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1873 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1874 InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode"); | 1874 InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode"); |
| 1875 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1875 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1876 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1876 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1877 BuildInstanceSetterArguments(node, arguments, true); // Value used. | 1877 BuildInstanceSetterArguments(node, arguments, true); // Value used. |
| 1878 const String& name = | 1878 const String& name = |
| 1879 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 1879 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 1880 Do(new InstanceCallInstr(node->token_pos(), | 1880 Do(new InstanceCallComp(node->token_pos(), |
| 1881 name, | 1881 name, |
| 1882 Token::kSET, | 1882 Token::kSET, |
| 1883 arguments, | 1883 arguments, |
| 1884 Array::ZoneHandle(), | 1884 Array::ZoneHandle(), |
| 1885 1)); // Checked argument count. | 1885 1)); // Checked argument count. |
| 1886 ReturnDefinition( | 1886 ReturnComputation( |
| 1887 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); | 1887 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); |
| 1888 } | 1888 } |
| 1889 | 1889 |
| 1890 | 1890 |
| 1891 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 1891 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| 1892 InlineBailout("EffectGraphVisitor::VisitStaticGetterNode"); | 1892 InlineBailout("EffectGraphVisitor::VisitStaticGetterNode"); |
| 1893 const String& getter_name = | 1893 const String& getter_name = |
| 1894 String::Handle(Field::GetterName(node->field_name())); | 1894 String::Handle(Field::GetterName(node->field_name())); |
| 1895 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1895 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1896 new ZoneGrowableArray<PushArgumentInstr*>(); | 1896 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1897 Function& getter_function = Function::ZoneHandle(); | 1897 Function& getter_function = Function::ZoneHandle(); |
| 1898 if (node->is_super_getter()) { | 1898 if (node->is_super_getter()) { |
| 1899 // Statically resolved instance getter, i.e. "super getter". | 1899 // Statically resolved instance getter, i.e. "super getter". |
| 1900 getter_function = | 1900 getter_function = |
| 1901 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); | 1901 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); |
| 1902 ASSERT(!getter_function.IsNull()); | 1902 ASSERT(!getter_function.IsNull()); |
| 1903 ASSERT(node->receiver() != NULL); | 1903 ASSERT(node->receiver() != NULL); |
| 1904 ValueGraphVisitor receiver_value(owner(), temp_index()); | 1904 ValueGraphVisitor receiver_value(owner(), temp_index()); |
| 1905 node->receiver()->Visit(&receiver_value); | 1905 node->receiver()->Visit(&receiver_value); |
| 1906 Append(receiver_value); | 1906 Append(receiver_value); |
| 1907 arguments->Add(PushArgument(receiver_value.value())); | 1907 arguments->Add(PushArgument(receiver_value.value())); |
| 1908 } else { | 1908 } else { |
| 1909 getter_function = node->cls().LookupStaticFunction(getter_name); | 1909 getter_function = node->cls().LookupStaticFunction(getter_name); |
| 1910 ASSERT(!getter_function.IsNull()); | 1910 ASSERT(!getter_function.IsNull()); |
| 1911 } | 1911 } |
| 1912 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), | 1912 StaticCallComp* call = new StaticCallComp(node->token_pos(), |
| 1913 getter_function, | 1913 getter_function, |
| 1914 Array::ZoneHandle(), // No names. | 1914 Array::ZoneHandle(), // No names. |
| 1915 arguments); | 1915 arguments); |
| 1916 ReturnDefinition(call); | 1916 ReturnComputation(call); |
| 1917 } | 1917 } |
| 1918 | 1918 |
| 1919 | 1919 |
| 1920 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, | 1920 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| 1921 bool result_is_needed) { | 1921 bool result_is_needed) { |
| 1922 InlineBailout("EffectGraphVisitor::BuildStaticSetter"); | 1922 InlineBailout("EffectGraphVisitor::BuildStaticSetter"); |
| 1923 const String& setter_name = | 1923 const String& setter_name = |
| 1924 String::Handle(Field::SetterName(node->field_name())); | 1924 String::Handle(Field::SetterName(node->field_name())); |
| 1925 // A super setter is an instance setter whose setter function is | 1925 // A super setter is an instance setter whose setter function is |
| 1926 // resolved at compile time (in the caller instance getter's super class). | 1926 // resolved at compile time (in the caller instance getter's super class). |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1947 Value* value = NULL; | 1947 Value* value = NULL; |
| 1948 if (result_is_needed) { | 1948 if (result_is_needed) { |
| 1949 value = Bind( | 1949 value = Bind( |
| 1950 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), | 1950 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), |
| 1951 for_value.value())); | 1951 for_value.value())); |
| 1952 } else { | 1952 } else { |
| 1953 value = for_value.value(); | 1953 value = for_value.value(); |
| 1954 } | 1954 } |
| 1955 arguments->Add(PushArgument(value)); | 1955 arguments->Add(PushArgument(value)); |
| 1956 | 1956 |
| 1957 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), | 1957 StaticCallComp* call = new StaticCallComp(node->token_pos(), |
| 1958 setter_function, | 1958 setter_function, |
| 1959 Array::ZoneHandle(), // No names. | 1959 Array::ZoneHandle(), // No names. |
| 1960 arguments); | 1960 arguments); |
| 1961 if (result_is_needed) { | 1961 if (result_is_needed) { |
| 1962 Do(call); | 1962 Do(call); |
| 1963 ReturnDefinition( | 1963 ReturnComputation( |
| 1964 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); | 1964 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); |
| 1965 } else { | 1965 } else { |
| 1966 ReturnDefinition(call); | 1966 ReturnComputation(call); |
| 1967 } | 1967 } |
| 1968 } | 1968 } |
| 1969 | 1969 |
| 1970 | 1970 |
| 1971 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 1971 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 1972 InlineBailout("EffectGraphVisitor::VisitStaticSetterNode"); | 1972 InlineBailout("EffectGraphVisitor::VisitStaticSetterNode"); |
| 1973 BuildStaticSetter(node, false); // Result not needed. | 1973 BuildStaticSetter(node, false); // Result not needed. |
| 1974 } | 1974 } |
| 1975 | 1975 |
| 1976 | 1976 |
| 1977 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 1977 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 1978 InlineBailout("ValueGraphVisitor::VisitStaticSetterNode"); | 1978 InlineBailout("ValueGraphVisitor::VisitStaticSetterNode"); |
| 1979 BuildStaticSetter(node, true); // Result needed. | 1979 BuildStaticSetter(node, true); // Result needed. |
| 1980 } | 1980 } |
| 1981 | 1981 |
| 1982 | 1982 |
| 1983 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { | 1983 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { |
| 1984 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); | 1984 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); |
| 1985 NativeCallInstr* native_call = new NativeCallInstr(node); | 1985 NativeCallComp* native_call = new NativeCallComp(node); |
| 1986 ReturnDefinition(native_call); | 1986 ReturnComputation(native_call); |
| 1987 } | 1987 } |
| 1988 | 1988 |
| 1989 | 1989 |
| 1990 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { | 1990 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { |
| 1991 InlineBailout("EffectGraphVisitor::VisitPrimaryNode"); | 1991 InlineBailout("EffectGraphVisitor::VisitPrimaryNode"); |
| 1992 // PrimaryNodes are temporary during parsing. | 1992 // PrimaryNodes are temporary during parsing. |
| 1993 UNREACHABLE(); | 1993 UNREACHABLE(); |
| 1994 } | 1994 } |
| 1995 | 1995 |
| 1996 | 1996 |
| 1997 // <Expression> ::= LoadLocal { local: LocalVariable } | 1997 // <Expression> ::= LoadLocal { local: LocalVariable } |
| 1998 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 1998 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 1999 InlineBailout("EffectGraphVisitor::VisitLoadLocalNode"); | 1999 InlineBailout("EffectGraphVisitor::VisitLoadLocalNode"); |
| 2000 if (node->HasPseudo()) { | 2000 if (node->HasPseudo()) { |
| 2001 EffectGraphVisitor for_pseudo(owner(), temp_index()); | 2001 EffectGraphVisitor for_pseudo(owner(), temp_index()); |
| 2002 node->pseudo()->Visit(&for_pseudo); | 2002 node->pseudo()->Visit(&for_pseudo); |
| 2003 Append(for_pseudo); | 2003 Append(for_pseudo); |
| 2004 } | 2004 } |
| 2005 } | 2005 } |
| 2006 | 2006 |
| 2007 | 2007 |
| 2008 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2008 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 2009 InlineBailout("ValueGraphVisitor::VisitLoadLocalNode"); | 2009 InlineBailout("ValueGraphVisitor::VisitLoadLocalNode"); |
| 2010 EffectGraphVisitor::VisitLoadLocalNode(node); | 2010 EffectGraphVisitor::VisitLoadLocalNode(node); |
| 2011 Definition* load = BuildLoadLocal(node->local()); | 2011 Computation* load = BuildLoadLocal(node->local()); |
| 2012 ReturnDefinition(load); | 2012 ReturnComputation(load); |
| 2013 } | 2013 } |
| 2014 | 2014 |
| 2015 | 2015 |
| 2016 // <Expression> ::= StoreLocal { local: LocalVariable | 2016 // <Expression> ::= StoreLocal { local: LocalVariable |
| 2017 // value: <Expression> } | 2017 // value: <Expression> } |
| 2018 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 2018 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 2019 InlineBailout("EffectGraphVisitor::VisitStoreLocalNode"); | 2019 InlineBailout("EffectGraphVisitor::VisitStoreLocalNode"); |
| 2020 ValueGraphVisitor for_value(owner(), temp_index()); | 2020 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2021 node->value()->Visit(&for_value); | 2021 node->value()->Visit(&for_value); |
| 2022 Append(for_value); | 2022 Append(for_value); |
| 2023 Value* store_value = for_value.value(); | 2023 Value* store_value = for_value.value(); |
| 2024 if (FLAG_enable_type_checks) { | 2024 if (FLAG_enable_type_checks) { |
| 2025 store_value = BuildAssignableValue(node->value()->token_pos(), | 2025 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2026 store_value, | 2026 store_value, |
| 2027 node->local().type(), | 2027 node->local().type(), |
| 2028 node->local().name()); | 2028 node->local().name()); |
| 2029 } | 2029 } |
| 2030 Definition* store = BuildStoreLocal(node->local(), store_value); | 2030 Computation* store = BuildStoreLocal(node->local(), store_value); |
| 2031 ReturnDefinition(store); | 2031 ReturnComputation(store); |
| 2032 } | 2032 } |
| 2033 | 2033 |
| 2034 | 2034 |
| 2035 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 2035 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 2036 LoadInstanceFieldNode* node) { | 2036 LoadInstanceFieldNode* node) { |
| 2037 InlineBailout("EffectGraphVisitor::VisitLoadInstanceFieldNode"); | 2037 InlineBailout("EffectGraphVisitor::VisitLoadInstanceFieldNode"); |
| 2038 ValueGraphVisitor for_instance(owner(), temp_index()); | 2038 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 2039 node->instance()->Visit(&for_instance); | 2039 node->instance()->Visit(&for_instance); |
| 2040 Append(for_instance); | 2040 Append(for_instance); |
| 2041 LoadInstanceFieldInstr* load = new LoadInstanceFieldInstr( | 2041 LoadInstanceFieldComp* load = new LoadInstanceFieldComp( |
| 2042 node->field(), for_instance.value()); | 2042 node->field(), for_instance.value()); |
| 2043 ReturnDefinition(load); | 2043 ReturnComputation(load); |
| 2044 } | 2044 } |
| 2045 | 2045 |
| 2046 | 2046 |
| 2047 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 2047 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 2048 StoreInstanceFieldNode* node) { | 2048 StoreInstanceFieldNode* node) { |
| 2049 InlineBailout("EffectGraphVisitor::VisitStoreInstanceFieldNode"); | 2049 InlineBailout("EffectGraphVisitor::VisitStoreInstanceFieldNode"); |
| 2050 ValueGraphVisitor for_instance(owner(), temp_index()); | 2050 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 2051 node->instance()->Visit(&for_instance); | 2051 node->instance()->Visit(&for_instance); |
| 2052 Append(for_instance); | 2052 Append(for_instance); |
| 2053 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 2053 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); |
| 2054 node->value()->Visit(&for_value); | 2054 node->value()->Visit(&for_value); |
| 2055 Append(for_value); | 2055 Append(for_value); |
| 2056 Value* store_value = for_value.value(); | 2056 Value* store_value = for_value.value(); |
| 2057 if (FLAG_enable_type_checks) { | 2057 if (FLAG_enable_type_checks) { |
| 2058 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2058 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2059 const String& dst_name = String::ZoneHandle(node->field().name()); | 2059 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2060 store_value = BuildAssignableValue(node->value()->token_pos(), | 2060 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2061 store_value, | 2061 store_value, |
| 2062 type, | 2062 type, |
| 2063 dst_name); | 2063 dst_name); |
| 2064 } | 2064 } |
| 2065 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr( | 2065 StoreInstanceFieldComp* store = new StoreInstanceFieldComp( |
| 2066 node->field(), for_instance.value(), store_value); | 2066 node->field(), for_instance.value(), store_value); |
| 2067 ReturnDefinition(store); | 2067 ReturnComputation(store); |
| 2068 } | 2068 } |
| 2069 | 2069 |
| 2070 | 2070 |
| 2071 // StoreInstanceFieldNode does not return result. | 2071 // StoreInstanceFieldNode does not return result. |
| 2072 void ValueGraphVisitor::VisitStoreInstanceFieldNode( | 2072 void ValueGraphVisitor::VisitStoreInstanceFieldNode( |
| 2073 StoreInstanceFieldNode* node) { | 2073 StoreInstanceFieldNode* node) { |
| 2074 InlineBailout("ValueGraphVisitor::VisitStoreInstanceFieldNode"); | 2074 InlineBailout("ValueGraphVisitor::VisitStoreInstanceFieldNode"); |
| 2075 UNIMPLEMENTED(); | 2075 UNIMPLEMENTED(); |
| 2076 } | 2076 } |
| 2077 | 2077 |
| 2078 | 2078 |
| 2079 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 2079 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 2080 InlineBailout("EffectGraphVisitor::VisitLoadStaticFieldNode"); | 2080 InlineBailout("EffectGraphVisitor::VisitLoadStaticFieldNode"); |
| 2081 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); | 2081 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); |
| 2082 ReturnDefinition(load); | 2082 ReturnComputation(load); |
| 2083 } | 2083 } |
| 2084 | 2084 |
| 2085 | 2085 |
| 2086 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 2086 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 2087 InlineBailout("EffectGraphVisitor::VisitStoreStaticFieldNode"); | 2087 InlineBailout("EffectGraphVisitor::VisitStoreStaticFieldNode"); |
| 2088 ValueGraphVisitor for_value(owner(), temp_index()); | 2088 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2089 node->value()->Visit(&for_value); | 2089 node->value()->Visit(&for_value); |
| 2090 Append(for_value); | 2090 Append(for_value); |
| 2091 Value* store_value = for_value.value(); | 2091 Value* store_value = for_value.value(); |
| 2092 if (FLAG_enable_type_checks) { | 2092 if (FLAG_enable_type_checks) { |
| 2093 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2093 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2094 const String& dst_name = String::ZoneHandle(node->field().name()); | 2094 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2095 store_value = BuildAssignableValue(node->value()->token_pos(), | 2095 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2096 store_value, | 2096 store_value, |
| 2097 type, | 2097 type, |
| 2098 dst_name); | 2098 dst_name); |
| 2099 } | 2099 } |
| 2100 StoreStaticFieldInstr* store = | 2100 StoreStaticFieldComp* store = |
| 2101 new StoreStaticFieldInstr(node->field(), store_value); | 2101 new StoreStaticFieldComp(node->field(), store_value); |
| 2102 ReturnDefinition(store); | 2102 ReturnComputation(store); |
| 2103 } | 2103 } |
| 2104 | 2104 |
| 2105 | 2105 |
| 2106 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 2106 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 2107 InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode"); | 2107 InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode"); |
| 2108 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2108 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2109 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2109 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2110 ValueGraphVisitor for_array(owner(), temp_index()); | 2110 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2111 node->array()->Visit(&for_array); | 2111 node->array()->Visit(&for_array); |
| 2112 Append(for_array); | 2112 Append(for_array); |
| 2113 arguments->Add(PushArgument(for_array.value())); | 2113 arguments->Add(PushArgument(for_array.value())); |
| 2114 | 2114 |
| 2115 ValueGraphVisitor for_index(owner(), temp_index()); | 2115 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2116 node->index_expr()->Visit(&for_index); | 2116 node->index_expr()->Visit(&for_index); |
| 2117 Append(for_index); | 2117 Append(for_index); |
| 2118 arguments->Add(PushArgument(for_index.value())); | 2118 arguments->Add(PushArgument(for_index.value())); |
| 2119 | 2119 |
| 2120 const intptr_t checked_argument_count = 1; | 2120 const intptr_t checked_argument_count = 1; |
| 2121 const String& name = | 2121 const String& name = |
| 2122 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); | 2122 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); |
| 2123 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), | 2123 InstanceCallComp* load = new InstanceCallComp(node->token_pos(), |
| 2124 name, | 2124 name, |
| 2125 Token::kINDEX, | 2125 Token::kINDEX, |
| 2126 arguments, | 2126 arguments, |
| 2127 Array::ZoneHandle(), | 2127 Array::ZoneHandle(), |
| 2128 checked_argument_count); | 2128 checked_argument_count); |
| 2129 ReturnDefinition(load); | 2129 ReturnComputation(load); |
| 2130 } | 2130 } |
| 2131 | 2131 |
| 2132 | 2132 |
| 2133 Definition* EffectGraphVisitor::BuildStoreIndexedValues( | 2133 Computation* EffectGraphVisitor::BuildStoreIndexedValues( |
| 2134 StoreIndexedNode* node, | 2134 StoreIndexedNode* node, |
| 2135 bool result_is_needed) { | 2135 bool result_is_needed) { |
| 2136 InlineBailout("EffectGraphVisitor::BuildStoreIndexedValues"); | 2136 InlineBailout("EffectGraphVisitor::BuildStoreIndexedValues"); |
| 2137 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2137 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2138 new ZoneGrowableArray<PushArgumentInstr*>(3); | 2138 new ZoneGrowableArray<PushArgumentInstr*>(3); |
| 2139 ValueGraphVisitor for_array(owner(), temp_index()); | 2139 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2140 node->array()->Visit(&for_array); | 2140 node->array()->Visit(&for_array); |
| 2141 Append(for_array); | 2141 Append(for_array); |
| 2142 arguments->Add(PushArgument(for_array.value())); | 2142 arguments->Add(PushArgument(for_array.value())); |
| 2143 | 2143 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2155 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), | 2155 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), |
| 2156 for_value.value())); | 2156 for_value.value())); |
| 2157 } else { | 2157 } else { |
| 2158 value = for_value.value(); | 2158 value = for_value.value(); |
| 2159 } | 2159 } |
| 2160 arguments->Add(PushArgument(value)); | 2160 arguments->Add(PushArgument(value)); |
| 2161 | 2161 |
| 2162 const intptr_t checked_argument_count = 1; | 2162 const intptr_t checked_argument_count = 1; |
| 2163 const String& name = | 2163 const String& name = |
| 2164 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); | 2164 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); |
| 2165 InstanceCallInstr* store = new InstanceCallInstr(node->token_pos(), | 2165 InstanceCallComp* store = new InstanceCallComp(node->token_pos(), |
| 2166 name, | 2166 name, |
| 2167 Token::kASSIGN_INDEX, | 2167 Token::kASSIGN_INDEX, |
| 2168 arguments, | 2168 arguments, |
| 2169 Array::ZoneHandle(), | 2169 Array::ZoneHandle(), |
| 2170 checked_argument_count); | 2170 checked_argument_count); |
| 2171 if (result_is_needed) { | 2171 if (result_is_needed) { |
| 2172 Do(store); | 2172 Do(store); |
| 2173 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); | 2173 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); |
| 2174 } else { | 2174 } else { |
| 2175 return store; | 2175 return store; |
| 2176 } | 2176 } |
| 2177 } | 2177 } |
| 2178 | 2178 |
| 2179 | 2179 |
| 2180 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 2180 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 2181 InlineBailout("EffectGraphVisitor::VisitStoreIndexedNode"); | 2181 InlineBailout("EffectGraphVisitor::VisitStoreIndexedNode"); |
| 2182 ReturnDefinition(BuildStoreIndexedValues(node, | 2182 ReturnComputation(BuildStoreIndexedValues(node, |
| 2183 false)); // Result not needed. | 2183 false)); // Result not needed. |
| 2184 } | 2184 } |
| 2185 | 2185 |
| 2186 | 2186 |
| 2187 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 2187 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 2188 InlineBailout("ValueGraphVisitor::VisitStoreIndexedNode"); | 2188 InlineBailout("ValueGraphVisitor::VisitStoreIndexedNode"); |
| 2189 ReturnDefinition(BuildStoreIndexedValues(node, | 2189 ReturnComputation(BuildStoreIndexedValues(node, |
| 2190 true)); // Result is needed. | 2190 true)); // Result is needed. |
| 2191 } | 2191 } |
| 2192 | 2192 |
| 2193 | 2193 |
| 2194 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { | 2194 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { |
| 2195 return (node == owner()->parsed_function().node_sequence()) && | 2195 return (node == owner()->parsed_function().node_sequence()) && |
| 2196 (owner()->parsed_function().saved_context_var() != NULL); | 2196 (owner()->parsed_function().saved_context_var() != NULL); |
| 2197 } | 2197 } |
| 2198 | 2198 |
| 2199 | 2199 |
| 2200 void EffectGraphVisitor::UnchainContext() { | 2200 void EffectGraphVisitor::UnchainContext() { |
| 2201 InlineBailout("EffectGraphVisitor::UnchainContext"); | 2201 InlineBailout("EffectGraphVisitor::UnchainContext"); |
| 2202 Value* context = Bind(new CurrentContextInstr()); | 2202 Value* context = Bind(new CurrentContextComp()); |
| 2203 Value* parent = Bind( | 2203 Value* parent = Bind( |
| 2204 new LoadVMFieldInstr(context, | 2204 new LoadVMFieldComp(context, |
| 2205 Context::parent_offset(), | 2205 Context::parent_offset(), |
| 2206 Type::ZoneHandle())); // Not an instance, no type. | 2206 Type::ZoneHandle())); // Not an instance, no type. |
| 2207 Do(new StoreContextInstr(parent)); | 2207 Do(new StoreContextComp(parent)); |
| 2208 } | 2208 } |
| 2209 | 2209 |
| 2210 | 2210 |
| 2211 // <Statement> ::= Sequence { scope: LocalScope | 2211 // <Statement> ::= Sequence { scope: LocalScope |
| 2212 // nodes: <Statement>* | 2212 // nodes: <Statement>* |
| 2213 // label: SourceLabel } | 2213 // label: SourceLabel } |
| 2214 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 2214 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| 2215 LocalScope* scope = node->scope(); | 2215 LocalScope* scope = node->scope(); |
| 2216 const intptr_t num_context_variables = | 2216 const intptr_t num_context_variables = |
| 2217 (scope != NULL) ? scope->num_context_variables() : 0; | 2217 (scope != NULL) ? scope->num_context_variables() : 0; |
| 2218 int previous_context_level = owner()->context_level(); | 2218 int previous_context_level = owner()->context_level(); |
| 2219 if (num_context_variables > 0) { | 2219 if (num_context_variables > 0) { |
| 2220 InlineBailout("EffectGraphVisitor::VisitSequenceNode (captured vars)"); | 2220 InlineBailout("EffectGraphVisitor::VisitSequenceNode (captured vars)"); |
| 2221 // The loop local scope declares variables that are captured. | 2221 // The loop local scope declares variables that are captured. |
| 2222 // Allocate and chain a new context. | 2222 // Allocate and chain a new context. |
| 2223 // Allocate context computation (uses current CTX) | 2223 // Allocate context computation (uses current CTX) |
| 2224 Value* allocated_context = | 2224 Value* allocated_context = |
| 2225 Bind(new AllocateContextInstr(node->token_pos(), | 2225 Bind(new AllocateContextComp(node->token_pos(), num_context_variables)); |
| 2226 num_context_variables)); | |
| 2227 | 2226 |
| 2228 // If this node_sequence is the body of the function being compiled, and if | 2227 // If this node_sequence is the body of the function being compiled, and if |
| 2229 // this function is not a closure, do not link the current context as the | 2228 // this function is not a closure, do not link the current context as the |
| 2230 // parent of the newly allocated context, as it is not accessible. Instead, | 2229 // parent of the newly allocated context, as it is not accessible. Instead, |
| 2231 // save it in a pre-allocated variable and restore it on exit. | 2230 // save it in a pre-allocated variable and restore it on exit. |
| 2232 if (MustSaveRestoreContext(node)) { | 2231 if (MustSaveRestoreContext(node)) { |
| 2233 Value* current_context = Bind(new CurrentContextInstr()); | 2232 Value* current_context = Bind(new CurrentContextComp()); |
| 2234 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(), | 2233 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(), |
| 2235 current_context)); | 2234 current_context)); |
| 2236 Value* null_context = Bind(new ConstantInstr(Object::ZoneHandle())); | 2235 Value* null_context = Bind(new ConstantComp(Object::ZoneHandle())); |
| 2237 Do(new StoreContextInstr(null_context)); | 2236 Do(new StoreContextComp(null_context)); |
| 2238 } | 2237 } |
| 2239 | 2238 |
| 2240 Do(new ChainContextInstr(allocated_context)); | 2239 Do(new ChainContextComp(allocated_context)); |
| 2241 owner()->set_context_level(scope->context_level()); | 2240 owner()->set_context_level(scope->context_level()); |
| 2242 | 2241 |
| 2243 // If this node_sequence is the body of the function being compiled, copy | 2242 // If this node_sequence is the body of the function being compiled, copy |
| 2244 // the captured parameters from the frame into the context. | 2243 // the captured parameters from the frame into the context. |
| 2245 if (node == owner()->parsed_function().node_sequence()) { | 2244 if (node == owner()->parsed_function().node_sequence()) { |
| 2246 ASSERT(scope->context_level() == 1); | 2245 ASSERT(scope->context_level() == 1); |
| 2247 const Function& function = owner()->parsed_function().function(); | 2246 const Function& function = owner()->parsed_function().function(); |
| 2248 int num_params = function.NumberOfParameters(); | 2247 int num_params = function.NumberOfParameters(); |
| 2249 int param_frame_index = (num_params == function.num_fixed_parameters()) ? | 2248 int param_frame_index = (num_params == function.num_fixed_parameters()) ? |
| 2250 (1 + num_params) : ParsedFunction::kFirstLocalSlotIndex; | 2249 (1 + num_params) : ParsedFunction::kFirstLocalSlotIndex; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2266 Type::ZoneHandle(Type::DynamicType())); // Type. | 2265 Type::ZoneHandle(Type::DynamicType())); // Type. |
| 2267 temp_local->set_index(param_frame_index); | 2266 temp_local->set_index(param_frame_index); |
| 2268 | 2267 |
| 2269 // Copy parameter from local frame to current context. | 2268 // Copy parameter from local frame to current context. |
| 2270 Value* load = Bind(BuildLoadLocal(*temp_local)); | 2269 Value* load = Bind(BuildLoadLocal(*temp_local)); |
| 2271 Do(BuildStoreLocal(parameter, load)); | 2270 Do(BuildStoreLocal(parameter, load)); |
| 2272 // Write NULL to the source location to detect buggy accesses and | 2271 // Write NULL to the source location to detect buggy accesses and |
| 2273 // allow GC of passed value if it gets overwritten by a new value in | 2272 // allow GC of passed value if it gets overwritten by a new value in |
| 2274 // the function. | 2273 // the function. |
| 2275 Value* null_constant = | 2274 Value* null_constant = |
| 2276 Bind(new ConstantInstr(Object::ZoneHandle())); | 2275 Bind(new ConstantComp(Object::ZoneHandle())); |
| 2277 Do(BuildStoreLocal(*temp_local, null_constant)); | 2276 Do(BuildStoreLocal(*temp_local, null_constant)); |
| 2278 } | 2277 } |
| 2279 } | 2278 } |
| 2280 } | 2279 } |
| 2281 } | 2280 } |
| 2282 | 2281 |
| 2283 if (FLAG_enable_type_checks && | 2282 if (FLAG_enable_type_checks && |
| 2284 (node == owner()->parsed_function().node_sequence())) { | 2283 (node == owner()->parsed_function().node_sequence())) { |
| 2285 InlineBailout("EffectGraphVisitor::VisitSequenceNode (type check)"); | 2284 InlineBailout("EffectGraphVisitor::VisitSequenceNode (type check)"); |
| 2286 const Function& function = owner()->parsed_function().function(); | 2285 const Function& function = owner()->parsed_function().function(); |
| 2287 const int num_params = function.NumberOfParameters(); | 2286 const int num_params = function.NumberOfParameters(); |
| 2288 int pos = 0; | 2287 int pos = 0; |
| 2289 if (function.IsConstructor()) { | 2288 if (function.IsConstructor()) { |
| 2290 // Skip type checking of receiver and phase for constructor functions. | 2289 // Skip type checking of receiver and phase for constructor functions. |
| 2291 pos = 2; | 2290 pos = 2; |
| 2292 } else if (function.IsFactory() || function.IsDynamicFunction()) { | 2291 } else if (function.IsFactory() || function.IsDynamicFunction()) { |
| 2293 // Skip type checking of type arguments for factory functions. | 2292 // Skip type checking of type arguments for factory functions. |
| 2294 // Skip type checking of receiver for instance functions. | 2293 // Skip type checking of receiver for instance functions. |
| 2295 pos = 1; | 2294 pos = 1; |
| 2296 } | 2295 } |
| 2297 while (pos < num_params) { | 2296 while (pos < num_params) { |
| 2298 const LocalVariable& parameter = *scope->VariableAt(pos); | 2297 const LocalVariable& parameter = *scope->VariableAt(pos); |
| 2299 ASSERT(parameter.owner() == scope); | 2298 ASSERT(parameter.owner() == scope); |
| 2300 if (!CanSkipTypeCheck(parameter.token_pos(), | 2299 if (!CanSkipTypeCheck(parameter.token_pos(), |
| 2301 NULL, | 2300 NULL, |
| 2302 parameter.type(), | 2301 parameter.type(), |
| 2303 parameter.name())) { | 2302 parameter.name())) { |
| 2304 Value* parameter_value = Bind(BuildLoadLocal(parameter)); | 2303 Value* parameter_value = Bind(BuildLoadLocal(parameter)); |
| 2305 AssertAssignableInstr* assert_assignable = | 2304 AssertAssignableComp* assert_assignable = |
| 2306 BuildAssertAssignable(parameter.token_pos(), | 2305 BuildAssertAssignable(parameter.token_pos(), |
| 2307 parameter_value, | 2306 parameter_value, |
| 2308 parameter.type(), | 2307 parameter.type(), |
| 2309 parameter.name()); | 2308 parameter.name()); |
| 2310 parameter_value = Bind(assert_assignable); | 2309 parameter_value = Bind(assert_assignable); |
| 2311 // Store the type checked argument back to its corresponding local | 2310 // Store the type checked argument back to its corresponding local |
| 2312 // variable so that ssa renaming detects the dependency and makes use | 2311 // variable so that ssa renaming detects the dependency and makes use |
| 2313 // of the checked type in type propagation. | 2312 // of the checked type in type propagation. |
| 2314 Do(BuildStoreLocal(parameter, parameter_value)); | 2313 Do(BuildStoreLocal(parameter, parameter_value)); |
| 2315 } | 2314 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2353 (node != owner()->parsed_function().node_sequence())); | 2352 (node != owner()->parsed_function().node_sequence())); |
| 2354 owner()->set_context_level(previous_context_level); | 2353 owner()->set_context_level(previous_context_level); |
| 2355 } | 2354 } |
| 2356 | 2355 |
| 2357 | 2356 |
| 2358 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 2357 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| 2359 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode"); | 2358 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode"); |
| 2360 // NOTE: The implicit variables ':saved_context', ':exception_var' | 2359 // NOTE: The implicit variables ':saved_context', ':exception_var' |
| 2361 // and ':stacktrace_var' can never be captured variables. | 2360 // and ':stacktrace_var' can never be captured variables. |
| 2362 // Restores CTX from local variable ':saved_context'. | 2361 // Restores CTX from local variable ':saved_context'. |
| 2363 Do(new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); | 2362 Do(new CatchEntryComp(node->exception_var(), node->stacktrace_var())); |
| 2364 BuildLoadContext(node->context_var()); | 2363 BuildLoadContext(node->context_var()); |
| 2365 | 2364 |
| 2366 EffectGraphVisitor for_catch(owner(), temp_index()); | 2365 EffectGraphVisitor for_catch(owner(), temp_index()); |
| 2367 node->VisitChildren(&for_catch); | 2366 node->VisitChildren(&for_catch); |
| 2368 Append(for_catch); | 2367 Append(for_catch); |
| 2369 } | 2368 } |
| 2370 | 2369 |
| 2371 | 2370 |
| 2372 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 2371 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| 2373 InlineBailout("EffectGraphVisitor::VisitTryCatchNode"); | 2372 InlineBailout("EffectGraphVisitor::VisitTryCatchNode"); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2453 CloseFragment(); | 2452 CloseFragment(); |
| 2454 } | 2453 } |
| 2455 | 2454 |
| 2456 | 2455 |
| 2457 // A throw cannot be part of an expression, however, the parser may replace | 2456 // A throw cannot be part of an expression, however, the parser may replace |
| 2458 // certain expression nodes with a throw. In that case generate a literal null | 2457 // certain expression nodes with a throw. In that case generate a literal null |
| 2459 // so that the fragment is not closed in the middle of an expression. | 2458 // so that the fragment is not closed in the middle of an expression. |
| 2460 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2459 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 2461 InlineBailout("ValueGraphVisitor::VisitThrowNode"); | 2460 InlineBailout("ValueGraphVisitor::VisitThrowNode"); |
| 2462 BuildThrowNode(node); | 2461 BuildThrowNode(node); |
| 2463 ReturnDefinition(new ConstantInstr(Instance::ZoneHandle())); | 2462 ReturnComputation(new ConstantComp(Instance::ZoneHandle())); |
| 2464 } | 2463 } |
| 2465 | 2464 |
| 2466 | 2465 |
| 2467 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { | 2466 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
| 2468 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode"); | 2467 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode"); |
| 2469 const intptr_t try_index = owner()->try_index(); | 2468 const intptr_t try_index = owner()->try_index(); |
| 2470 if (try_index >= 0) { | 2469 if (try_index >= 0) { |
| 2471 // We are about to generate code for an inlined finally block. Exceptions | 2470 // We are about to generate code for an inlined finally block. Exceptions |
| 2472 // thrown in this block of code should be treated as though they are | 2471 // thrown in this block of code should be treated as though they are |
| 2473 // thrown not from the current try block but the outer try block if any. | 2472 // thrown not from the current try block but the outer try block if any. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2501 AstPrinter::PrintFunctionNodes(parsed_function()); | 2500 AstPrinter::PrintFunctionNodes(parsed_function()); |
| 2502 } | 2501 } |
| 2503 // Compilation can be nested, preserve the computation-id. | 2502 // Compilation can be nested, preserve the computation-id. |
| 2504 const Function& function = parsed_function().function(); | 2503 const Function& function = parsed_function().function(); |
| 2505 TargetEntryInstr* normal_entry = new TargetEntryInstr( | 2504 TargetEntryInstr* normal_entry = new TargetEntryInstr( |
| 2506 CatchClauseNode::kInvalidTryIndex); | 2505 CatchClauseNode::kInvalidTryIndex); |
| 2507 graph_entry_ = new GraphEntryInstr(normal_entry); | 2506 graph_entry_ = new GraphEntryInstr(normal_entry); |
| 2508 EffectGraphVisitor for_effect(this, 0); | 2507 EffectGraphVisitor for_effect(this, 0); |
| 2509 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the | 2508 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the |
| 2510 // stack check on entry for leaf routines). | 2509 // stack check on entry for leaf routines). |
| 2511 for_effect.Do(new CheckStackOverflowInstr(function.token_pos())); | 2510 for_effect.Do(new CheckStackOverflowComp(function.token_pos())); |
| 2512 parsed_function().node_sequence()->Visit(&for_effect); | 2511 parsed_function().node_sequence()->Visit(&for_effect); |
| 2513 AppendFragment(normal_entry, for_effect); | 2512 AppendFragment(normal_entry, for_effect); |
| 2514 // Check that the graph is properly terminated. | 2513 // Check that the graph is properly terminated. |
| 2515 ASSERT(!for_effect.is_open()); | 2514 ASSERT(!for_effect.is_open()); |
| 2516 return new FlowGraph(*this, graph_entry_); | 2515 return new FlowGraph(*this, graph_entry_); |
| 2517 } | 2516 } |
| 2518 | 2517 |
| 2519 | 2518 |
| 2520 FlowGraph* FlowGraphBuilder::BuildGraphForInlining(InliningContext context) { | 2519 FlowGraph* FlowGraphBuilder::BuildGraphForInlining(InliningContext context) { |
| 2521 ASSERT(inlining_context_ == kNotInlining); | 2520 ASSERT(inlining_context_ == kNotInlining); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2540 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2539 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2541 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2540 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2542 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2541 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2543 const Error& error = Error::Handle( | 2542 const Error& error = Error::Handle( |
| 2544 LanguageError::New(String::Handle(String::New(chars)))); | 2543 LanguageError::New(String::Handle(String::New(chars)))); |
| 2545 Isolate::Current()->long_jump_base()->Jump(1, error); | 2544 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2546 } | 2545 } |
| 2547 | 2546 |
| 2548 | 2547 |
| 2549 } // namespace dart | 2548 } // namespace dart |
| OLD | NEW |