| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <map> | 5 #include <map> |
| 6 #include <set> | 6 #include <set> |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "vm/kernel_to_il.h" | 9 #include "vm/kernel_to_il.h" |
| 10 | 10 |
| (...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1762 // Run and canonicalize. | 1762 // Run and canonicalize. |
| 1763 const Object& result = | 1763 const Object& result = |
| 1764 RunFunction(func, interpolate_arg, Array::null_array()); | 1764 RunFunction(func, interpolate_arg, Array::null_array()); |
| 1765 result_ = H.Canonicalize(dart::String::Cast(result)); | 1765 result_ = H.Canonicalize(dart::String::Cast(result)); |
| 1766 } | 1766 } |
| 1767 } | 1767 } |
| 1768 | 1768 |
| 1769 | 1769 |
| 1770 void ConstantEvaluator::VisitConditionalExpression( | 1770 void ConstantEvaluator::VisitConditionalExpression( |
| 1771 ConditionalExpression* node) { | 1771 ConditionalExpression* node) { |
| 1772 EvaluateExpression(node->condition()); | 1772 if (EvaluateBooleanExpression(node->condition())) { |
| 1773 if (Bool::Cast(result_).value()) { | |
| 1774 EvaluateExpression(node->then()); | 1773 EvaluateExpression(node->then()); |
| 1775 } else { | 1774 } else { |
| 1776 EvaluateExpression(node->otherwise()); | 1775 EvaluateExpression(node->otherwise()); |
| 1777 } | 1776 } |
| 1778 } | 1777 } |
| 1779 | 1778 |
| 1780 | 1779 |
| 1781 void ConstantEvaluator::VisitLogicalExpression(LogicalExpression* node) { | 1780 void ConstantEvaluator::VisitLogicalExpression(LogicalExpression* node) { |
| 1782 if (node->op() == LogicalExpression::kAnd) { | 1781 if (node->op() == LogicalExpression::kAnd) { |
| 1783 EvaluateExpression(node->left()); | 1782 if (EvaluateBooleanExpression(node->left())) { |
| 1784 if (Bool::Cast(result_).value()) { | 1783 EvaluateBooleanExpression(node->right()); |
| 1785 EvaluateExpression(node->right()); | |
| 1786 } | 1784 } |
| 1787 } else { | 1785 } else { |
| 1788 ASSERT(node->op() == LogicalExpression::kOr); | 1786 ASSERT(node->op() == LogicalExpression::kOr); |
| 1789 EvaluateExpression(node->left()); | 1787 if (!EvaluateBooleanExpression(node->left())) { |
| 1790 if (!Bool::Cast(result_).value()) { | 1788 EvaluateBooleanExpression(node->right()); |
| 1791 EvaluateExpression(node->right()); | |
| 1792 } | 1789 } |
| 1793 } | 1790 } |
| 1794 } | 1791 } |
| 1795 | 1792 |
| 1796 | 1793 |
| 1797 void ConstantEvaluator::VisitNot(Not* node) { | 1794 void ConstantEvaluator::VisitNot(Not* node) { |
| 1798 EvaluateExpression(node->expression()); | 1795 result_ ^= Bool::Get(!EvaluateBooleanExpression(node->expression())).raw(); |
| 1799 ASSERT(result_.IsBool()); | |
| 1800 result_ = | |
| 1801 Bool::Cast(result_).value() ? Bool::False().raw() : Bool::True().raw(); | |
| 1802 } | 1796 } |
| 1803 | 1797 |
| 1804 | 1798 |
| 1805 void ConstantEvaluator::VisitPropertyGet(PropertyGet* node) { | 1799 void ConstantEvaluator::VisitPropertyGet(PropertyGet* node) { |
| 1806 const size_t kLengthLen = strlen("length"); | 1800 const size_t kLengthLen = strlen("length"); |
| 1807 | 1801 |
| 1808 String* string = node->name()->string(); | 1802 String* string = node->name()->string(); |
| 1809 if (string->size() == kLengthLen && | 1803 if (string->size() == kLengthLen && |
| 1810 memcmp(string->buffer(), "length", kLengthLen) == 0) { | 1804 memcmp(string->buffer(), "length", kLengthLen) == 0) { |
| 1811 node->receiver()->AcceptExpressionVisitor(this); | 1805 node->receiver()->AcceptExpressionVisitor(this); |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2526 Push(argument); | 2520 Push(argument); |
| 2527 | 2521 |
| 2528 argument->set_temp_index(argument->temp_index() - 1); | 2522 argument->set_temp_index(argument->temp_index() - 1); |
| 2529 ++pending_argument_count_; | 2523 ++pending_argument_count_; |
| 2530 | 2524 |
| 2531 return Fragment(argument); | 2525 return Fragment(argument); |
| 2532 } | 2526 } |
| 2533 | 2527 |
| 2534 | 2528 |
| 2535 Fragment FlowGraphBuilder::Return(TokenPosition position) { | 2529 Fragment FlowGraphBuilder::Return(TokenPosition position) { |
| 2530 Fragment instructions; |
| 2531 |
| 2532 instructions += CheckReturnTypeInCheckedMode(); |
| 2533 |
| 2536 Value* value = Pop(); | 2534 Value* value = Pop(); |
| 2537 ASSERT(stack_ == NULL); | 2535 ASSERT(stack_ == NULL); |
| 2538 ReturnInstr* return_instr = | 2536 |
| 2539 new (Z) ReturnInstr(TokenPosition::kNoSource, value); | 2537 ReturnInstr* return_instr = new (Z) ReturnInstr(position, value); |
| 2540 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); | 2538 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); |
| 2541 return Fragment(return_instr).closed(); | 2539 |
| 2540 instructions <<= return_instr; |
| 2541 |
| 2542 return instructions.closed(); |
| 2542 } | 2543 } |
| 2543 | 2544 |
| 2544 | 2545 |
| 2545 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, | 2546 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, |
| 2546 const Function& target, | 2547 const Function& target, |
| 2547 intptr_t argument_count) { | 2548 intptr_t argument_count) { |
| 2548 return StaticCall(position, target, argument_count, Array::null_array()); | 2549 return StaticCall(position, target, argument_count, Array::null_array()); |
| 2549 } | 2550 } |
| 2550 | 2551 |
| 2551 | 2552 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2602 class_id, kAlignedAccess, Thread::kNoDeoptId, TokenPosition::kNoSource); | 2603 class_id, kAlignedAccess, Thread::kNoDeoptId, TokenPosition::kNoSource); |
| 2603 Push(store); | 2604 Push(store); |
| 2604 return Fragment(store); | 2605 return Fragment(store); |
| 2605 } | 2606 } |
| 2606 | 2607 |
| 2607 | 2608 |
| 2608 Fragment FlowGraphBuilder::StoreInstanceField( | 2609 Fragment FlowGraphBuilder::StoreInstanceField( |
| 2609 const dart::Field& field, | 2610 const dart::Field& field, |
| 2610 bool is_initialization_store, | 2611 bool is_initialization_store, |
| 2611 StoreBarrierType emit_store_barrier) { | 2612 StoreBarrierType emit_store_barrier) { |
| 2613 Fragment instructions; |
| 2614 |
| 2615 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); |
| 2616 instructions += CheckAssignableInCheckedMode( |
| 2617 dst_type, dart::String::ZoneHandle(Z, field.name())); |
| 2618 |
| 2612 Value* value = Pop(); | 2619 Value* value = Pop(); |
| 2613 if (value->BindsToConstant()) { | 2620 if (value->BindsToConstant()) { |
| 2614 emit_store_barrier = kNoStoreBarrier; | 2621 emit_store_barrier = kNoStoreBarrier; |
| 2615 } | 2622 } |
| 2623 |
| 2616 StoreInstanceFieldInstr* store = new (Z) | 2624 StoreInstanceFieldInstr* store = new (Z) |
| 2617 StoreInstanceFieldInstr(MayCloneField(Z, field), Pop(), value, | 2625 StoreInstanceFieldInstr(MayCloneField(Z, field), Pop(), value, |
| 2618 emit_store_barrier, TokenPosition::kNoSource); | 2626 emit_store_barrier, TokenPosition::kNoSource); |
| 2619 store->set_is_initialization(is_initialization_store); | 2627 store->set_is_initialization(is_initialization_store); |
| 2620 return Fragment(store); | 2628 instructions <<= store; |
| 2629 |
| 2630 return instructions; |
| 2621 } | 2631 } |
| 2622 | 2632 |
| 2623 | 2633 |
| 2624 Fragment FlowGraphBuilder::StoreInstanceFieldGuarded( | 2634 Fragment FlowGraphBuilder::StoreInstanceFieldGuarded( |
| 2625 const dart::Field& field, | 2635 const dart::Field& field, |
| 2626 bool is_initialization_store) { | 2636 bool is_initialization_store) { |
| 2627 Fragment instructions; | 2637 Fragment instructions; |
| 2628 const dart::Field& field_clone = MayCloneField(Z, field); | 2638 const dart::Field& field_clone = MayCloneField(Z, field); |
| 2629 if (FLAG_use_field_guards) { | 2639 if (FLAG_use_field_guards) { |
| 2630 LocalVariable* store_expression = MakeTemporary(); | 2640 LocalVariable* store_expression = MakeTemporary(); |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3086 // The argument was `null` and the receiver is not the null class (we only | 3096 // The argument was `null` and the receiver is not the null class (we only |
| 3087 // go into this branch for user-defined == operators) so we can return | 3097 // go into this branch for user-defined == operators) so we can return |
| 3088 // false. | 3098 // false. |
| 3089 Fragment null_fragment(null_entry); | 3099 Fragment null_fragment(null_entry); |
| 3090 null_fragment += Constant(Bool::False()); | 3100 null_fragment += Constant(Bool::False()); |
| 3091 null_fragment += Return(dart_function.end_token_pos()); | 3101 null_fragment += Return(dart_function.end_token_pos()); |
| 3092 | 3102 |
| 3093 body = Fragment(body.entry, non_null_entry); | 3103 body = Fragment(body.entry, non_null_entry); |
| 3094 } | 3104 } |
| 3095 | 3105 |
| 3106 // If we run in checked mode, we have to check the type of the passed |
| 3107 // arguments. |
| 3108 if (I->type_checks()) { |
| 3109 List<VariableDeclaration>& positional = function->positional_parameters(); |
| 3110 List<VariableDeclaration>& named = function->named_parameters(); |
| 3111 |
| 3112 for (intptr_t i = 0; i < positional.length(); i++) { |
| 3113 VariableDeclaration* variable = positional[i]; |
| 3114 body += LoadLocal(LookupVariable(variable)); |
| 3115 body += CheckVariableTypeInCheckedMode(variable); |
| 3116 body += Drop(); |
| 3117 } |
| 3118 for (intptr_t i = 0; i < named.length(); i++) { |
| 3119 VariableDeclaration* variable = named[i]; |
| 3120 body += LoadLocal(LookupVariable(variable)); |
| 3121 body += CheckVariableTypeInCheckedMode(variable); |
| 3122 body += Drop(); |
| 3123 } |
| 3124 } |
| 3125 |
| 3096 if (dart_function.is_native()) { | 3126 if (dart_function.is_native()) { |
| 3097 body += NativeFunctionBody(function, dart_function); | 3127 body += NativeFunctionBody(function, dart_function); |
| 3098 } else if (function->body() != NULL) { | 3128 } else if (function->body() != NULL) { |
| 3099 body += TranslateStatement(function->body()); | 3129 body += TranslateStatement(function->body()); |
| 3100 } | 3130 } |
| 3101 if (body.is_open()) { | 3131 if (body.is_open()) { |
| 3102 body += NullConstant(); | 3132 body += NullConstant(); |
| 3103 body += Return(dart_function.end_token_pos()); | 3133 body += Return(dart_function.end_token_pos()); |
| 3104 } | 3134 } |
| 3105 | 3135 |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3458 return Fragment(new (Z) GuardFieldLengthInstr(Pop(), field, deopt_id)); | 3488 return Fragment(new (Z) GuardFieldLengthInstr(Pop(), field, deopt_id)); |
| 3459 } | 3489 } |
| 3460 | 3490 |
| 3461 | 3491 |
| 3462 Fragment FlowGraphBuilder::GuardFieldClass(const dart::Field& field, | 3492 Fragment FlowGraphBuilder::GuardFieldClass(const dart::Field& field, |
| 3463 intptr_t deopt_id) { | 3493 intptr_t deopt_id) { |
| 3464 return Fragment(new (Z) GuardFieldClassInstr(Pop(), field, deopt_id)); | 3494 return Fragment(new (Z) GuardFieldClassInstr(Pop(), field, deopt_id)); |
| 3465 } | 3495 } |
| 3466 | 3496 |
| 3467 | 3497 |
| 3498 Fragment FlowGraphBuilder::CheckVariableTypeInCheckedMode( |
| 3499 VariableDeclaration* variable) { |
| 3500 if (I->type_checks()) { |
| 3501 const AbstractType& dst_type = T.TranslateType(variable->type()); |
| 3502 if (dst_type.IsMalformed()) { |
| 3503 return ThrowTypeError(); |
| 3504 } |
| 3505 return CheckAssignableInCheckedMode(dst_type, |
| 3506 H.DartSymbol(variable->name())); |
| 3507 } |
| 3508 return Fragment(); |
| 3509 } |
| 3510 |
| 3511 |
| 3512 Fragment FlowGraphBuilder::EvaluateAssertion() { |
| 3513 const dart::Class& klass = dart::Class::ZoneHandle( |
| 3514 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); |
| 3515 ASSERT(!klass.IsNull()); |
| 3516 const dart::Function& target = |
| 3517 dart::Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate( |
| 3518 H.DartSymbol("_evaluateAssertion"))); |
| 3519 ASSERT(!target.IsNull()); |
| 3520 return StaticCall(TokenPosition::kNoSource, target, 1); |
| 3521 } |
| 3522 |
| 3523 |
| 3524 Fragment FlowGraphBuilder::CheckReturnTypeInCheckedMode() { |
| 3525 if (I->type_checks()) { |
| 3526 const AbstractType& return_type = |
| 3527 AbstractType::Handle(Z, parsed_function_->function().result_type()); |
| 3528 return CheckAssignableInCheckedMode(return_type, Symbols::FunctionResult()); |
| 3529 } |
| 3530 return Fragment(); |
| 3531 } |
| 3532 |
| 3533 |
| 3534 Fragment FlowGraphBuilder::CheckBooleanInCheckedMode() { |
| 3535 Fragment instructions; |
| 3536 if (I->type_checks()) { |
| 3537 LocalVariable* top_of_stack = MakeTemporary(); |
| 3538 instructions += LoadLocal(top_of_stack); |
| 3539 instructions += AssertBool(); |
| 3540 instructions += Drop(); |
| 3541 } |
| 3542 return instructions; |
| 3543 } |
| 3544 |
| 3545 |
| 3546 Fragment FlowGraphBuilder::CheckAssignableInCheckedMode( |
| 3547 const dart::AbstractType& dst_type, |
| 3548 const dart::String& dst_name) { |
| 3549 Fragment instructions; |
| 3550 if (I->type_checks() && !dst_type.IsDynamicType() && |
| 3551 !dst_type.IsObjectType()) { |
| 3552 LocalVariable* top_of_stack = MakeTemporary(); |
| 3553 instructions += LoadLocal(top_of_stack); |
| 3554 instructions += AssertAssignable(dst_type, dst_name); |
| 3555 instructions += Drop(); |
| 3556 } |
| 3557 return instructions; |
| 3558 } |
| 3559 |
| 3560 |
| 3561 Fragment FlowGraphBuilder::AssertBool() { |
| 3562 Value* value = Pop(); |
| 3563 AssertBooleanInstr* instr = |
| 3564 new (Z) AssertBooleanInstr(TokenPosition::kNoSource, value); |
| 3565 Push(instr); |
| 3566 return Fragment(instr); |
| 3567 } |
| 3568 |
| 3569 |
| 3570 Fragment FlowGraphBuilder::AssertAssignable(const dart::AbstractType& dst_type, |
| 3571 const dart::String& dst_name) { |
| 3572 Fragment instructions; |
| 3573 Value* value = Pop(); |
| 3574 |
| 3575 instructions += LoadInstantiatorTypeArguments(); |
| 3576 Value* type_args = Pop(); |
| 3577 |
| 3578 AssertAssignableInstr* instr = new (Z) |
| 3579 AssertAssignableInstr(TokenPosition::kNoSource, value, type_args, |
| 3580 dst_type, dst_name, H.thread()->GetNextDeoptId()); |
| 3581 Push(instr); |
| 3582 |
| 3583 instructions += Fragment(instr); |
| 3584 |
| 3585 return instructions; |
| 3586 } |
| 3587 |
| 3588 |
| 3468 FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor( | 3589 FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor( |
| 3469 const Function& method) { | 3590 const Function& method) { |
| 3470 // A method extractor is the implicit getter for a method. | 3591 // A method extractor is the implicit getter for a method. |
| 3471 const Function& function = | 3592 const Function& function = |
| 3472 Function::ZoneHandle(Z, method.extracted_method_closure()); | 3593 Function::ZoneHandle(Z, method.extracted_method_closure()); |
| 3473 | 3594 |
| 3474 TargetEntryInstr* normal_entry = BuildTargetEntry(); | 3595 TargetEntryInstr* normal_entry = BuildTargetEntry(); |
| 3475 graph_entry_ = new (Z) | 3596 graph_entry_ = new (Z) |
| 3476 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); | 3597 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); |
| 3477 Fragment body(normal_entry); | 3598 Fragment body(normal_entry); |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3899 #endif | 4020 #endif |
| 3900 statement->AcceptStatementVisitor(this); | 4021 statement->AcceptStatementVisitor(this); |
| 3901 DEBUG_ASSERT(context_depth_ == original_context_depth); | 4022 DEBUG_ASSERT(context_depth_ == original_context_depth); |
| 3902 return fragment_; | 4023 return fragment_; |
| 3903 } | 4024 } |
| 3904 | 4025 |
| 3905 | 4026 |
| 3906 Fragment FlowGraphBuilder::TranslateCondition(Expression* expression, | 4027 Fragment FlowGraphBuilder::TranslateCondition(Expression* expression, |
| 3907 bool* negate) { | 4028 bool* negate) { |
| 3908 *negate = expression->IsNot(); | 4029 *negate = expression->IsNot(); |
| 4030 Fragment instructions; |
| 3909 if (*negate) { | 4031 if (*negate) { |
| 3910 return TranslateExpression(Not::Cast(expression)->expression()); | 4032 instructions += TranslateExpression(Not::Cast(expression)->expression()); |
| 4033 } else { |
| 4034 instructions += TranslateExpression(expression); |
| 3911 } | 4035 } |
| 3912 return TranslateExpression(expression); | 4036 instructions += CheckBooleanInCheckedMode(); |
| 4037 return instructions; |
| 3913 } | 4038 } |
| 3914 | 4039 |
| 3915 | 4040 |
| 3916 Fragment FlowGraphBuilder::TranslateExpression(Expression* expression) { | 4041 Fragment FlowGraphBuilder::TranslateExpression(Expression* expression) { |
| 3917 expression->AcceptExpressionVisitor(this); | 4042 expression->AcceptExpressionVisitor(this); |
| 3918 return fragment_; | 4043 return fragment_; |
| 3919 } | 4044 } |
| 3920 | 4045 |
| 3921 | 4046 |
| 3922 ArgumentArray FlowGraphBuilder::GetArguments(int count) { | 4047 ArgumentArray FlowGraphBuilder::GetArguments(int count) { |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4293 } | 4418 } |
| 4294 | 4419 |
| 4295 | 4420 |
| 4296 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { | 4421 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { |
| 4297 fragment_ = LoadLocal(LookupVariable(node->variable())); | 4422 fragment_ = LoadLocal(LookupVariable(node->variable())); |
| 4298 } | 4423 } |
| 4299 | 4424 |
| 4300 | 4425 |
| 4301 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { | 4426 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { |
| 4302 Fragment instructions = TranslateExpression(node->expression()); | 4427 Fragment instructions = TranslateExpression(node->expression()); |
| 4428 instructions += CheckVariableTypeInCheckedMode(node->variable()); |
| 4303 instructions += | 4429 instructions += |
| 4304 StoreLocal(node->position(), LookupVariable(node->variable())); | 4430 StoreLocal(node->position(), LookupVariable(node->variable())); |
| 4305 fragment_ = instructions; | 4431 fragment_ = instructions; |
| 4306 } | 4432 } |
| 4307 | 4433 |
| 4308 | 4434 |
| 4309 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { | 4435 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { |
| 4310 Member* target = node->target(); | 4436 Member* target = node->target(); |
| 4311 if (target->IsField()) { | 4437 if (target->IsField()) { |
| 4312 Field* kernel_field = Field::Cast(target); | 4438 Field* kernel_field = Field::Cast(target); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 4342 } | 4468 } |
| 4343 } | 4469 } |
| 4344 | 4470 |
| 4345 | 4471 |
| 4346 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { | 4472 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { |
| 4347 Member* target = node->target(); | 4473 Member* target = node->target(); |
| 4348 if (target->IsField()) { | 4474 if (target->IsField()) { |
| 4349 Field* kernel_field = Field::Cast(target); | 4475 Field* kernel_field = Field::Cast(target); |
| 4350 const dart::Field& field = | 4476 const dart::Field& field = |
| 4351 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); | 4477 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); |
| 4478 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); |
| 4352 Fragment instructions = TranslateExpression(node->expression()); | 4479 Fragment instructions = TranslateExpression(node->expression()); |
| 4480 instructions += CheckAssignableInCheckedMode( |
| 4481 dst_type, dart::String::ZoneHandle(Z, field.name())); |
| 4353 LocalVariable* variable = MakeTemporary(); | 4482 LocalVariable* variable = MakeTemporary(); |
| 4354 instructions += LoadLocal(variable); | 4483 instructions += LoadLocal(variable); |
| 4355 fragment_ = instructions + StoreStaticField(field); | 4484 fragment_ = instructions + StoreStaticField(field); |
| 4356 } else { | 4485 } else { |
| 4357 ASSERT(target->IsProcedure()); | 4486 ASSERT(target->IsProcedure()); |
| 4358 | 4487 |
| 4359 // Evaluate the expression on the right hand side. | 4488 // Evaluate the expression on the right hand side. |
| 4360 Fragment instructions = TranslateExpression(node->expression()); | 4489 Fragment instructions = TranslateExpression(node->expression()); |
| 4361 LocalVariable* variable = MakeTemporary(); | 4490 LocalVariable* variable = MakeTemporary(); |
| 4362 | 4491 |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4613 Constant(constant_evaluator_.EvaluateConstructorInvocation(node)); | 4742 Constant(constant_evaluator_.EvaluateConstructorInvocation(node)); |
| 4614 return; | 4743 return; |
| 4615 } | 4744 } |
| 4616 | 4745 |
| 4617 Class* kernel_class = Class::Cast(node->target()->parent()); | 4746 Class* kernel_class = Class::Cast(node->target()->parent()); |
| 4618 | 4747 |
| 4619 dart::Class& klass = | 4748 dart::Class& klass = |
| 4620 dart::Class::ZoneHandle(Z, H.LookupClassByKernelClass(kernel_class)); | 4749 dart::Class::ZoneHandle(Z, H.LookupClassByKernelClass(kernel_class)); |
| 4621 | 4750 |
| 4622 Fragment instructions; | 4751 Fragment instructions; |
| 4752 |
| 4753 // Check for malbounded-ness of type. |
| 4754 if (I->type_checks()) { |
| 4755 List<DartType>& kernel_type_arguments = node->arguments()->types(); |
| 4756 const TypeArguments& type_arguments = T.TranslateInstantiatedTypeArguments( |
| 4757 klass, kernel_type_arguments.raw_array(), |
| 4758 kernel_type_arguments.length()); |
| 4759 |
| 4760 AbstractType& type = AbstractType::Handle( |
| 4761 Z, Type::New(klass, type_arguments, TokenPosition::kNoSource)); |
| 4762 type = ClassFinalizer::FinalizeType(klass, type, |
| 4763 ClassFinalizer::kCanonicalize); |
| 4764 |
| 4765 if (type.IsMalbounded()) { |
| 4766 // Evaluate expressions for correctness. |
| 4767 List<Expression>& positional = node->arguments()->positional(); |
| 4768 List<NamedExpression>& named = node->arguments()->named(); |
| 4769 for (intptr_t i = 0; i < positional.length(); ++i) { |
| 4770 instructions += TranslateExpression(positional[i]); |
| 4771 instructions += Drop(); |
| 4772 } |
| 4773 for (intptr_t i = 0; i < named.length(); ++i) { |
| 4774 instructions += TranslateExpression(named[i]->expression()); |
| 4775 instructions += Drop(); |
| 4776 } |
| 4777 |
| 4778 // Throw an error & keep the [Value] on the stack. |
| 4779 instructions += ThrowTypeError(); |
| 4780 |
| 4781 // Bail out early. |
| 4782 fragment_ = instructions; |
| 4783 return; |
| 4784 } |
| 4785 } |
| 4786 |
| 4623 if (klass.NumTypeArguments() > 0) { | 4787 if (klass.NumTypeArguments() > 0) { |
| 4624 List<DartType>& kernel_type_arguments = node->arguments()->types(); | 4788 List<DartType>& kernel_type_arguments = node->arguments()->types(); |
| 4625 const TypeArguments& type_arguments = T.TranslateInstantiatedTypeArguments( | 4789 const TypeArguments& type_arguments = T.TranslateInstantiatedTypeArguments( |
| 4626 klass, kernel_type_arguments.raw_array(), | 4790 klass, kernel_type_arguments.raw_array(), |
| 4627 kernel_type_arguments.length()); | 4791 kernel_type_arguments.length()); |
| 4628 if (!klass.IsGeneric()) { | 4792 if (!klass.IsGeneric()) { |
| 4629 Type& type = Type::ZoneHandle(Z, T.ReceiverType(klass).raw()); | 4793 Type& type = Type::ZoneHandle(Z, T.ReceiverType(klass).raw()); |
| 4630 | 4794 |
| 4631 // TODO(27590): Can we move this code into [ReceiverType]? | 4795 // TODO(27590): Can we move this code into [ReceiverType]? |
| 4632 type ^= ClassFinalizer::FinalizeType(*active_class_.klass, type, | 4796 type ^= ClassFinalizer::FinalizeType(*active_class_.klass, type, |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4817 right_fragment += Goto(join); | 4981 right_fragment += Goto(join); |
| 4818 constant_fragment += Goto(join); | 4982 constant_fragment += Goto(join); |
| 4819 | 4983 |
| 4820 fragment_ = Fragment(instructions.entry, join) + | 4984 fragment_ = Fragment(instructions.entry, join) + |
| 4821 LoadLocal(parsed_function_->expression_temp_var()); | 4985 LoadLocal(parsed_function_->expression_temp_var()); |
| 4822 } | 4986 } |
| 4823 | 4987 |
| 4824 | 4988 |
| 4825 void FlowGraphBuilder::VisitNot(Not* node) { | 4989 void FlowGraphBuilder::VisitNot(Not* node) { |
| 4826 Fragment instructions = TranslateExpression(node->expression()); | 4990 Fragment instructions = TranslateExpression(node->expression()); |
| 4827 fragment_ = instructions + BooleanNegate(); | 4991 instructions += CheckBooleanInCheckedMode(); |
| 4992 instructions += BooleanNegate(); |
| 4993 fragment_ = instructions; |
| 4828 } | 4994 } |
| 4829 | 4995 |
| 4830 | 4996 |
| 4831 void FlowGraphBuilder::VisitThisExpression(ThisExpression* node) { | 4997 void FlowGraphBuilder::VisitThisExpression(ThisExpression* node) { |
| 4832 fragment_ = LoadLocal(scopes_->this_variable); | 4998 fragment_ = LoadLocal(scopes_->this_variable); |
| 4833 } | 4999 } |
| 4834 | 5000 |
| 4835 | 5001 |
| 4836 void FlowGraphBuilder::VisitStringConcatenation(StringConcatenation* node) { | 5002 void FlowGraphBuilder::VisitStringConcatenation(StringConcatenation* node) { |
| 4837 List<Expression>& expressions = node->expressions(); | 5003 List<Expression>& expressions = node->expressions(); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5077 if (initializer == NULL) { | 5243 if (initializer == NULL) { |
| 5078 instructions += NullConstant(); | 5244 instructions += NullConstant(); |
| 5079 } else { | 5245 } else { |
| 5080 if (node->IsConst()) { | 5246 if (node->IsConst()) { |
| 5081 const Instance& constant_value = | 5247 const Instance& constant_value = |
| 5082 constant_evaluator_.EvaluateExpression(initializer); | 5248 constant_evaluator_.EvaluateExpression(initializer); |
| 5083 variable->SetConstValue(constant_value); | 5249 variable->SetConstValue(constant_value); |
| 5084 instructions += Constant(constant_value); | 5250 instructions += Constant(constant_value); |
| 5085 } else { | 5251 } else { |
| 5086 instructions += TranslateExpression(initializer); | 5252 instructions += TranslateExpression(initializer); |
| 5253 instructions += CheckVariableTypeInCheckedMode(node); |
| 5087 } | 5254 } |
| 5088 } | 5255 } |
| 5089 instructions += StoreLocal(variable->token_pos(), variable); | 5256 instructions += StoreLocal(variable->token_pos(), variable); |
| 5090 instructions += Drop(); | 5257 instructions += Drop(); |
| 5091 fragment_ = instructions; | 5258 fragment_ = instructions; |
| 5092 } | 5259 } |
| 5093 | 5260 |
| 5094 | 5261 |
| 5095 void FlowGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { | 5262 void FlowGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { |
| 5096 Fragment instructions = TranslateFunctionNode(node->function(), node); | 5263 Fragment instructions = TranslateFunctionNode(node->function(), node); |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5541 | 5708 |
| 5542 void FlowGraphBuilder::VisitAssertStatement(AssertStatement* node) { | 5709 void FlowGraphBuilder::VisitAssertStatement(AssertStatement* node) { |
| 5543 if (!I->asserts()) { | 5710 if (!I->asserts()) { |
| 5544 fragment_ = Fragment(); | 5711 fragment_ = Fragment(); |
| 5545 return; | 5712 return; |
| 5546 } | 5713 } |
| 5547 | 5714 |
| 5548 TargetEntryInstr* then; | 5715 TargetEntryInstr* then; |
| 5549 TargetEntryInstr* otherwise; | 5716 TargetEntryInstr* otherwise; |
| 5550 | 5717 |
| 5551 bool negate; | |
| 5552 Fragment instructions; | 5718 Fragment instructions; |
| 5553 instructions += TranslateCondition(node->condition(), &negate); | 5719 // Asserts can be of the following two kinds: |
| 5554 instructions += BranchIfTrue(&then, &otherwise, negate); | 5720 // |
| 5721 // * `assert(expr)` |
| 5722 // * `assert(() { ... })` |
| 5723 // |
| 5724 // The call to `_AssertionError._evaluateAssertion()` will take care of both |
| 5725 // and returns a boolean. |
| 5726 instructions += TranslateExpression(node->condition()); |
| 5727 instructions += PushArgument(); |
| 5728 instructions += EvaluateAssertion(); |
| 5729 instructions += CheckBooleanInCheckedMode(); |
| 5730 instructions += Constant(Bool::True()); |
| 5731 instructions += BranchIfEqual(&then, &otherwise, false); |
| 5555 | 5732 |
| 5556 const dart::Class& klass = dart::Class::ZoneHandle( | 5733 const dart::Class& klass = dart::Class::ZoneHandle( |
| 5557 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); | 5734 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); |
| 5558 ASSERT(!klass.IsNull()); | 5735 ASSERT(!klass.IsNull()); |
| 5559 const dart::Function& constructor = dart::Function::ZoneHandle( | 5736 const dart::Function& constructor = dart::Function::ZoneHandle( |
| 5560 Z, klass.LookupConstructorAllowPrivate( | 5737 Z, klass.LookupConstructorAllowPrivate( |
| 5561 H.DartSymbol("_AssertionError._create"))); | 5738 H.DartSymbol("_AssertionError._create"))); |
| 5562 ASSERT(!constructor.IsNull()); | 5739 ASSERT(!constructor.IsNull()); |
| 5563 | 5740 |
| 5564 const dart::String& url = H.DartString( | 5741 const dart::String& url = H.DartString( |
| 5565 parsed_function_->function().ToLibNamePrefixedQualifiedCString(), | 5742 parsed_function_->function().ToLibNamePrefixedQualifiedCString(), |
| 5566 Heap::kOld); | 5743 Heap::kOld); |
| 5567 | 5744 |
| 5568 // Create instance of _AssertionError | 5745 // Create instance of _AssertionError |
| 5569 Fragment otherwise_fragment(otherwise); | 5746 Fragment otherwise_fragment(otherwise); |
| 5570 otherwise_fragment += AllocateObject(klass, 0); | 5747 otherwise_fragment += AllocateObject(klass, 0); |
| 5571 LocalVariable* instance = MakeTemporary(); | 5748 LocalVariable* instance = MakeTemporary(); |
| 5572 | 5749 |
| 5573 // Call _AssertionError._create constructor. | 5750 // Call _AssertionError._create constructor. |
| 5574 otherwise_fragment += LoadLocal(instance); | 5751 otherwise_fragment += LoadLocal(instance); |
| 5575 otherwise_fragment += PushArgument(); // this | 5752 otherwise_fragment += PushArgument(); // this |
| 5576 | 5753 |
| 5577 otherwise_fragment += | 5754 otherwise_fragment += Constant(H.DartString("<no message>", Heap::kOld)); |
| 5578 node->message() != NULL | |
| 5579 ? TranslateExpression(node->message()) | |
| 5580 : Constant(H.DartString("<no message>", Heap::kOld)); | |
| 5581 otherwise_fragment += PushArgument(); // failedAssertion | 5755 otherwise_fragment += PushArgument(); // failedAssertion |
| 5582 | 5756 |
| 5583 otherwise_fragment += Constant(url); | 5757 otherwise_fragment += Constant(url); |
| 5584 otherwise_fragment += PushArgument(); // url | 5758 otherwise_fragment += PushArgument(); // url |
| 5585 | 5759 |
| 5586 otherwise_fragment += IntConstant(0); | 5760 otherwise_fragment += IntConstant(0); |
| 5587 otherwise_fragment += PushArgument(); // line | 5761 otherwise_fragment += PushArgument(); // line |
| 5588 | 5762 |
| 5589 otherwise_fragment += IntConstant(0); | 5763 otherwise_fragment += IntConstant(0); |
| 5590 otherwise_fragment += PushArgument(); // column | 5764 otherwise_fragment += PushArgument(); // column |
| 5591 | 5765 |
| 5592 otherwise_fragment += Constant(H.DartString("<no message>", Heap::kOld)); | 5766 otherwise_fragment += |
| 5767 node->message() != NULL |
| 5768 ? TranslateExpression(node->message()) |
| 5769 : Constant(H.DartString("<no message>", Heap::kOld)); |
| 5593 otherwise_fragment += PushArgument(); // message | 5770 otherwise_fragment += PushArgument(); // message |
| 5594 | 5771 |
| 5595 otherwise_fragment += StaticCall(TokenPosition::kNoSource, constructor, 6); | 5772 otherwise_fragment += StaticCall(TokenPosition::kNoSource, constructor, 6); |
| 5596 otherwise_fragment += Drop(); | 5773 otherwise_fragment += Drop(); |
| 5597 | 5774 |
| 5598 // Throw _AssertionError exception. | 5775 // Throw _AssertionError exception. |
| 5599 otherwise_fragment += PushArgument(); | 5776 otherwise_fragment += PushArgument(); |
| 5600 otherwise_fragment += ThrowException(TokenPosition::kNoSource); | 5777 otherwise_fragment += ThrowException(TokenPosition::kNoSource); |
| 5601 otherwise_fragment += Drop(); | 5778 otherwise_fragment += Drop(); |
| 5602 | 5779 |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6045 thread->clear_sticky_error(); | 6222 thread->clear_sticky_error(); |
| 6046 return error.raw(); | 6223 return error.raw(); |
| 6047 } | 6224 } |
| 6048 } | 6225 } |
| 6049 | 6226 |
| 6050 | 6227 |
| 6051 } // namespace kernel | 6228 } // namespace kernel |
| 6052 } // namespace dart | 6229 } // namespace dart |
| 6053 | 6230 |
| 6054 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6231 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |