| 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 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1338 if (named->length() == 0) return Array::ZoneHandle(Z); | 1338 if (named->length() == 0) return Array::ZoneHandle(Z); |
| 1339 | 1339 |
| 1340 const Array& names = | 1340 const Array& names = |
| 1341 Array::ZoneHandle(Z, Array::New(named->length(), Heap::kOld)); | 1341 Array::ZoneHandle(Z, Array::New(named->length(), Heap::kOld)); |
| 1342 for (intptr_t i = 0; i < named->length(); ++i) { | 1342 for (intptr_t i = 0; i < named->length(); ++i) { |
| 1343 names.SetAt(i, DartSymbol((*named)[i]->name())); | 1343 names.SetAt(i, DartSymbol((*named)[i]->name())); |
| 1344 } | 1344 } |
| 1345 return names; | 1345 return names; |
| 1346 } | 1346 } |
| 1347 | 1347 |
| 1348 | |
| 1349 ConstantEvaluator::ConstantEvaluator(FlowGraphBuilder* builder, | 1348 ConstantEvaluator::ConstantEvaluator(FlowGraphBuilder* builder, |
| 1350 Zone* zone, | 1349 Zone* zone, |
| 1351 TranslationHelper* h, | 1350 TranslationHelper* h, |
| 1352 DartTypeTranslator* type_translator) | 1351 DartTypeTranslator* type_translator) |
| 1353 : builder_(builder), | 1352 : builder_(builder), |
| 1354 isolate_(Isolate::Current()), | 1353 isolate_(Isolate::Current()), |
| 1355 zone_(zone), | 1354 zone_(zone), |
| 1356 translation_helper_(*h), | 1355 translation_helper_(*h), |
| 1357 type_translator_(*type_translator), | 1356 type_translator_(*type_translator), |
| 1358 script_(Script::Handle( | 1357 script_(Script::Handle( |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2077 return instructions; | 2076 return instructions; |
| 2078 } | 2077 } |
| 2079 | 2078 |
| 2080 | 2079 |
| 2081 Fragment FlowGraphBuilder::PushContext(int size) { | 2080 Fragment FlowGraphBuilder::PushContext(int size) { |
| 2082 ASSERT(size > 0); | 2081 ASSERT(size > 0); |
| 2083 Fragment instructions = AllocateContext(size); | 2082 Fragment instructions = AllocateContext(size); |
| 2084 LocalVariable* context = MakeTemporary(); | 2083 LocalVariable* context = MakeTemporary(); |
| 2085 instructions += LoadLocal(context); | 2084 instructions += LoadLocal(context); |
| 2086 instructions += LoadLocal(parsed_function_->current_context_var()); | 2085 instructions += LoadLocal(parsed_function_->current_context_var()); |
| 2087 instructions += StoreInstanceField(Context::parent_offset()); | 2086 instructions += |
| 2087 StoreInstanceField(TokenPosition::kNoSource, Context::parent_offset()); |
| 2088 instructions += StoreLocal(TokenPosition::kNoSource, | 2088 instructions += StoreLocal(TokenPosition::kNoSource, |
| 2089 parsed_function_->current_context_var()); | 2089 parsed_function_->current_context_var()); |
| 2090 ++context_depth_; | 2090 ++context_depth_; |
| 2091 return instructions; | 2091 return instructions; |
| 2092 } | 2092 } |
| 2093 | 2093 |
| 2094 | 2094 |
| 2095 Fragment FlowGraphBuilder::PopContext() { | 2095 Fragment FlowGraphBuilder::PopContext() { |
| 2096 return AdjustContextTo(context_depth_ - 1); | 2096 return AdjustContextTo(context_depth_ - 1); |
| 2097 } | 2097 } |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2427 // Use it's side effect of leaving a constant on the stack (does not change | 2427 // Use it's side effect of leaving a constant on the stack (does not change |
| 2428 // the graph). | 2428 // the graph). |
| 2429 NullConstant(); | 2429 NullConstant(); |
| 2430 | 2430 |
| 2431 pending_argument_count_ -= 1; | 2431 pending_argument_count_ -= 1; |
| 2432 | 2432 |
| 2433 return instructions; | 2433 return instructions; |
| 2434 } | 2434 } |
| 2435 | 2435 |
| 2436 | 2436 |
| 2437 Fragment FlowGraphBuilder::RethrowException(int catch_try_index) { | 2437 Fragment FlowGraphBuilder::RethrowException(TokenPosition position, |
| 2438 int catch_try_index) { |
| 2438 Fragment instructions; | 2439 Fragment instructions; |
| 2439 instructions += Drop(); | 2440 instructions += Drop(); |
| 2440 instructions += Drop(); | 2441 instructions += Drop(); |
| 2441 instructions += | 2442 instructions += |
| 2442 Fragment(new (Z) ReThrowInstr(TokenPosition::kNoSource, catch_try_index)) | 2443 Fragment(new (Z) ReThrowInstr(position, catch_try_index)).closed(); |
| 2443 .closed(); | |
| 2444 // Use it's side effect of leaving a constant on the stack (does not change | 2444 // Use it's side effect of leaving a constant on the stack (does not change |
| 2445 // the graph). | 2445 // the graph). |
| 2446 NullConstant(); | 2446 NullConstant(); |
| 2447 | 2447 |
| 2448 pending_argument_count_ -= 2; | 2448 pending_argument_count_ -= 2; |
| 2449 | 2449 |
| 2450 return instructions; | 2450 return instructions; |
| 2451 } | 2451 } |
| 2452 | 2452 |
| 2453 | 2453 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2562 | 2562 |
| 2563 Fragment FlowGraphBuilder::Return(TokenPosition position) { | 2563 Fragment FlowGraphBuilder::Return(TokenPosition position) { |
| 2564 Fragment instructions; | 2564 Fragment instructions; |
| 2565 | 2565 |
| 2566 instructions += CheckReturnTypeInCheckedMode(); | 2566 instructions += CheckReturnTypeInCheckedMode(); |
| 2567 | 2567 |
| 2568 Value* value = Pop(); | 2568 Value* value = Pop(); |
| 2569 ASSERT(stack_ == NULL); | 2569 ASSERT(stack_ == NULL); |
| 2570 | 2570 |
| 2571 const Function& function = parsed_function_->function(); | 2571 const Function& function = parsed_function_->function(); |
| 2572 if (FLAG_support_debugger && position.IsDebugPause() && | 2572 if (NeedsDebugStepCheck(function, position)) { |
| 2573 !function.is_native()) { | 2573 instructions += DebugStepCheck(position); |
| 2574 instructions <<= | |
| 2575 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); | |
| 2576 } | 2574 } |
| 2577 | 2575 |
| 2578 if (FLAG_causal_async_stacks && | 2576 if (FLAG_causal_async_stacks && |
| 2579 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { | 2577 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { |
| 2580 // We are returning from an asynchronous closure. Before we do that, be | 2578 // We are returning from an asynchronous closure. Before we do that, be |
| 2581 // sure to clear the thread's asynchronous stack trace. | 2579 // sure to clear the thread's asynchronous stack trace. |
| 2582 const Function& target = Function::ZoneHandle( | 2580 const Function& target = Function::ZoneHandle( |
| 2583 Z, I->object_store()->async_clear_thread_stack_trace()); | 2581 Z, I->object_store()->async_clear_thread_stack_trace()); |
| 2584 ASSERT(!target.IsNull()); | 2582 ASSERT(!target.IsNull()); |
| 2585 instructions += StaticCall(TokenPosition::kNoSource, target, 0); | 2583 instructions += StaticCall(TokenPosition::kNoSource, target, 0); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2694 instructions += GuardFieldClass(field_clone, H.thread()->GetNextDeoptId()); | 2692 instructions += GuardFieldClass(field_clone, H.thread()->GetNextDeoptId()); |
| 2695 instructions += LoadLocal(store_expression); | 2693 instructions += LoadLocal(store_expression); |
| 2696 instructions += GuardFieldLength(field_clone, H.thread()->GetNextDeoptId()); | 2694 instructions += GuardFieldLength(field_clone, H.thread()->GetNextDeoptId()); |
| 2697 } | 2695 } |
| 2698 instructions += StoreInstanceField(field_clone, is_initialization_store); | 2696 instructions += StoreInstanceField(field_clone, is_initialization_store); |
| 2699 return instructions; | 2697 return instructions; |
| 2700 } | 2698 } |
| 2701 | 2699 |
| 2702 | 2700 |
| 2703 Fragment FlowGraphBuilder::StoreInstanceField( | 2701 Fragment FlowGraphBuilder::StoreInstanceField( |
| 2702 TokenPosition position, |
| 2704 intptr_t offset, | 2703 intptr_t offset, |
| 2705 StoreBarrierType emit_store_barrier) { | 2704 StoreBarrierType emit_store_barrier) { |
| 2706 Value* value = Pop(); | 2705 Value* value = Pop(); |
| 2707 if (value->BindsToConstant()) { | 2706 if (value->BindsToConstant()) { |
| 2708 emit_store_barrier = kNoStoreBarrier; | 2707 emit_store_barrier = kNoStoreBarrier; |
| 2709 } | 2708 } |
| 2710 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr( | 2709 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr( |
| 2711 offset, Pop(), value, emit_store_barrier, TokenPosition::kNoSource); | 2710 offset, Pop(), value, emit_store_barrier, position); |
| 2712 return Fragment(store); | 2711 return Fragment(store); |
| 2713 } | 2712 } |
| 2714 | 2713 |
| 2715 | 2714 |
| 2716 Fragment FlowGraphBuilder::StoreLocal(TokenPosition position, | 2715 Fragment FlowGraphBuilder::StoreLocal(TokenPosition position, |
| 2717 LocalVariable* variable) { | 2716 LocalVariable* variable) { |
| 2718 Fragment instructions; | 2717 Fragment instructions; |
| 2719 if (variable->is_captured()) { | 2718 if (variable->is_captured()) { |
| 2720 LocalVariable* value = MakeTemporary(); | 2719 LocalVariable* value = MakeTemporary(); |
| 2721 instructions += LoadContextAt(variable->owner()->context_level()); | 2720 instructions += LoadContextAt(variable->owner()->context_level()); |
| 2722 instructions += LoadLocal(value); | 2721 instructions += LoadLocal(value); |
| 2723 instructions += | 2722 instructions += StoreInstanceField( |
| 2724 StoreInstanceField(Context::variable_offset(variable->index())); | 2723 position, Context::variable_offset(variable->index())); |
| 2725 } else { | 2724 } else { |
| 2726 Value* value = Pop(); | 2725 Value* value = Pop(); |
| 2727 if (FLAG_support_debugger && position.IsDebugPause() && | |
| 2728 !variable->IsInternal()) { | |
| 2729 if (value->definition()->IsConstant() || | |
| 2730 value->definition()->IsAllocateObject() || | |
| 2731 (value->definition()->IsLoadLocal() && | |
| 2732 !value->definition()->AsLoadLocal()->local().IsInternal())) { | |
| 2733 instructions <<= new (Z) | |
| 2734 DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); | |
| 2735 } | |
| 2736 } | |
| 2737 | |
| 2738 StoreLocalInstr* store = | 2726 StoreLocalInstr* store = |
| 2739 new (Z) StoreLocalInstr(*variable, value, position); | 2727 new (Z) StoreLocalInstr(*variable, value, position); |
| 2740 instructions <<= store; | 2728 instructions <<= store; |
| 2741 Push(store); | 2729 Push(store); |
| 2742 } | 2730 } |
| 2743 return instructions; | 2731 return instructions; |
| 2744 } | 2732 } |
| 2745 | 2733 |
| 2746 | 2734 |
| 2747 Fragment FlowGraphBuilder::StoreStaticField(const dart::Field& field) { | 2735 Fragment FlowGraphBuilder::StoreStaticField(TokenPosition position, |
| 2748 return Fragment(new (Z) StoreStaticFieldInstr(MayCloneField(Z, field), Pop(), | 2736 const dart::Field& field) { |
| 2749 TokenPosition::kNoSource)); | 2737 return Fragment( |
| 2738 new (Z) StoreStaticFieldInstr(MayCloneField(Z, field), Pop(), position)); |
| 2750 } | 2739 } |
| 2751 | 2740 |
| 2752 | 2741 |
| 2753 Fragment FlowGraphBuilder::StringInterpolate(TokenPosition position) { | 2742 Fragment FlowGraphBuilder::StringInterpolate(TokenPosition position) { |
| 2754 Value* array = Pop(); | 2743 Value* array = Pop(); |
| 2755 StringInterpolateInstr* interpolate = | 2744 StringInterpolateInstr* interpolate = |
| 2756 new (Z) StringInterpolateInstr(array, position); | 2745 new (Z) StringInterpolateInstr(array, position); |
| 2757 Push(interpolate); | 2746 Push(interpolate); |
| 2758 return Fragment(interpolate); | 2747 return Fragment(interpolate); |
| 2759 } | 2748 } |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3110 parameter->set_index(parameter_index); | 3099 parameter->set_index(parameter_index); |
| 3111 // Mark the stack variable so it will be ignored by the code for | 3100 // Mark the stack variable so it will be ignored by the code for |
| 3112 // try/catch. | 3101 // try/catch. |
| 3113 parameter->set_is_captured_parameter(true); | 3102 parameter->set_is_captured_parameter(true); |
| 3114 | 3103 |
| 3115 // Copy the parameter from the stack to the context. Overwrite it | 3104 // Copy the parameter from the stack to the context. Overwrite it |
| 3116 // with a null constant on the stack so the original value is | 3105 // with a null constant on the stack so the original value is |
| 3117 // eligible for garbage collection. | 3106 // eligible for garbage collection. |
| 3118 body += LoadLocal(context); | 3107 body += LoadLocal(context); |
| 3119 body += LoadLocal(parameter); | 3108 body += LoadLocal(parameter); |
| 3120 body += StoreInstanceField(Context::variable_offset(variable->index())); | 3109 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3110 Context::variable_offset(variable->index())); |
| 3121 body += NullConstant(); | 3111 body += NullConstant(); |
| 3122 body += StoreLocal(TokenPosition::kNoSource, parameter); | 3112 body += StoreLocal(TokenPosition::kNoSource, parameter); |
| 3123 body += Drop(); | 3113 body += Drop(); |
| 3124 } | 3114 } |
| 3125 } | 3115 } |
| 3126 body += Drop(); // The context. | 3116 body += Drop(); // The context. |
| 3127 } | 3117 } |
| 3128 if (constructor != NULL) { | 3118 if (constructor != NULL) { |
| 3129 // TODO(27590): Currently the [VariableDeclaration]s from the | 3119 // TODO(27590): Currently the [VariableDeclaration]s from the |
| 3130 // initializers will be visible inside the entire body of the constructor. | 3120 // initializers will be visible inside the entire body of the constructor. |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3270 TargetEntryInstr* otherwise; | 3260 TargetEntryInstr* otherwise; |
| 3271 dispatch += LoadLocal(scopes_->switch_variable); | 3261 dispatch += LoadLocal(scopes_->switch_variable); |
| 3272 dispatch += IntConstant(i); | 3262 dispatch += IntConstant(i); |
| 3273 dispatch += BranchIfStrictEqual(&then, &otherwise); | 3263 dispatch += BranchIfStrictEqual(&then, &otherwise); |
| 3274 | 3264 |
| 3275 // True branch is linked to appropriate continuation point. | 3265 // True branch is linked to appropriate continuation point. |
| 3276 // Note: continuations start with nop DropTemps instruction | 3266 // Note: continuations start with nop DropTemps instruction |
| 3277 // which acts like an anchor, so we need to skip it. | 3267 // which acts like an anchor, so we need to skip it. |
| 3278 then->LinkTo(yield_continuations_[i].entry->next()); | 3268 then->LinkTo(yield_continuations_[i].entry->next()); |
| 3279 then->set_try_index(yield_continuations_[i].try_index); | 3269 then->set_try_index(yield_continuations_[i].try_index); |
| 3280 | |
| 3281 // False branch will contain the next comparison. | 3270 // False branch will contain the next comparison. |
| 3282 dispatch = Fragment(dispatch.entry, otherwise); | 3271 dispatch = Fragment(dispatch.entry, otherwise); |
| 3283 block = otherwise; | 3272 block = otherwise; |
| 3284 } | 3273 } |
| 3285 body = dispatch; | 3274 body = dispatch; |
| 3286 | 3275 |
| 3287 context_depth_ = current_context_depth; | 3276 context_depth_ = current_context_depth; |
| 3288 } | 3277 } |
| 3289 | 3278 |
| 3290 if (FLAG_causal_async_stacks && | 3279 if (FLAG_causal_async_stacks && |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3311 instructions += PushArgument(); | 3300 instructions += PushArgument(); |
| 3312 | 3301 |
| 3313 // Call _asyncSetThreadStackTrace | 3302 // Call _asyncSetThreadStackTrace |
| 3314 instructions += StaticCall(TokenPosition::kNoSource, target, 1); | 3303 instructions += StaticCall(TokenPosition::kNoSource, target, 1); |
| 3315 instructions += Drop(); | 3304 instructions += Drop(); |
| 3316 | 3305 |
| 3317 body = instructions + body; | 3306 body = instructions + body; |
| 3318 context_depth_ = current_context_depth; | 3307 context_depth_ = current_context_depth; |
| 3319 } | 3308 } |
| 3320 | 3309 |
| 3321 if (FLAG_support_debugger && function->position().IsDebugPause() && | 3310 if (NeedsDebugStepCheck(dart_function, function->position())) { |
| 3322 !dart_function.is_native() && dart_function.is_debuggable()) { | |
| 3323 // If a switch was added above: Start the switch by injecting a debugable | 3311 // If a switch was added above: Start the switch by injecting a debugable |
| 3324 // safepoint so stepping over an await works. | 3312 // safepoint so stepping over an await works. |
| 3325 // If not, still start the body with a debugable safepoint to ensure | 3313 // If not, still start the body with a debugable safepoint to ensure |
| 3326 // breaking on a method always happens, even if there are no | 3314 // breaking on a method always happens, even if there are no |
| 3327 // assignments/calls/runtimecalls in the first basic block. | 3315 // assignments/calls/runtimecalls in the first basic block. |
| 3328 // Place this check at the last parameter to ensure parameters | 3316 // Place this check at the last parameter to ensure parameters |
| 3329 // are in scope in the debugger at method entry. | 3317 // are in scope in the debugger at method entry. |
| 3330 const int num_params = dart_function.NumParameters(); | 3318 const int num_params = dart_function.NumParameters(); |
| 3331 TokenPosition check_pos = TokenPosition::kNoSource; | 3319 TokenPosition check_pos = TokenPosition::kNoSource; |
| 3332 if (num_params > 0) { | 3320 if (num_params > 0) { |
| 3333 LocalScope* scope = parsed_function_->node_sequence()->scope(); | 3321 LocalScope* scope = parsed_function_->node_sequence()->scope(); |
| 3334 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); | 3322 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); |
| 3335 check_pos = parameter.token_pos(); | 3323 check_pos = parameter.token_pos(); |
| 3336 } | 3324 } |
| 3337 if (!check_pos.IsDebugPause()) { | 3325 if (!check_pos.IsDebugPause()) { |
| 3338 // No parameters or synthetic parameters. | 3326 // No parameters or synthetic parameters. |
| 3339 check_pos = function->position(); | 3327 check_pos = function->position(); |
| 3340 ASSERT(check_pos.IsDebugPause()); | 3328 ASSERT(check_pos.IsDebugPause()); |
| 3341 } | 3329 } |
| 3342 Fragment check( | 3330 body = DebugStepCheck(check_pos) + body; |
| 3343 new (Z) DebugStepCheckInstr(check_pos, RawPcDescriptors::kRuntimeCall)); | |
| 3344 body = check + body; | |
| 3345 } | 3331 } |
| 3346 | 3332 |
| 3347 normal_entry->LinkTo(body.entry); | 3333 normal_entry->LinkTo(body.entry); |
| 3348 | 3334 |
| 3349 // When compiling for OSR, use a depth first search to prune instructions | 3335 // When compiling for OSR, use a depth first search to prune instructions |
| 3350 // unreachable from the OSR entry. Catch entries are always considered | 3336 // unreachable from the OSR entry. Catch entries are always considered |
| 3351 // reachable, even if they become unreachable after OSR. | 3337 // reachable, even if they become unreachable after OSR. |
| 3352 if (osr_id_ != Compiler::kNoOSRDeoptId) { | 3338 if (osr_id_ != Compiler::kNoOSRDeoptId) { |
| 3353 BitVector* block_marks = new (Z) BitVector(Z, next_block_id_); | 3339 BitVector* block_marks = new (Z) BitVector(Z, next_block_id_); |
| 3354 bool found = graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, | 3340 bool found = graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3439 break; | 3425 break; |
| 3440 case MethodRecognizer::kLinkedHashMap_getIndex: | 3426 case MethodRecognizer::kLinkedHashMap_getIndex: |
| 3441 body += LoadLocal(scopes_->this_variable); | 3427 body += LoadLocal(scopes_->this_variable); |
| 3442 body += LoadNativeField(kind, LinkedHashMap::index_offset(), | 3428 body += LoadNativeField(kind, LinkedHashMap::index_offset(), |
| 3443 Object::dynamic_type(), kDynamicCid); | 3429 Object::dynamic_type(), kDynamicCid); |
| 3444 break; | 3430 break; |
| 3445 case MethodRecognizer::kLinkedHashMap_setIndex: | 3431 case MethodRecognizer::kLinkedHashMap_setIndex: |
| 3446 body += LoadLocal(scopes_->this_variable); | 3432 body += LoadLocal(scopes_->this_variable); |
| 3447 body += LoadLocal( | 3433 body += LoadLocal( |
| 3448 LookupVariable(kernel_function->positional_parameters()[0])); | 3434 LookupVariable(kernel_function->positional_parameters()[0])); |
| 3449 body += StoreInstanceField(LinkedHashMap::index_offset()); | 3435 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3436 LinkedHashMap::index_offset()); |
| 3450 body += NullConstant(); | 3437 body += NullConstant(); |
| 3451 break; | 3438 break; |
| 3452 case MethodRecognizer::kLinkedHashMap_getData: | 3439 case MethodRecognizer::kLinkedHashMap_getData: |
| 3453 body += LoadLocal(scopes_->this_variable); | 3440 body += LoadLocal(scopes_->this_variable); |
| 3454 body += LoadNativeField(kind, LinkedHashMap::data_offset(), | 3441 body += LoadNativeField(kind, LinkedHashMap::data_offset(), |
| 3455 Object::dynamic_type(), kArrayCid); | 3442 Object::dynamic_type(), kArrayCid); |
| 3456 break; | 3443 break; |
| 3457 case MethodRecognizer::kLinkedHashMap_setData: | 3444 case MethodRecognizer::kLinkedHashMap_setData: |
| 3458 body += LoadLocal(scopes_->this_variable); | 3445 body += LoadLocal(scopes_->this_variable); |
| 3459 body += LoadLocal( | 3446 body += LoadLocal( |
| 3460 LookupVariable(kernel_function->positional_parameters()[0])); | 3447 LookupVariable(kernel_function->positional_parameters()[0])); |
| 3461 body += StoreInstanceField(LinkedHashMap::data_offset()); | 3448 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3449 LinkedHashMap::data_offset()); |
| 3462 body += NullConstant(); | 3450 body += NullConstant(); |
| 3463 break; | 3451 break; |
| 3464 case MethodRecognizer::kLinkedHashMap_getHashMask: | 3452 case MethodRecognizer::kLinkedHashMap_getHashMask: |
| 3465 body += LoadLocal(scopes_->this_variable); | 3453 body += LoadLocal(scopes_->this_variable); |
| 3466 body += LoadNativeField(kind, LinkedHashMap::hash_mask_offset(), | 3454 body += LoadNativeField(kind, LinkedHashMap::hash_mask_offset(), |
| 3467 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); | 3455 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); |
| 3468 break; | 3456 break; |
| 3469 case MethodRecognizer::kLinkedHashMap_setHashMask: | 3457 case MethodRecognizer::kLinkedHashMap_setHashMask: |
| 3470 body += LoadLocal(scopes_->this_variable); | 3458 body += LoadLocal(scopes_->this_variable); |
| 3471 body += LoadLocal( | 3459 body += LoadLocal( |
| 3472 LookupVariable(kernel_function->positional_parameters()[0])); | 3460 LookupVariable(kernel_function->positional_parameters()[0])); |
| 3473 body += StoreInstanceField(LinkedHashMap::hash_mask_offset(), | 3461 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3462 LinkedHashMap::hash_mask_offset(), |
| 3474 kNoStoreBarrier); | 3463 kNoStoreBarrier); |
| 3475 body += NullConstant(); | 3464 body += NullConstant(); |
| 3476 break; | 3465 break; |
| 3477 case MethodRecognizer::kLinkedHashMap_getUsedData: | 3466 case MethodRecognizer::kLinkedHashMap_getUsedData: |
| 3478 body += LoadLocal(scopes_->this_variable); | 3467 body += LoadLocal(scopes_->this_variable); |
| 3479 body += LoadNativeField(kind, LinkedHashMap::used_data_offset(), | 3468 body += LoadNativeField(kind, LinkedHashMap::used_data_offset(), |
| 3480 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); | 3469 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); |
| 3481 break; | 3470 break; |
| 3482 case MethodRecognizer::kLinkedHashMap_setUsedData: | 3471 case MethodRecognizer::kLinkedHashMap_setUsedData: |
| 3483 body += LoadLocal(scopes_->this_variable); | 3472 body += LoadLocal(scopes_->this_variable); |
| 3484 body += LoadLocal( | 3473 body += LoadLocal( |
| 3485 LookupVariable(kernel_function->positional_parameters()[0])); | 3474 LookupVariable(kernel_function->positional_parameters()[0])); |
| 3486 body += StoreInstanceField(LinkedHashMap::used_data_offset(), | 3475 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3476 LinkedHashMap::used_data_offset(), |
| 3487 kNoStoreBarrier); | 3477 kNoStoreBarrier); |
| 3488 body += NullConstant(); | 3478 body += NullConstant(); |
| 3489 break; | 3479 break; |
| 3490 case MethodRecognizer::kLinkedHashMap_getDeletedKeys: | 3480 case MethodRecognizer::kLinkedHashMap_getDeletedKeys: |
| 3491 body += LoadLocal(scopes_->this_variable); | 3481 body += LoadLocal(scopes_->this_variable); |
| 3492 body += LoadNativeField(kind, LinkedHashMap::deleted_keys_offset(), | 3482 body += LoadNativeField(kind, LinkedHashMap::deleted_keys_offset(), |
| 3493 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); | 3483 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); |
| 3494 break; | 3484 break; |
| 3495 case MethodRecognizer::kLinkedHashMap_setDeletedKeys: | 3485 case MethodRecognizer::kLinkedHashMap_setDeletedKeys: |
| 3496 body += LoadLocal(scopes_->this_variable); | 3486 body += LoadLocal(scopes_->this_variable); |
| 3497 body += LoadLocal( | 3487 body += LoadLocal( |
| 3498 LookupVariable(kernel_function->positional_parameters()[0])); | 3488 LookupVariable(kernel_function->positional_parameters()[0])); |
| 3499 body += StoreInstanceField(LinkedHashMap::deleted_keys_offset(), | 3489 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3490 LinkedHashMap::deleted_keys_offset(), |
| 3500 kNoStoreBarrier); | 3491 kNoStoreBarrier); |
| 3501 body += NullConstant(); | 3492 body += NullConstant(); |
| 3502 break; | 3493 break; |
| 3503 case MethodRecognizer::kBigint_getNeg: | 3494 case MethodRecognizer::kBigint_getNeg: |
| 3504 body += LoadLocal(scopes_->this_variable); | 3495 body += LoadLocal(scopes_->this_variable); |
| 3505 body += LoadNativeField(kind, Bigint::neg_offset(), | 3496 body += LoadNativeField(kind, Bigint::neg_offset(), |
| 3506 Type::ZoneHandle(Z, Type::BoolType()), kBoolCid); | 3497 Type::ZoneHandle(Z, Type::BoolType()), kBoolCid); |
| 3507 break; | 3498 break; |
| 3508 default: { | 3499 default: { |
| 3509 dart::String& name = dart::String::ZoneHandle(Z, function.native_name()); | 3500 dart::String& name = dart::String::ZoneHandle(Z, function.native_name()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3530 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); | 3521 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); |
| 3531 | 3522 |
| 3532 Fragment body(normal_entry); | 3523 Fragment body(normal_entry); |
| 3533 if (is_setter) { | 3524 if (is_setter) { |
| 3534 if (is_method) { | 3525 if (is_method) { |
| 3535 body += LoadLocal(scopes_->this_variable); | 3526 body += LoadLocal(scopes_->this_variable); |
| 3536 body += LoadLocal(setter_value); | 3527 body += LoadLocal(setter_value); |
| 3537 body += StoreInstanceFieldGuarded(field, false); | 3528 body += StoreInstanceFieldGuarded(field, false); |
| 3538 } else { | 3529 } else { |
| 3539 body += LoadLocal(setter_value); | 3530 body += LoadLocal(setter_value); |
| 3540 body += StoreStaticField(field); | 3531 body += StoreStaticField(TokenPosition::kNoSource, field); |
| 3541 } | 3532 } |
| 3542 body += NullConstant(); | 3533 body += NullConstant(); |
| 3543 } else if (is_method) { | 3534 } else if (is_method) { |
| 3544 body += LoadLocal(scopes_->this_variable); | 3535 body += LoadLocal(scopes_->this_variable); |
| 3545 body += LoadField(field); | 3536 body += LoadField(field); |
| 3546 } else if (field.is_const()) { | 3537 } else if (field.is_const()) { |
| 3547 // If the parser needs to know the value of an uninitialized constant field | 3538 // If the parser needs to know the value of an uninitialized constant field |
| 3548 // it will set the value to the transition sentinel (used to detect circular | 3539 // it will set the value to the transition sentinel (used to detect circular |
| 3549 // initialization) and then call the implicit getter. Thus, the getter | 3540 // initialization) and then call the implicit getter. Thus, the getter |
| 3550 // cannot contain the InitStaticField instruction that normal static getters | 3541 // cannot contain the InitStaticField instruction that normal static getters |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3599 fragment += AllocateObject(closure_class, target); | 3590 fragment += AllocateObject(closure_class, target); |
| 3600 LocalVariable* closure = MakeTemporary(); | 3591 LocalVariable* closure = MakeTemporary(); |
| 3601 | 3592 |
| 3602 // Allocate a context that closes over `this`. | 3593 // Allocate a context that closes over `this`. |
| 3603 fragment += AllocateContext(1); | 3594 fragment += AllocateContext(1); |
| 3604 LocalVariable* context = MakeTemporary(); | 3595 LocalVariable* context = MakeTemporary(); |
| 3605 | 3596 |
| 3606 // Store the function and the context in the closure. | 3597 // Store the function and the context in the closure. |
| 3607 fragment += LoadLocal(closure); | 3598 fragment += LoadLocal(closure); |
| 3608 fragment += Constant(target); | 3599 fragment += Constant(target); |
| 3609 fragment += StoreInstanceField(Closure::function_offset()); | 3600 fragment += |
| 3601 StoreInstanceField(TokenPosition::kNoSource, Closure::function_offset()); |
| 3610 | 3602 |
| 3611 fragment += LoadLocal(closure); | 3603 fragment += LoadLocal(closure); |
| 3612 fragment += LoadLocal(context); | 3604 fragment += LoadLocal(context); |
| 3613 fragment += StoreInstanceField(Closure::context_offset()); | 3605 fragment += |
| 3606 StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset()); |
| 3614 | 3607 |
| 3615 // The context is on top of the operand stack. Store `this`. The context | 3608 // The context is on top of the operand stack. Store `this`. The context |
| 3616 // doesn't need a parent pointer because it doesn't close over anything | 3609 // doesn't need a parent pointer because it doesn't close over anything |
| 3617 // else. | 3610 // else. |
| 3618 fragment += LoadLocal(scopes_->this_variable); | 3611 fragment += LoadLocal(scopes_->this_variable); |
| 3619 fragment += StoreInstanceField(Context::variable_offset(0)); | 3612 fragment += |
| 3613 StoreInstanceField(TokenPosition::kNoSource, Context::variable_offset(0)); |
| 3620 | 3614 |
| 3621 return fragment; | 3615 return fragment; |
| 3622 } | 3616 } |
| 3623 | 3617 |
| 3624 | 3618 |
| 3625 Fragment FlowGraphBuilder::GuardFieldLength(const dart::Field& field, | 3619 Fragment FlowGraphBuilder::GuardFieldLength(const dart::Field& field, |
| 3626 intptr_t deopt_id) { | 3620 intptr_t deopt_id) { |
| 3627 return Fragment(new (Z) GuardFieldLengthInstr(Pop(), field, deopt_id)); | 3621 return Fragment(new (Z) GuardFieldLengthInstr(Pop(), field, deopt_id)); |
| 3628 } | 3622 } |
| 3629 | 3623 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3641 if (dst_type.IsMalformed()) { | 3635 if (dst_type.IsMalformed()) { |
| 3642 return ThrowTypeError(); | 3636 return ThrowTypeError(); |
| 3643 } | 3637 } |
| 3644 return CheckAssignableInCheckedMode(dst_type, | 3638 return CheckAssignableInCheckedMode(dst_type, |
| 3645 H.DartSymbol(variable->name())); | 3639 H.DartSymbol(variable->name())); |
| 3646 } | 3640 } |
| 3647 return Fragment(); | 3641 return Fragment(); |
| 3648 } | 3642 } |
| 3649 | 3643 |
| 3650 | 3644 |
| 3645 bool FlowGraphBuilder::NeedsDebugStepCheck(const Function& function, |
| 3646 TokenPosition position) { |
| 3647 return FLAG_support_debugger && position.IsDebugPause() && |
| 3648 !function.is_native() && function.is_debuggable(); |
| 3649 } |
| 3650 |
| 3651 |
| 3652 bool FlowGraphBuilder::NeedsDebugStepCheck(Value* value, |
| 3653 TokenPosition position) { |
| 3654 if (!FLAG_support_debugger || !position.IsDebugPause()) return false; |
| 3655 Definition* definition = value->definition(); |
| 3656 if (definition->IsConstant() || definition->IsLoadStaticField()) return true; |
| 3657 if (definition->IsAllocateObject()) { |
| 3658 return !definition->AsAllocateObject()->closure_function().IsNull(); |
| 3659 } |
| 3660 return definition->IsLoadLocal() && |
| 3661 !definition->AsLoadLocal()->local().IsInternal(); |
| 3662 } |
| 3663 |
| 3664 Fragment FlowGraphBuilder::DebugStepCheck(TokenPosition position) { |
| 3665 return Fragment( |
| 3666 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall)); |
| 3667 } |
| 3668 |
| 3669 |
| 3651 Fragment FlowGraphBuilder::EvaluateAssertion() { | 3670 Fragment FlowGraphBuilder::EvaluateAssertion() { |
| 3652 const dart::Class& klass = dart::Class::ZoneHandle( | 3671 const dart::Class& klass = dart::Class::ZoneHandle( |
| 3653 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); | 3672 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); |
| 3654 ASSERT(!klass.IsNull()); | 3673 ASSERT(!klass.IsNull()); |
| 3655 const dart::Function& target = | 3674 const dart::Function& target = |
| 3656 dart::Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate( | 3675 dart::Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate( |
| 3657 H.DartSymbol("_evaluateAssertion"))); | 3676 H.DartSymbol("_evaluateAssertion"))); |
| 3658 ASSERT(!target.IsNull()); | 3677 ASSERT(!target.IsNull()); |
| 3659 return StaticCall(TokenPosition::kNoSource, target, 1); | 3678 return StaticCall(TokenPosition::kNoSource, target, 1); |
| 3660 } | 3679 } |
| (...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4557 } | 4576 } |
| 4558 | 4577 |
| 4559 | 4578 |
| 4560 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { | 4579 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { |
| 4561 fragment_ = LoadLocal(LookupVariable(node->variable())); | 4580 fragment_ = LoadLocal(LookupVariable(node->variable())); |
| 4562 } | 4581 } |
| 4563 | 4582 |
| 4564 | 4583 |
| 4565 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { | 4584 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { |
| 4566 Fragment instructions = TranslateExpression(node->expression()); | 4585 Fragment instructions = TranslateExpression(node->expression()); |
| 4586 if (NeedsDebugStepCheck(stack_, node->position())) { |
| 4587 instructions = DebugStepCheck(node->position()) + instructions; |
| 4588 } |
| 4567 instructions += CheckVariableTypeInCheckedMode(node->variable()); | 4589 instructions += CheckVariableTypeInCheckedMode(node->variable()); |
| 4568 instructions += | 4590 instructions += |
| 4569 StoreLocal(node->position(), LookupVariable(node->variable())); | 4591 StoreLocal(node->position(), LookupVariable(node->variable())); |
| 4570 fragment_ = instructions; | 4592 fragment_ = instructions; |
| 4571 } | 4593 } |
| 4572 | 4594 |
| 4573 | 4595 |
| 4574 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { | 4596 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { |
| 4575 Member* target = node->target(); | 4597 Member* target = node->target(); |
| 4576 if (target->IsField()) { | 4598 if (target->IsField()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4609 | 4631 |
| 4610 | 4632 |
| 4611 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { | 4633 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { |
| 4612 Member* target = node->target(); | 4634 Member* target = node->target(); |
| 4613 if (target->IsField()) { | 4635 if (target->IsField()) { |
| 4614 Field* kernel_field = Field::Cast(target); | 4636 Field* kernel_field = Field::Cast(target); |
| 4615 const dart::Field& field = | 4637 const dart::Field& field = |
| 4616 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); | 4638 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); |
| 4617 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); | 4639 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); |
| 4618 Fragment instructions = TranslateExpression(node->expression()); | 4640 Fragment instructions = TranslateExpression(node->expression()); |
| 4641 if (NeedsDebugStepCheck(stack_, node->position())) { |
| 4642 instructions = DebugStepCheck(node->position()) + instructions; |
| 4643 } |
| 4619 instructions += CheckAssignableInCheckedMode( | 4644 instructions += CheckAssignableInCheckedMode( |
| 4620 dst_type, dart::String::ZoneHandle(Z, field.name())); | 4645 dst_type, dart::String::ZoneHandle(Z, field.name())); |
| 4621 LocalVariable* variable = MakeTemporary(); | 4646 LocalVariable* variable = MakeTemporary(); |
| 4622 instructions += LoadLocal(variable); | 4647 instructions += LoadLocal(variable); |
| 4623 fragment_ = instructions + StoreStaticField(field); | 4648 fragment_ = instructions + StoreStaticField(node->position(), field); |
| 4624 } else { | 4649 } else { |
| 4625 ASSERT(target->IsProcedure()); | 4650 ASSERT(target->IsProcedure()); |
| 4626 | 4651 |
| 4627 // Evaluate the expression on the right hand side. | 4652 // Evaluate the expression on the right hand side. |
| 4628 Fragment instructions = TranslateExpression(node->expression()); | 4653 Fragment instructions = TranslateExpression(node->expression()); |
| 4629 LocalVariable* variable = MakeTemporary(); | 4654 LocalVariable* variable = MakeTemporary(); |
| 4630 | 4655 |
| 4631 // Prepare argument. | 4656 // Prepare argument. |
| 4632 instructions += LoadLocal(variable); | 4657 instructions += LoadLocal(variable); |
| 4633 instructions += PushArgument(); | 4658 instructions += PushArgument(); |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5039 instructions += LoadInstantiatorTypeArguments(); | 5064 instructions += LoadInstantiatorTypeArguments(); |
| 5040 } else { | 5065 } else { |
| 5041 instructions += NullConstant(); | 5066 instructions += NullConstant(); |
| 5042 } | 5067 } |
| 5043 instructions += PushArgument(); // Type arguments. | 5068 instructions += PushArgument(); // Type arguments. |
| 5044 | 5069 |
| 5045 instructions += Constant(type); | 5070 instructions += Constant(type); |
| 5046 instructions += PushArgument(); // Type. | 5071 instructions += PushArgument(); // Type. |
| 5047 | 5072 |
| 5048 instructions += InstanceCall( | 5073 instructions += InstanceCall( |
| 5049 TokenPosition::kNoSource, | 5074 node->position(), dart::Library::PrivateCoreLibName(Symbols::_as()), |
| 5050 dart::Library::PrivateCoreLibName(Symbols::_as()), Token::kAS, 3); | 5075 Token::kAS, 3); |
| 5051 } | 5076 } |
| 5052 | 5077 |
| 5053 fragment_ = instructions; | 5078 fragment_ = instructions; |
| 5054 } | 5079 } |
| 5055 | 5080 |
| 5056 | 5081 |
| 5057 void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) { | 5082 void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) { |
| 5058 bool negate; | 5083 bool negate; |
| 5059 Fragment instructions = TranslateCondition(node->condition(), &negate); | 5084 Fragment instructions = TranslateCondition(node->condition(), &negate); |
| 5060 | 5085 |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5264 Fragment instructions = TranslateStatement(node->variable()); | 5289 Fragment instructions = TranslateStatement(node->variable()); |
| 5265 instructions += TranslateExpression(node->body()); | 5290 instructions += TranslateExpression(node->body()); |
| 5266 fragment_ = instructions; | 5291 fragment_ = instructions; |
| 5267 } | 5292 } |
| 5268 | 5293 |
| 5269 | 5294 |
| 5270 void FlowGraphBuilder::VisitThrow(Throw* node) { | 5295 void FlowGraphBuilder::VisitThrow(Throw* node) { |
| 5271 Fragment instructions; | 5296 Fragment instructions; |
| 5272 | 5297 |
| 5273 instructions += TranslateExpression(node->expression()); | 5298 instructions += TranslateExpression(node->expression()); |
| 5299 if (NeedsDebugStepCheck(stack_, node->position())) { |
| 5300 instructions = DebugStepCheck(node->position()) + instructions; |
| 5301 } |
| 5274 instructions += PushArgument(); | 5302 instructions += PushArgument(); |
| 5275 instructions += ThrowException(node->position()); | 5303 instructions += ThrowException(node->position()); |
| 5276 ASSERT(instructions.is_closed()); | 5304 ASSERT(instructions.is_closed()); |
| 5277 | 5305 |
| 5278 fragment_ = instructions; | 5306 fragment_ = instructions; |
| 5279 } | 5307 } |
| 5280 | 5308 |
| 5281 | 5309 |
| 5282 void FlowGraphBuilder::VisitRethrow(Rethrow* node) { | 5310 void FlowGraphBuilder::VisitRethrow(Rethrow* node) { |
| 5283 Fragment instructions; | 5311 Fragment instructions; |
| 5284 | 5312 |
| 5313 instructions = DebugStepCheck(node->position()) + instructions; |
| 5285 instructions += LoadLocal(catch_block_->exception_var()); | 5314 instructions += LoadLocal(catch_block_->exception_var()); |
| 5286 instructions += PushArgument(); | 5315 instructions += PushArgument(); |
| 5287 instructions += LoadLocal(catch_block_->stack_trace_var()); | 5316 instructions += LoadLocal(catch_block_->stack_trace_var()); |
| 5288 instructions += PushArgument(); | 5317 instructions += PushArgument(); |
| 5289 instructions += RethrowException(catch_block_->catch_try_index()); | 5318 instructions += |
| 5319 RethrowException(node->position(), catch_block_->catch_try_index()); |
| 5290 | 5320 |
| 5291 fragment_ = instructions; | 5321 fragment_ = instructions; |
| 5292 } | 5322 } |
| 5293 | 5323 |
| 5294 | 5324 |
| 5295 Fragment FlowGraphBuilder::TranslateArguments(Arguments* node, | 5325 Fragment FlowGraphBuilder::TranslateArguments(Arguments* node, |
| 5296 Array* argument_names) { | 5326 Array* argument_names) { |
| 5297 Fragment instructions; | 5327 Fragment instructions; |
| 5298 | 5328 |
| 5299 List<Expression>& positional = node->positional(); | 5329 List<Expression>& positional = node->positional(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5342 | 5372 |
| 5343 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { | 5373 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { |
| 5344 bool inside_try_finally = try_finally_block_ != NULL; | 5374 bool inside_try_finally = try_finally_block_ != NULL; |
| 5345 | 5375 |
| 5346 Fragment instructions = node->expression() == NULL | 5376 Fragment instructions = node->expression() == NULL |
| 5347 ? NullConstant() | 5377 ? NullConstant() |
| 5348 : TranslateExpression(node->expression()); | 5378 : TranslateExpression(node->expression()); |
| 5349 if (instructions.is_open()) { | 5379 if (instructions.is_open()) { |
| 5350 if (inside_try_finally) { | 5380 if (inside_try_finally) { |
| 5351 ASSERT(scopes_->finally_return_variable != NULL); | 5381 ASSERT(scopes_->finally_return_variable != NULL); |
| 5352 instructions += StoreLocal(TokenPosition::kNoSource, | 5382 const Function& function = parsed_function_->function(); |
| 5353 scopes_->finally_return_variable); | 5383 if (NeedsDebugStepCheck(function, node->position())) { |
| 5384 instructions += DebugStepCheck(node->position()); |
| 5385 } |
| 5386 instructions += |
| 5387 StoreLocal(node->position(), scopes_->finally_return_variable); |
| 5354 instructions += Drop(); | 5388 instructions += Drop(); |
| 5355 instructions += TranslateFinallyFinalizers(NULL, -1); | 5389 instructions += TranslateFinallyFinalizers(NULL, -1); |
| 5356 if (instructions.is_open()) { | 5390 if (instructions.is_open()) { |
| 5357 instructions += LoadLocal(scopes_->finally_return_variable); | 5391 instructions += LoadLocal(scopes_->finally_return_variable); |
| 5358 instructions += Return(node->position()); | 5392 instructions += Return(TokenPosition::kNoSource); |
| 5359 } | 5393 } |
| 5360 } else { | 5394 } else { |
| 5361 instructions += Return(node->position()); | 5395 instructions += Return(node->position()); |
| 5362 } | 5396 } |
| 5363 } else { | 5397 } else { |
| 5364 Pop(); | 5398 Pop(); |
| 5365 } | 5399 } |
| 5366 fragment_ = instructions; | 5400 fragment_ = instructions; |
| 5367 } | 5401 } |
| 5368 | 5402 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 5385 if (node->IsConst()) { | 5419 if (node->IsConst()) { |
| 5386 const Instance& constant_value = | 5420 const Instance& constant_value = |
| 5387 constant_evaluator_.EvaluateExpression(initializer); | 5421 constant_evaluator_.EvaluateExpression(initializer); |
| 5388 variable->SetConstValue(constant_value); | 5422 variable->SetConstValue(constant_value); |
| 5389 instructions += Constant(constant_value); | 5423 instructions += Constant(constant_value); |
| 5390 } else { | 5424 } else { |
| 5391 instructions += TranslateExpression(initializer); | 5425 instructions += TranslateExpression(initializer); |
| 5392 instructions += CheckVariableTypeInCheckedMode(node); | 5426 instructions += CheckVariableTypeInCheckedMode(node); |
| 5393 } | 5427 } |
| 5394 } | 5428 } |
| 5395 instructions += StoreLocal(variable->token_pos(), variable); | 5429 // Use position of equal sign if it exists. If the equal sign does not exist |
| 5430 // use the position of the identifier. |
| 5431 TokenPosition debug_position = |
| 5432 Utils::Maximum(node->position(), node->equals_position()); |
| 5433 if (NeedsDebugStepCheck(stack_, debug_position)) { |
| 5434 instructions = DebugStepCheck(debug_position) + instructions; |
| 5435 } |
| 5436 instructions += StoreLocal(node->position(), variable); |
| 5396 instructions += Drop(); | 5437 instructions += Drop(); |
| 5397 fragment_ = instructions; | 5438 fragment_ = instructions; |
| 5398 } | 5439 } |
| 5399 | 5440 |
| 5400 | 5441 |
| 5401 void FlowGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { | 5442 void FlowGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { |
| 5402 Fragment instructions = TranslateFunctionNode(node->function(), node); | 5443 Fragment instructions = DebugStepCheck(node->position()); |
| 5444 instructions += TranslateFunctionNode(node->function(), node); |
| 5403 instructions += | 5445 instructions += |
| 5404 StoreLocal(TokenPosition::kNoSource, LookupVariable(node->variable())); | 5446 StoreLocal(node->position(), LookupVariable(node->variable())); |
| 5405 instructions += Drop(); | 5447 instructions += Drop(); |
| 5406 fragment_ = instructions; | 5448 fragment_ = instructions; |
| 5407 } | 5449 } |
| 5408 | 5450 |
| 5409 | 5451 |
| 5410 void FlowGraphBuilder::VisitIfStatement(IfStatement* node) { | 5452 void FlowGraphBuilder::VisitIfStatement(IfStatement* node) { |
| 5411 bool negate; | 5453 bool negate; |
| 5412 Fragment instructions = TranslateCondition(node->condition(), &negate); | 5454 Fragment instructions = TranslateCondition(node->condition(), &negate); |
| 5413 TargetEntryInstr* then_entry; | 5455 TargetEntryInstr* then_entry; |
| 5414 TargetEntryInstr* otherwise_entry; | 5456 TargetEntryInstr* otherwise_entry; |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5633 void FlowGraphBuilder::VisitBreakStatement(BreakStatement* node) { | 5675 void FlowGraphBuilder::VisitBreakStatement(BreakStatement* node) { |
| 5634 TryFinallyBlock* outer_finally = NULL; | 5676 TryFinallyBlock* outer_finally = NULL; |
| 5635 intptr_t target_context_depth = -1; | 5677 intptr_t target_context_depth = -1; |
| 5636 JoinEntryInstr* destination = breakable_block_->BreakDestination( | 5678 JoinEntryInstr* destination = breakable_block_->BreakDestination( |
| 5637 node->target(), &outer_finally, &target_context_depth); | 5679 node->target(), &outer_finally, &target_context_depth); |
| 5638 | 5680 |
| 5639 Fragment instructions; | 5681 Fragment instructions; |
| 5640 instructions += | 5682 instructions += |
| 5641 TranslateFinallyFinalizers(outer_finally, target_context_depth); | 5683 TranslateFinallyFinalizers(outer_finally, target_context_depth); |
| 5642 if (instructions.is_open()) { | 5684 if (instructions.is_open()) { |
| 5685 if (NeedsDebugStepCheck(parsed_function_->function(), node->position())) { |
| 5686 instructions += DebugStepCheck(node->position()); |
| 5687 } |
| 5643 instructions += Goto(destination); | 5688 instructions += Goto(destination); |
| 5644 } | 5689 } |
| 5645 fragment_ = instructions; | 5690 fragment_ = instructions; |
| 5646 } | 5691 } |
| 5647 | 5692 |
| 5648 | 5693 |
| 5649 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) { | 5694 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) { |
| 5650 SwitchBlock block(this, node); | 5695 SwitchBlock block(this, node); |
| 5651 | 5696 |
| 5652 // Instead of using a variable we should reuse the expression on the stack, | 5697 // Instead of using a variable we should reuse the expression on the stack, |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5975 ++catch_depth_; | 6020 ++catch_depth_; |
| 5976 const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); | 6021 const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); |
| 5977 handler_types.SetAt(0, Object::dynamic_type()); | 6022 handler_types.SetAt(0, Object::dynamic_type()); |
| 5978 Fragment finally_body = CatchBlockEntry(handler_types, try_handler_index); | 6023 Fragment finally_body = CatchBlockEntry(handler_types, try_handler_index); |
| 5979 finally_body += TranslateStatement(node->finalizer()); | 6024 finally_body += TranslateStatement(node->finalizer()); |
| 5980 if (finally_body.is_open()) { | 6025 if (finally_body.is_open()) { |
| 5981 finally_body += LoadLocal(CurrentException()); | 6026 finally_body += LoadLocal(CurrentException()); |
| 5982 finally_body += PushArgument(); | 6027 finally_body += PushArgument(); |
| 5983 finally_body += LoadLocal(CurrentStackTrace()); | 6028 finally_body += LoadLocal(CurrentStackTrace()); |
| 5984 finally_body += PushArgument(); | 6029 finally_body += PushArgument(); |
| 5985 finally_body += RethrowException(try_handler_index); | 6030 finally_body += |
| 6031 RethrowException(TokenPosition::kNoSource, try_handler_index); |
| 5986 Drop(); | 6032 Drop(); |
| 5987 } | 6033 } |
| 5988 --catch_depth_; | 6034 --catch_depth_; |
| 5989 | 6035 |
| 5990 fragment_ = Fragment(try_body.entry, after_try); | 6036 fragment_ = Fragment(try_body.entry, after_try); |
| 5991 } | 6037 } |
| 5992 | 6038 |
| 5993 | 6039 |
| 5994 void FlowGraphBuilder::VisitTryCatch(class TryCatch* node) { | 6040 void FlowGraphBuilder::VisitTryCatch(class TryCatch* node) { |
| 5995 InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch"); | 6041 InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch"); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6086 } | 6132 } |
| 6087 | 6133 |
| 6088 // In case the last catch body was not handling the exception and branching to | 6134 // In case the last catch body was not handling the exception and branching to |
| 6089 // after the try block, we will rethrow the exception (i.e. no default catch | 6135 // after the try block, we will rethrow the exception (i.e. no default catch |
| 6090 // handler). | 6136 // handler). |
| 6091 if (catch_body.is_open()) { | 6137 if (catch_body.is_open()) { |
| 6092 catch_body += LoadLocal(CurrentException()); | 6138 catch_body += LoadLocal(CurrentException()); |
| 6093 catch_body += PushArgument(); | 6139 catch_body += PushArgument(); |
| 6094 catch_body += LoadLocal(CurrentStackTrace()); | 6140 catch_body += LoadLocal(CurrentStackTrace()); |
| 6095 catch_body += PushArgument(); | 6141 catch_body += PushArgument(); |
| 6096 catch_body += RethrowException(try_handler_index); | 6142 catch_body += RethrowException(TokenPosition::kNoSource, try_handler_index); |
| 6097 Drop(); | 6143 Drop(); |
| 6098 } | 6144 } |
| 6099 --catch_depth_; | 6145 --catch_depth_; |
| 6100 | 6146 |
| 6101 fragment_ = Fragment(try_body.entry, after_try); | 6147 fragment_ = Fragment(try_body.entry, after_try); |
| 6102 } | 6148 } |
| 6103 | 6149 |
| 6104 | 6150 |
| 6105 void FlowGraphBuilder::VisitYieldStatement(YieldStatement* node) { | 6151 void FlowGraphBuilder::VisitYieldStatement(YieldStatement* node) { |
| 6106 ASSERT(node->is_native()); // Must have been desugared. | 6152 ASSERT(node->is_native()); // Must have been desugared. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6160 TargetEntryInstr* error; | 6206 TargetEntryInstr* error; |
| 6161 | 6207 |
| 6162 continuation += LoadLocal(exception_var); | 6208 continuation += LoadLocal(exception_var); |
| 6163 continuation += BranchIfNull(&no_error, &error); | 6209 continuation += BranchIfNull(&no_error, &error); |
| 6164 | 6210 |
| 6165 Fragment rethrow(error); | 6211 Fragment rethrow(error); |
| 6166 rethrow += LoadLocal(exception_var); | 6212 rethrow += LoadLocal(exception_var); |
| 6167 rethrow += PushArgument(); | 6213 rethrow += PushArgument(); |
| 6168 rethrow += LoadLocal(stack_trace_var); | 6214 rethrow += LoadLocal(stack_trace_var); |
| 6169 rethrow += PushArgument(); | 6215 rethrow += PushArgument(); |
| 6170 rethrow += RethrowException(CatchClauseNode::kInvalidTryIndex); | 6216 rethrow += |
| 6217 RethrowException(node->position(), CatchClauseNode::kInvalidTryIndex); |
| 6171 Drop(); | 6218 Drop(); |
| 6172 | 6219 |
| 6173 | 6220 |
| 6174 continuation = Fragment(continuation.entry, no_error); | 6221 continuation = Fragment(continuation.entry, no_error); |
| 6175 } | 6222 } |
| 6176 | 6223 |
| 6177 fragment_ = continuation; | 6224 fragment_ = continuation; |
| 6178 } | 6225 } |
| 6179 | 6226 |
| 6180 | 6227 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6261 dart::Class::ZoneHandle(Z, I->object_store()->closure_class()); | 6308 dart::Class::ZoneHandle(Z, I->object_store()->closure_class()); |
| 6262 ASSERT(!closure_class.IsNull()); | 6309 ASSERT(!closure_class.IsNull()); |
| 6263 Fragment instructions = AllocateObject(closure_class, function); | 6310 Fragment instructions = AllocateObject(closure_class, function); |
| 6264 LocalVariable* closure = MakeTemporary(); | 6311 LocalVariable* closure = MakeTemporary(); |
| 6265 | 6312 |
| 6266 // TODO(27590): Generic closures need type arguments. | 6313 // TODO(27590): Generic closures need type arguments. |
| 6267 | 6314 |
| 6268 // Store the function and the context in the closure. | 6315 // Store the function and the context in the closure. |
| 6269 instructions += LoadLocal(closure); | 6316 instructions += LoadLocal(closure); |
| 6270 instructions += Constant(function); | 6317 instructions += Constant(function); |
| 6271 instructions += StoreInstanceField(Closure::function_offset()); | 6318 instructions += |
| 6319 StoreInstanceField(TokenPosition::kNoSource, Closure::function_offset()); |
| 6272 | 6320 |
| 6273 instructions += LoadLocal(closure); | 6321 instructions += LoadLocal(closure); |
| 6274 instructions += LoadLocal(parsed_function_->current_context_var()); | 6322 instructions += LoadLocal(parsed_function_->current_context_var()); |
| 6275 instructions += StoreInstanceField(Closure::context_offset()); | 6323 instructions += |
| 6324 StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset()); |
| 6276 | 6325 |
| 6277 return instructions; | 6326 return instructions; |
| 6278 } | 6327 } |
| 6279 | 6328 |
| 6280 | 6329 |
| 6281 RawObject* EvaluateMetadata(TreeNode* const kernel_node) { | 6330 RawObject* EvaluateMetadata(TreeNode* const kernel_node) { |
| 6282 LongJumpScope jump; | 6331 LongJumpScope jump; |
| 6283 if (setjmp(*jump.Set()) == 0) { | 6332 if (setjmp(*jump.Set()) == 0) { |
| 6284 Thread* thread = Thread::Current(); | 6333 Thread* thread = Thread::Current(); |
| 6285 Zone* zone_ = thread->zone(); | 6334 Zone* zone_ = thread->zone(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6384 thread->clear_sticky_error(); | 6433 thread->clear_sticky_error(); |
| 6385 return error.raw(); | 6434 return error.raw(); |
| 6386 } | 6435 } |
| 6387 } | 6436 } |
| 6388 | 6437 |
| 6389 | 6438 |
| 6390 } // namespace kernel | 6439 } // namespace kernel |
| 6391 } // namespace dart | 6440 } // namespace dart |
| 6392 | 6441 |
| 6393 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6442 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |