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

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

Issue 2659363003: VM: [Kernel] Partial support for checked mode. (Closed)
Patch Set: Renamed Maybe* -> *InCheckedMode 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
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | tests/language/language_kernel.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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)
OLDNEW
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | tests/language/language_kernel.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698