Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(502)

Side by Side Diff: runtime/vm/kernel_to_il.cc

Issue 2659363003: VM: [Kernel] Partial support for checked mode. (Closed)
Patch Set: Revert changes to test Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698