Chromium Code Reviews| 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 1752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 EvaluateExpression(node->condition()); |
| 1773 if (Bool::Cast(result_).value()) { | 1773 if (result_.raw() == Bool::True().raw()) { |
| 1774 EvaluateExpression(node->then()); | 1774 EvaluateExpression(node->then()); |
| 1775 } else { | 1775 } else { |
| 1776 MaybeCheckBool(); | |
| 1776 EvaluateExpression(node->otherwise()); | 1777 EvaluateExpression(node->otherwise()); |
| 1777 } | 1778 } |
| 1778 } | 1779 } |
| 1779 | 1780 |
| 1780 | 1781 |
| 1781 void ConstantEvaluator::VisitLogicalExpression(LogicalExpression* node) { | 1782 void ConstantEvaluator::VisitLogicalExpression(LogicalExpression* node) { |
| 1782 if (node->op() == LogicalExpression::kAnd) { | 1783 if (node->op() == LogicalExpression::kAnd) { |
| 1783 EvaluateExpression(node->left()); | 1784 EvaluateExpression(node->left()); |
| 1785 MaybeCheckBool(); | |
|
Vyacheslav Egorov (Google)
2017/01/30 18:30:28
Consider making a helper:
EvaluateBooleanExpres
kustermann
2017/01/31 10:39:45
Done.
| |
| 1784 if (Bool::Cast(result_).value()) { | 1786 if (Bool::Cast(result_).value()) { |
| 1785 EvaluateExpression(node->right()); | 1787 EvaluateExpression(node->right()); |
| 1788 MaybeCheckBool(); | |
| 1786 } | 1789 } |
| 1787 } else { | 1790 } else { |
| 1788 ASSERT(node->op() == LogicalExpression::kOr); | 1791 ASSERT(node->op() == LogicalExpression::kOr); |
| 1789 EvaluateExpression(node->left()); | 1792 EvaluateExpression(node->left()); |
| 1793 MaybeCheckBool(); | |
| 1790 if (!Bool::Cast(result_).value()) { | 1794 if (!Bool::Cast(result_).value()) { |
| 1791 EvaluateExpression(node->right()); | 1795 EvaluateExpression(node->right()); |
| 1796 MaybeCheckBool(); | |
| 1792 } | 1797 } |
| 1793 } | 1798 } |
| 1794 } | 1799 } |
| 1795 | 1800 |
| 1796 | 1801 |
| 1797 void ConstantEvaluator::VisitNot(Not* node) { | 1802 void ConstantEvaluator::VisitNot(Not* node) { |
| 1798 EvaluateExpression(node->expression()); | 1803 EvaluateExpression(node->expression()); |
| 1799 ASSERT(result_.IsBool()); | 1804 if (result_.raw() == Bool::True().raw()) { |
| 1800 result_ = | 1805 result_ = Bool::False().raw(); |
| 1801 Bool::Cast(result_).value() ? Bool::False().raw() : Bool::True().raw(); | 1806 } else { |
| 1807 MaybeCheckBool(); | |
| 1808 result_ = Bool::True().raw(); | |
| 1809 } | |
| 1802 } | 1810 } |
| 1803 | 1811 |
| 1804 | 1812 |
| 1805 void ConstantEvaluator::VisitPropertyGet(PropertyGet* node) { | 1813 void ConstantEvaluator::VisitPropertyGet(PropertyGet* node) { |
| 1806 const size_t kLengthLen = strlen("length"); | 1814 const size_t kLengthLen = strlen("length"); |
| 1807 | 1815 |
| 1808 String* string = node->name()->string(); | 1816 String* string = node->name()->string(); |
| 1809 if (string->size() == kLengthLen && | 1817 if (string->size() == kLengthLen && |
| 1810 memcmp(string->buffer(), "length", kLengthLen) == 0) { | 1818 memcmp(string->buffer(), "length", kLengthLen) == 0) { |
| 1811 node->receiver()->AcceptExpressionVisitor(this); | 1819 node->receiver()->AcceptExpressionVisitor(this); |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2526 Push(argument); | 2534 Push(argument); |
| 2527 | 2535 |
| 2528 argument->set_temp_index(argument->temp_index() - 1); | 2536 argument->set_temp_index(argument->temp_index() - 1); |
| 2529 ++pending_argument_count_; | 2537 ++pending_argument_count_; |
| 2530 | 2538 |
| 2531 return Fragment(argument); | 2539 return Fragment(argument); |
| 2532 } | 2540 } |
| 2533 | 2541 |
| 2534 | 2542 |
| 2535 Fragment FlowGraphBuilder::Return(TokenPosition position) { | 2543 Fragment FlowGraphBuilder::Return(TokenPosition position) { |
| 2544 Fragment instructions; | |
| 2545 | |
| 2546 instructions += MaybeCheckReturnType(); | |
|
Vyacheslav Egorov (Google)
2017/01/30 18:30:28
Maybe "maybe" is not a good prefix because it does
kustermann
2017/01/31 10:39:45
Done.
| |
| 2547 | |
| 2536 Value* value = Pop(); | 2548 Value* value = Pop(); |
| 2537 ASSERT(stack_ == NULL); | 2549 ASSERT(stack_ == NULL); |
| 2538 ReturnInstr* return_instr = | 2550 |
| 2539 new (Z) ReturnInstr(TokenPosition::kNoSource, value); | 2551 ReturnInstr* return_instr = new (Z) ReturnInstr(position, value); |
| 2540 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); | 2552 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); |
| 2541 return Fragment(return_instr).closed(); | 2553 |
| 2554 instructions <<= return_instr; | |
| 2555 | |
| 2556 return instructions.closed(); | |
| 2542 } | 2557 } |
| 2543 | 2558 |
| 2544 | 2559 |
| 2545 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, | 2560 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, |
| 2546 const Function& target, | 2561 const Function& target, |
| 2547 intptr_t argument_count) { | 2562 intptr_t argument_count) { |
| 2548 return StaticCall(position, target, argument_count, Array::null_array()); | 2563 return StaticCall(position, target, argument_count, Array::null_array()); |
| 2549 } | 2564 } |
| 2550 | 2565 |
| 2551 | 2566 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2602 class_id, kAlignedAccess, Thread::kNoDeoptId, TokenPosition::kNoSource); | 2617 class_id, kAlignedAccess, Thread::kNoDeoptId, TokenPosition::kNoSource); |
| 2603 Push(store); | 2618 Push(store); |
| 2604 return Fragment(store); | 2619 return Fragment(store); |
| 2605 } | 2620 } |
| 2606 | 2621 |
| 2607 | 2622 |
| 2608 Fragment FlowGraphBuilder::StoreInstanceField( | 2623 Fragment FlowGraphBuilder::StoreInstanceField( |
| 2609 const dart::Field& field, | 2624 const dart::Field& field, |
| 2610 bool is_initialization_store, | 2625 bool is_initialization_store, |
| 2611 StoreBarrierType emit_store_barrier) { | 2626 StoreBarrierType emit_store_barrier) { |
| 2627 Fragment instructions; | |
| 2628 | |
| 2629 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); | |
| 2630 instructions += | |
| 2631 MaybeCheckAssignable(dst_type, dart::String::ZoneHandle(Z, field.name())); | |
| 2632 | |
| 2612 Value* value = Pop(); | 2633 Value* value = Pop(); |
| 2613 if (value->BindsToConstant()) { | 2634 if (value->BindsToConstant()) { |
| 2614 emit_store_barrier = kNoStoreBarrier; | 2635 emit_store_barrier = kNoStoreBarrier; |
| 2615 } | 2636 } |
| 2637 | |
| 2616 StoreInstanceFieldInstr* store = new (Z) | 2638 StoreInstanceFieldInstr* store = new (Z) |
| 2617 StoreInstanceFieldInstr(MayCloneField(Z, field), Pop(), value, | 2639 StoreInstanceFieldInstr(MayCloneField(Z, field), Pop(), value, |
| 2618 emit_store_barrier, TokenPosition::kNoSource); | 2640 emit_store_barrier, TokenPosition::kNoSource); |
| 2619 store->set_is_initialization(is_initialization_store); | 2641 store->set_is_initialization(is_initialization_store); |
| 2620 return Fragment(store); | 2642 instructions <<= store; |
| 2643 | |
| 2644 return instructions; | |
| 2621 } | 2645 } |
| 2622 | 2646 |
| 2623 | 2647 |
| 2624 Fragment FlowGraphBuilder::StoreInstanceFieldGuarded( | 2648 Fragment FlowGraphBuilder::StoreInstanceFieldGuarded( |
| 2625 const dart::Field& field, | 2649 const dart::Field& field, |
| 2626 bool is_initialization_store) { | 2650 bool is_initialization_store) { |
| 2627 Fragment instructions; | 2651 Fragment instructions; |
| 2628 const dart::Field& field_clone = MayCloneField(Z, field); | 2652 const dart::Field& field_clone = MayCloneField(Z, field); |
| 2629 if (FLAG_use_field_guards) { | 2653 if (FLAG_use_field_guards) { |
| 2630 LocalVariable* store_expression = MakeTemporary(); | 2654 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 | 3110 // 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 | 3111 // go into this branch for user-defined == operators) so we can return |
| 3088 // false. | 3112 // false. |
| 3089 Fragment null_fragment(null_entry); | 3113 Fragment null_fragment(null_entry); |
| 3090 null_fragment += Constant(Bool::False()); | 3114 null_fragment += Constant(Bool::False()); |
| 3091 null_fragment += Return(dart_function.end_token_pos()); | 3115 null_fragment += Return(dart_function.end_token_pos()); |
| 3092 | 3116 |
| 3093 body = Fragment(body.entry, non_null_entry); | 3117 body = Fragment(body.entry, non_null_entry); |
| 3094 } | 3118 } |
| 3095 | 3119 |
| 3120 // If we run in checked mode, we have to check the type of the passed | |
| 3121 // arguments. | |
| 3122 if (I->type_checks()) { | |
| 3123 List<VariableDeclaration>& positional = function->positional_parameters(); | |
| 3124 List<VariableDeclaration>& named = function->named_parameters(); | |
| 3125 | |
| 3126 for (intptr_t i = 0; i < positional.length(); i++) { | |
| 3127 VariableDeclaration* variable = positional[i]; | |
| 3128 body += LoadLocal(LookupVariable(variable)); | |
| 3129 body += MaybeCheckVariableType(variable); | |
| 3130 body += Drop(); | |
| 3131 } | |
| 3132 for (intptr_t i = 0; i < named.length(); i++) { | |
| 3133 VariableDeclaration* variable = named[i]; | |
| 3134 body += LoadLocal(LookupVariable(variable)); | |
| 3135 body += MaybeCheckVariableType(variable); | |
| 3136 body += Drop(); | |
| 3137 } | |
| 3138 } | |
| 3139 | |
| 3096 if (dart_function.is_native()) { | 3140 if (dart_function.is_native()) { |
| 3097 body += NativeFunctionBody(function, dart_function); | 3141 body += NativeFunctionBody(function, dart_function); |
| 3098 } else if (function->body() != NULL) { | 3142 } else if (function->body() != NULL) { |
| 3099 body += TranslateStatement(function->body()); | 3143 body += TranslateStatement(function->body()); |
| 3100 } | 3144 } |
| 3101 if (body.is_open()) { | 3145 if (body.is_open()) { |
| 3102 body += NullConstant(); | 3146 body += NullConstant(); |
| 3103 body += Return(dart_function.end_token_pos()); | 3147 body += Return(dart_function.end_token_pos()); |
| 3104 } | 3148 } |
| 3105 | 3149 |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3458 return Fragment(new (Z) GuardFieldLengthInstr(Pop(), field, deopt_id)); | 3502 return Fragment(new (Z) GuardFieldLengthInstr(Pop(), field, deopt_id)); |
| 3459 } | 3503 } |
| 3460 | 3504 |
| 3461 | 3505 |
| 3462 Fragment FlowGraphBuilder::GuardFieldClass(const dart::Field& field, | 3506 Fragment FlowGraphBuilder::GuardFieldClass(const dart::Field& field, |
| 3463 intptr_t deopt_id) { | 3507 intptr_t deopt_id) { |
| 3464 return Fragment(new (Z) GuardFieldClassInstr(Pop(), field, deopt_id)); | 3508 return Fragment(new (Z) GuardFieldClassInstr(Pop(), field, deopt_id)); |
| 3465 } | 3509 } |
| 3466 | 3510 |
| 3467 | 3511 |
| 3512 Fragment FlowGraphBuilder::MaybeCheckVariableType( | |
| 3513 VariableDeclaration* variable) { | |
| 3514 if (I->type_checks()) { | |
| 3515 const AbstractType& dst_type = T.TranslateType(variable->type()); | |
| 3516 if (dst_type.IsMalformed()) { | |
| 3517 return ThrowTypeError(); | |
| 3518 } | |
| 3519 return MaybeCheckAssignable(dst_type, H.DartSymbol(variable->name())); | |
| 3520 } | |
| 3521 return Fragment(); | |
| 3522 } | |
| 3523 | |
| 3524 | |
| 3525 Fragment FlowGraphBuilder::EvaluateAssertion() { | |
| 3526 const dart::Class& klass = dart::Class::ZoneHandle( | |
| 3527 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); | |
| 3528 ASSERT(!klass.IsNull()); | |
| 3529 const dart::Function& target = | |
| 3530 dart::Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate( | |
| 3531 H.DartSymbol("_evaluateAssertion"))); | |
| 3532 ASSERT(!target.IsNull()); | |
| 3533 return StaticCall(TokenPosition::kNoSource, target, 1); | |
| 3534 } | |
| 3535 | |
| 3536 | |
| 3537 Fragment FlowGraphBuilder::MaybeCheckReturnType() { | |
| 3538 if (I->type_checks()) { | |
| 3539 const AbstractType& return_type = | |
| 3540 AbstractType::Handle(Z, parsed_function_->function().result_type()); | |
| 3541 return MaybeCheckAssignable(return_type, Symbols::FunctionResult()); | |
| 3542 } | |
| 3543 return Fragment(); | |
| 3544 } | |
| 3545 | |
| 3546 | |
| 3547 Fragment FlowGraphBuilder::MaybeCheckBool() { | |
| 3548 Fragment instructions; | |
| 3549 if (I->type_checks()) { | |
| 3550 LocalVariable* top_of_stack = MakeTemporary(); | |
| 3551 instructions += LoadLocal(top_of_stack); | |
| 3552 instructions += AssertBool(); | |
| 3553 instructions += Drop(); | |
| 3554 } | |
| 3555 return instructions; | |
| 3556 } | |
| 3557 | |
| 3558 | |
| 3559 Fragment FlowGraphBuilder::MaybeCheckAssignable( | |
| 3560 const dart::AbstractType& dst_type, | |
| 3561 const dart::String& dst_name) { | |
| 3562 Fragment instructions; | |
| 3563 if (I->type_checks() && !dst_type.IsDynamicType() && | |
| 3564 !dst_type.IsObjectType()) { | |
| 3565 LocalVariable* top_of_stack = MakeTemporary(); | |
| 3566 instructions += LoadLocal(top_of_stack); | |
| 3567 instructions += AssertAssignable(dst_type, dst_name); | |
| 3568 instructions += Drop(); | |
| 3569 } | |
| 3570 return instructions; | |
| 3571 } | |
| 3572 | |
| 3573 | |
| 3574 Fragment FlowGraphBuilder::AssertBool() { | |
| 3575 Value* value = Pop(); | |
| 3576 AssertBooleanInstr* instr = | |
| 3577 new (Z) AssertBooleanInstr(TokenPosition::kNoSource, value); | |
| 3578 Push(instr); | |
| 3579 return Fragment(instr); | |
| 3580 } | |
| 3581 | |
| 3582 | |
| 3583 Fragment FlowGraphBuilder::AssertAssignable(const dart::AbstractType& dst_type, | |
| 3584 const dart::String& dst_name) { | |
| 3585 Fragment instructions; | |
| 3586 Value* value = Pop(); | |
| 3587 | |
| 3588 instructions += LoadInstantiatorTypeArguments(); | |
| 3589 Value* type_args = Pop(); | |
| 3590 | |
| 3591 AssertAssignableInstr* instr = new (Z) | |
| 3592 AssertAssignableInstr(TokenPosition::kNoSource, value, type_args, | |
| 3593 dst_type, dst_name, H.thread()->GetNextDeoptId()); | |
| 3594 Push(instr); | |
| 3595 | |
| 3596 instructions += Fragment(instr); | |
| 3597 | |
| 3598 return instructions; | |
| 3599 } | |
| 3600 | |
| 3601 | |
| 3468 FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor( | 3602 FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor( |
| 3469 const Function& method) { | 3603 const Function& method) { |
| 3470 // A method extractor is the implicit getter for a method. | 3604 // A method extractor is the implicit getter for a method. |
| 3471 const Function& function = | 3605 const Function& function = |
| 3472 Function::ZoneHandle(Z, method.extracted_method_closure()); | 3606 Function::ZoneHandle(Z, method.extracted_method_closure()); |
| 3473 | 3607 |
| 3474 TargetEntryInstr* normal_entry = BuildTargetEntry(); | 3608 TargetEntryInstr* normal_entry = BuildTargetEntry(); |
| 3475 graph_entry_ = new (Z) | 3609 graph_entry_ = new (Z) |
| 3476 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); | 3610 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); |
| 3477 Fragment body(normal_entry); | 3611 Fragment body(normal_entry); |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3899 #endif | 4033 #endif |
| 3900 statement->AcceptStatementVisitor(this); | 4034 statement->AcceptStatementVisitor(this); |
| 3901 DEBUG_ASSERT(context_depth_ == original_context_depth); | 4035 DEBUG_ASSERT(context_depth_ == original_context_depth); |
| 3902 return fragment_; | 4036 return fragment_; |
| 3903 } | 4037 } |
| 3904 | 4038 |
| 3905 | 4039 |
| 3906 Fragment FlowGraphBuilder::TranslateCondition(Expression* expression, | 4040 Fragment FlowGraphBuilder::TranslateCondition(Expression* expression, |
| 3907 bool* negate) { | 4041 bool* negate) { |
| 3908 *negate = expression->IsNot(); | 4042 *negate = expression->IsNot(); |
| 4043 Fragment instructions; | |
| 3909 if (*negate) { | 4044 if (*negate) { |
| 3910 return TranslateExpression(Not::Cast(expression)->expression()); | 4045 instructions += TranslateExpression(Not::Cast(expression)->expression()); |
| 4046 } else { | |
| 4047 instructions += TranslateExpression(expression); | |
| 3911 } | 4048 } |
| 3912 return TranslateExpression(expression); | 4049 instructions += MaybeCheckBool(); |
| 4050 return instructions; | |
| 3913 } | 4051 } |
| 3914 | 4052 |
| 3915 | 4053 |
| 3916 Fragment FlowGraphBuilder::TranslateExpression(Expression* expression) { | 4054 Fragment FlowGraphBuilder::TranslateExpression(Expression* expression) { |
| 3917 expression->AcceptExpressionVisitor(this); | 4055 expression->AcceptExpressionVisitor(this); |
| 3918 return fragment_; | 4056 return fragment_; |
| 3919 } | 4057 } |
| 3920 | 4058 |
| 3921 | 4059 |
| 3922 ArgumentArray FlowGraphBuilder::GetArguments(int count) { | 4060 ArgumentArray FlowGraphBuilder::GetArguments(int count) { |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4293 } | 4431 } |
| 4294 | 4432 |
| 4295 | 4433 |
| 4296 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { | 4434 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { |
| 4297 fragment_ = LoadLocal(LookupVariable(node->variable())); | 4435 fragment_ = LoadLocal(LookupVariable(node->variable())); |
| 4298 } | 4436 } |
| 4299 | 4437 |
| 4300 | 4438 |
| 4301 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { | 4439 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { |
| 4302 Fragment instructions = TranslateExpression(node->expression()); | 4440 Fragment instructions = TranslateExpression(node->expression()); |
| 4441 instructions += MaybeCheckVariableType(node->variable()); | |
| 4303 instructions += | 4442 instructions += |
| 4304 StoreLocal(node->position(), LookupVariable(node->variable())); | 4443 StoreLocal(node->position(), LookupVariable(node->variable())); |
| 4305 fragment_ = instructions; | 4444 fragment_ = instructions; |
| 4306 } | 4445 } |
| 4307 | 4446 |
| 4308 | 4447 |
| 4309 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { | 4448 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { |
| 4310 Member* target = node->target(); | 4449 Member* target = node->target(); |
| 4311 if (target->IsField()) { | 4450 if (target->IsField()) { |
| 4312 Field* kernel_field = Field::Cast(target); | 4451 Field* kernel_field = Field::Cast(target); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 4342 } | 4481 } |
| 4343 } | 4482 } |
| 4344 | 4483 |
| 4345 | 4484 |
| 4346 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { | 4485 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { |
| 4347 Member* target = node->target(); | 4486 Member* target = node->target(); |
| 4348 if (target->IsField()) { | 4487 if (target->IsField()) { |
| 4349 Field* kernel_field = Field::Cast(target); | 4488 Field* kernel_field = Field::Cast(target); |
| 4350 const dart::Field& field = | 4489 const dart::Field& field = |
| 4351 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); | 4490 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); |
| 4491 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); | |
| 4352 Fragment instructions = TranslateExpression(node->expression()); | 4492 Fragment instructions = TranslateExpression(node->expression()); |
| 4493 instructions += MaybeCheckAssignable( | |
| 4494 dst_type, dart::String::ZoneHandle(Z, field.name())); | |
| 4353 LocalVariable* variable = MakeTemporary(); | 4495 LocalVariable* variable = MakeTemporary(); |
| 4354 instructions += LoadLocal(variable); | 4496 instructions += LoadLocal(variable); |
| 4355 fragment_ = instructions + StoreStaticField(field); | 4497 fragment_ = instructions + StoreStaticField(field); |
| 4356 } else { | 4498 } else { |
| 4357 ASSERT(target->IsProcedure()); | 4499 ASSERT(target->IsProcedure()); |
| 4358 | 4500 |
| 4359 // Evaluate the expression on the right hand side. | 4501 // Evaluate the expression on the right hand side. |
| 4360 Fragment instructions = TranslateExpression(node->expression()); | 4502 Fragment instructions = TranslateExpression(node->expression()); |
| 4361 LocalVariable* variable = MakeTemporary(); | 4503 LocalVariable* variable = MakeTemporary(); |
| 4362 | 4504 |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4613 Constant(constant_evaluator_.EvaluateConstructorInvocation(node)); | 4755 Constant(constant_evaluator_.EvaluateConstructorInvocation(node)); |
| 4614 return; | 4756 return; |
| 4615 } | 4757 } |
| 4616 | 4758 |
| 4617 Class* kernel_class = Class::Cast(node->target()->parent()); | 4759 Class* kernel_class = Class::Cast(node->target()->parent()); |
| 4618 | 4760 |
| 4619 dart::Class& klass = | 4761 dart::Class& klass = |
| 4620 dart::Class::ZoneHandle(Z, H.LookupClassByKernelClass(kernel_class)); | 4762 dart::Class::ZoneHandle(Z, H.LookupClassByKernelClass(kernel_class)); |
| 4621 | 4763 |
| 4622 Fragment instructions; | 4764 Fragment instructions; |
| 4765 | |
| 4766 // Check for malbounded-ness of type. | |
| 4767 if (I->type_checks()) { | |
| 4768 List<DartType>& kernel_type_arguments = node->arguments()->types(); | |
| 4769 const TypeArguments& type_arguments = T.TranslateInstantiatedTypeArguments( | |
| 4770 klass, kernel_type_arguments.raw_array(), | |
| 4771 kernel_type_arguments.length()); | |
| 4772 | |
| 4773 AbstractType& type = AbstractType::Handle( | |
| 4774 Z, Type::New(klass, type_arguments, TokenPosition::kNoSource)); | |
| 4775 type = ClassFinalizer::FinalizeType(klass, type, | |
| 4776 ClassFinalizer::kCanonicalize); | |
| 4777 | |
| 4778 if (type.IsMalbounded()) { | |
| 4779 // Evaluate expressions for correctness. | |
| 4780 List<Expression>& positional = node->arguments()->positional(); | |
| 4781 List<NamedExpression>& named = node->arguments()->named(); | |
| 4782 for (intptr_t i = 0; i < positional.length(); ++i) { | |
| 4783 instructions += TranslateExpression(positional[i]); | |
| 4784 instructions += Drop(); | |
| 4785 } | |
| 4786 for (intptr_t i = 0; i < named.length(); ++i) { | |
| 4787 instructions += TranslateExpression(named[i]->expression()); | |
| 4788 instructions += Drop(); | |
| 4789 } | |
| 4790 | |
| 4791 // Throw an error & keep the [Value] on the stack. | |
| 4792 instructions += ThrowTypeError(); | |
| 4793 | |
| 4794 // Bail out early. | |
| 4795 fragment_ = instructions; | |
| 4796 return; | |
| 4797 } | |
| 4798 } | |
| 4799 | |
| 4623 if (klass.NumTypeArguments() > 0) { | 4800 if (klass.NumTypeArguments() > 0) { |
| 4624 List<DartType>& kernel_type_arguments = node->arguments()->types(); | 4801 List<DartType>& kernel_type_arguments = node->arguments()->types(); |
| 4625 const TypeArguments& type_arguments = T.TranslateInstantiatedTypeArguments( | 4802 const TypeArguments& type_arguments = T.TranslateInstantiatedTypeArguments( |
| 4626 klass, kernel_type_arguments.raw_array(), | 4803 klass, kernel_type_arguments.raw_array(), |
| 4627 kernel_type_arguments.length()); | 4804 kernel_type_arguments.length()); |
| 4628 if (!klass.IsGeneric()) { | 4805 if (!klass.IsGeneric()) { |
| 4629 Type& type = Type::ZoneHandle(Z, T.ReceiverType(klass).raw()); | 4806 Type& type = Type::ZoneHandle(Z, T.ReceiverType(klass).raw()); |
| 4630 | 4807 |
| 4631 // TODO(27590): Can we move this code into [ReceiverType]? | 4808 // TODO(27590): Can we move this code into [ReceiverType]? |
| 4632 type ^= ClassFinalizer::FinalizeType(*active_class_.klass, type, | 4809 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); | 4994 right_fragment += Goto(join); |
| 4818 constant_fragment += Goto(join); | 4995 constant_fragment += Goto(join); |
| 4819 | 4996 |
| 4820 fragment_ = Fragment(instructions.entry, join) + | 4997 fragment_ = Fragment(instructions.entry, join) + |
| 4821 LoadLocal(parsed_function_->expression_temp_var()); | 4998 LoadLocal(parsed_function_->expression_temp_var()); |
| 4822 } | 4999 } |
| 4823 | 5000 |
| 4824 | 5001 |
| 4825 void FlowGraphBuilder::VisitNot(Not* node) { | 5002 void FlowGraphBuilder::VisitNot(Not* node) { |
| 4826 Fragment instructions = TranslateExpression(node->expression()); | 5003 Fragment instructions = TranslateExpression(node->expression()); |
| 4827 fragment_ = instructions + BooleanNegate(); | 5004 instructions += MaybeCheckBool(); |
| 5005 instructions += BooleanNegate(); | |
| 5006 fragment_ = instructions; | |
| 4828 } | 5007 } |
| 4829 | 5008 |
| 4830 | 5009 |
| 4831 void FlowGraphBuilder::VisitThisExpression(ThisExpression* node) { | 5010 void FlowGraphBuilder::VisitThisExpression(ThisExpression* node) { |
| 4832 fragment_ = LoadLocal(scopes_->this_variable); | 5011 fragment_ = LoadLocal(scopes_->this_variable); |
| 4833 } | 5012 } |
| 4834 | 5013 |
| 4835 | 5014 |
| 4836 void FlowGraphBuilder::VisitStringConcatenation(StringConcatenation* node) { | 5015 void FlowGraphBuilder::VisitStringConcatenation(StringConcatenation* node) { |
| 4837 List<Expression>& expressions = node->expressions(); | 5016 List<Expression>& expressions = node->expressions(); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5071 | 5250 |
| 5072 void FlowGraphBuilder::VisitVariableDeclaration(VariableDeclaration* node) { | 5251 void FlowGraphBuilder::VisitVariableDeclaration(VariableDeclaration* node) { |
| 5073 LocalVariable* variable = LookupVariable(node); | 5252 LocalVariable* variable = LookupVariable(node); |
| 5074 Expression* initializer = node->initializer(); | 5253 Expression* initializer = node->initializer(); |
| 5075 | 5254 |
| 5076 Fragment instructions; | 5255 Fragment instructions; |
| 5077 if (initializer == NULL) { | 5256 if (initializer == NULL) { |
| 5078 instructions += NullConstant(); | 5257 instructions += NullConstant(); |
| 5079 } else { | 5258 } else { |
| 5080 if (node->IsConst()) { | 5259 if (node->IsConst()) { |
| 5260 // FIXME(checked-mode) | |
|
Vyacheslav Egorov (Google)
2017/01/30 18:30:28
Needs to be
// TODO(issue-number) some comment
kustermann
2017/01/31 10:39:45
I'll remove the TODO. The ConstantEvaluator has be
| |
| 5081 const Instance& constant_value = | 5261 const Instance& constant_value = |
| 5082 constant_evaluator_.EvaluateExpression(initializer); | 5262 constant_evaluator_.EvaluateExpression(initializer); |
| 5083 variable->SetConstValue(constant_value); | 5263 variable->SetConstValue(constant_value); |
| 5084 instructions += Constant(constant_value); | 5264 instructions += Constant(constant_value); |
| 5085 } else { | 5265 } else { |
| 5086 instructions += TranslateExpression(initializer); | 5266 instructions += TranslateExpression(initializer); |
| 5267 instructions += MaybeCheckVariableType(node); | |
| 5087 } | 5268 } |
| 5088 } | 5269 } |
| 5089 instructions += StoreLocal(variable->token_pos(), variable); | 5270 instructions += StoreLocal(variable->token_pos(), variable); |
| 5090 instructions += Drop(); | 5271 instructions += Drop(); |
| 5091 fragment_ = instructions; | 5272 fragment_ = instructions; |
| 5092 } | 5273 } |
| 5093 | 5274 |
| 5094 | 5275 |
| 5095 void FlowGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { | 5276 void FlowGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { |
| 5096 Fragment instructions = TranslateFunctionNode(node->function(), node); | 5277 Fragment instructions = TranslateFunctionNode(node->function(), node); |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5541 | 5722 |
| 5542 void FlowGraphBuilder::VisitAssertStatement(AssertStatement* node) { | 5723 void FlowGraphBuilder::VisitAssertStatement(AssertStatement* node) { |
| 5543 if (!I->asserts()) { | 5724 if (!I->asserts()) { |
| 5544 fragment_ = Fragment(); | 5725 fragment_ = Fragment(); |
| 5545 return; | 5726 return; |
| 5546 } | 5727 } |
| 5547 | 5728 |
| 5548 TargetEntryInstr* then; | 5729 TargetEntryInstr* then; |
| 5549 TargetEntryInstr* otherwise; | 5730 TargetEntryInstr* otherwise; |
| 5550 | 5731 |
| 5551 bool negate; | |
| 5552 Fragment instructions; | 5732 Fragment instructions; |
| 5553 instructions += TranslateCondition(node->condition(), &negate); | 5733 // Asserts can be of the following two kinds: |
| 5554 instructions += BranchIfTrue(&then, &otherwise, negate); | 5734 // |
| 5735 // * `assert(expr)` | |
| 5736 // * `assert(() { ... })` | |
| 5737 // | |
| 5738 // The call to `_AssertionError._evaluateAssertion()` will take care of both | |
| 5739 // and returns a boolean. | |
| 5740 instructions += TranslateExpression(node->condition()); | |
| 5741 instructions += PushArgument(); | |
| 5742 instructions += EvaluateAssertion(); | |
| 5743 instructions += MaybeCheckBool(); | |
| 5744 instructions += Constant(Bool::True()); | |
| 5745 instructions += BranchIfEqual(&then, &otherwise, false); | |
| 5555 | 5746 |
| 5556 const dart::Class& klass = dart::Class::ZoneHandle( | 5747 const dart::Class& klass = dart::Class::ZoneHandle( |
| 5557 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); | 5748 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); |
| 5558 ASSERT(!klass.IsNull()); | 5749 ASSERT(!klass.IsNull()); |
| 5559 const dart::Function& constructor = dart::Function::ZoneHandle( | 5750 const dart::Function& constructor = dart::Function::ZoneHandle( |
| 5560 Z, klass.LookupConstructorAllowPrivate( | 5751 Z, klass.LookupConstructorAllowPrivate( |
| 5561 H.DartSymbol("_AssertionError._create"))); | 5752 H.DartSymbol("_AssertionError._create"))); |
| 5562 ASSERT(!constructor.IsNull()); | 5753 ASSERT(!constructor.IsNull()); |
| 5563 | 5754 |
| 5564 const dart::String& url = H.DartString( | 5755 const dart::String& url = H.DartString( |
| 5565 parsed_function_->function().ToLibNamePrefixedQualifiedCString(), | 5756 parsed_function_->function().ToLibNamePrefixedQualifiedCString(), |
| 5566 Heap::kOld); | 5757 Heap::kOld); |
| 5567 | 5758 |
| 5568 // Create instance of _AssertionError | 5759 // Create instance of _AssertionError |
| 5569 Fragment otherwise_fragment(otherwise); | 5760 Fragment otherwise_fragment(otherwise); |
| 5570 otherwise_fragment += AllocateObject(klass, 0); | 5761 otherwise_fragment += AllocateObject(klass, 0); |
| 5571 LocalVariable* instance = MakeTemporary(); | 5762 LocalVariable* instance = MakeTemporary(); |
| 5572 | 5763 |
| 5573 // Call _AssertionError._create constructor. | 5764 // Call _AssertionError._create constructor. |
| 5574 otherwise_fragment += LoadLocal(instance); | 5765 otherwise_fragment += LoadLocal(instance); |
| 5575 otherwise_fragment += PushArgument(); // this | 5766 otherwise_fragment += PushArgument(); // this |
| 5576 | 5767 |
| 5577 otherwise_fragment += | 5768 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 | 5769 otherwise_fragment += PushArgument(); // failedAssertion |
| 5582 | 5770 |
| 5583 otherwise_fragment += Constant(url); | 5771 otherwise_fragment += Constant(url); |
| 5584 otherwise_fragment += PushArgument(); // url | 5772 otherwise_fragment += PushArgument(); // url |
| 5585 | 5773 |
| 5586 otherwise_fragment += IntConstant(0); | 5774 otherwise_fragment += IntConstant(0); |
| 5587 otherwise_fragment += PushArgument(); // line | 5775 otherwise_fragment += PushArgument(); // line |
| 5588 | 5776 |
| 5589 otherwise_fragment += IntConstant(0); | 5777 otherwise_fragment += IntConstant(0); |
| 5590 otherwise_fragment += PushArgument(); // column | 5778 otherwise_fragment += PushArgument(); // column |
| 5591 | 5779 |
| 5592 otherwise_fragment += Constant(H.DartString("<no message>", Heap::kOld)); | 5780 otherwise_fragment += |
| 5781 node->message() != NULL | |
| 5782 ? TranslateExpression(node->message()) | |
| 5783 : Constant(H.DartString("<no message>", Heap::kOld)); | |
| 5593 otherwise_fragment += PushArgument(); // message | 5784 otherwise_fragment += PushArgument(); // message |
| 5594 | 5785 |
| 5595 otherwise_fragment += StaticCall(TokenPosition::kNoSource, constructor, 6); | 5786 otherwise_fragment += StaticCall(TokenPosition::kNoSource, constructor, 6); |
| 5596 otherwise_fragment += Drop(); | 5787 otherwise_fragment += Drop(); |
| 5597 | 5788 |
| 5598 // Throw _AssertionError exception. | 5789 // Throw _AssertionError exception. |
| 5599 otherwise_fragment += PushArgument(); | 5790 otherwise_fragment += PushArgument(); |
| 5600 otherwise_fragment += ThrowException(TokenPosition::kNoSource); | 5791 otherwise_fragment += ThrowException(TokenPosition::kNoSource); |
| 5601 otherwise_fragment += Drop(); | 5792 otherwise_fragment += Drop(); |
| 5602 | 5793 |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6045 thread->clear_sticky_error(); | 6236 thread->clear_sticky_error(); |
| 6046 return error.raw(); | 6237 return error.raw(); |
| 6047 } | 6238 } |
| 6048 } | 6239 } |
| 6049 | 6240 |
| 6050 | 6241 |
| 6051 } // namespace kernel | 6242 } // namespace kernel |
| 6052 } // namespace dart | 6243 } // namespace dart |
| 6053 | 6244 |
| 6054 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6245 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |