| 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 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1321 if (named->length() == 0) return Array::ZoneHandle(Z); | 1321 if (named->length() == 0) return Array::ZoneHandle(Z); |
| 1322 | 1322 |
| 1323 const Array& names = | 1323 const Array& names = |
| 1324 Array::ZoneHandle(Z, Array::New(named->length(), Heap::kOld)); | 1324 Array::ZoneHandle(Z, Array::New(named->length(), Heap::kOld)); |
| 1325 for (intptr_t i = 0; i < named->length(); ++i) { | 1325 for (intptr_t i = 0; i < named->length(); ++i) { |
| 1326 names.SetAt(i, DartSymbol((*named)[i]->name())); | 1326 names.SetAt(i, DartSymbol((*named)[i]->name())); |
| 1327 } | 1327 } |
| 1328 return names; | 1328 return names; |
| 1329 } | 1329 } |
| 1330 | 1330 |
| 1331 | |
| 1332 ConstantEvaluator::ConstantEvaluator(FlowGraphBuilder* builder, | 1331 ConstantEvaluator::ConstantEvaluator(FlowGraphBuilder* builder, |
| 1333 Zone* zone, | 1332 Zone* zone, |
| 1334 TranslationHelper* h, | 1333 TranslationHelper* h, |
| 1335 DartTypeTranslator* type_translator) | 1334 DartTypeTranslator* type_translator) |
| 1336 : builder_(builder), | 1335 : builder_(builder), |
| 1337 isolate_(Isolate::Current()), | 1336 isolate_(Isolate::Current()), |
| 1338 zone_(zone), | 1337 zone_(zone), |
| 1339 translation_helper_(*h), | 1338 translation_helper_(*h), |
| 1340 type_translator_(*type_translator), | 1339 type_translator_(*type_translator), |
| 1341 script_(Script::Handle( | 1340 script_(Script::Handle( |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2060 return instructions; | 2059 return instructions; |
| 2061 } | 2060 } |
| 2062 | 2061 |
| 2063 | 2062 |
| 2064 Fragment FlowGraphBuilder::PushContext(int size) { | 2063 Fragment FlowGraphBuilder::PushContext(int size) { |
| 2065 ASSERT(size > 0); | 2064 ASSERT(size > 0); |
| 2066 Fragment instructions = AllocateContext(size); | 2065 Fragment instructions = AllocateContext(size); |
| 2067 LocalVariable* context = MakeTemporary(); | 2066 LocalVariable* context = MakeTemporary(); |
| 2068 instructions += LoadLocal(context); | 2067 instructions += LoadLocal(context); |
| 2069 instructions += LoadLocal(parsed_function_->current_context_var()); | 2068 instructions += LoadLocal(parsed_function_->current_context_var()); |
| 2070 instructions += StoreInstanceField(Context::parent_offset()); | 2069 instructions += |
| 2070 StoreInstanceField(TokenPosition::kNoSource, Context::parent_offset()); |
| 2071 instructions += StoreLocal(TokenPosition::kNoSource, | 2071 instructions += StoreLocal(TokenPosition::kNoSource, |
| 2072 parsed_function_->current_context_var()); | 2072 parsed_function_->current_context_var()); |
| 2073 ++context_depth_; | 2073 ++context_depth_; |
| 2074 return instructions; | 2074 return instructions; |
| 2075 } | 2075 } |
| 2076 | 2076 |
| 2077 | 2077 |
| 2078 Fragment FlowGraphBuilder::PopContext() { | 2078 Fragment FlowGraphBuilder::PopContext() { |
| 2079 return AdjustContextTo(context_depth_ - 1); | 2079 return AdjustContextTo(context_depth_ - 1); |
| 2080 } | 2080 } |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2408 // Use it's side effect of leaving a constant on the stack (does not change | 2408 // Use it's side effect of leaving a constant on the stack (does not change |
| 2409 // the graph). | 2409 // the graph). |
| 2410 NullConstant(); | 2410 NullConstant(); |
| 2411 | 2411 |
| 2412 pending_argument_count_ -= 1; | 2412 pending_argument_count_ -= 1; |
| 2413 | 2413 |
| 2414 return instructions; | 2414 return instructions; |
| 2415 } | 2415 } |
| 2416 | 2416 |
| 2417 | 2417 |
| 2418 Fragment FlowGraphBuilder::RethrowException(int catch_try_index) { | 2418 Fragment FlowGraphBuilder::RethrowException(TokenPosition position, |
| 2419 int catch_try_index) { |
| 2419 Fragment instructions; | 2420 Fragment instructions; |
| 2420 instructions += Drop(); | 2421 instructions += Drop(); |
| 2421 instructions += Drop(); | 2422 instructions += Drop(); |
| 2422 instructions += | 2423 instructions += |
| 2423 Fragment(new (Z) ReThrowInstr(TokenPosition::kNoSource, catch_try_index)) | 2424 Fragment(new (Z) ReThrowInstr(position, catch_try_index)).closed(); |
| 2424 .closed(); | |
| 2425 // Use it's side effect of leaving a constant on the stack (does not change | 2425 // Use it's side effect of leaving a constant on the stack (does not change |
| 2426 // the graph). | 2426 // the graph). |
| 2427 NullConstant(); | 2427 NullConstant(); |
| 2428 | 2428 |
| 2429 pending_argument_count_ -= 2; | 2429 pending_argument_count_ -= 2; |
| 2430 | 2430 |
| 2431 return instructions; | 2431 return instructions; |
| 2432 } | 2432 } |
| 2433 | 2433 |
| 2434 | 2434 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2541 | 2541 |
| 2542 | 2542 |
| 2543 Fragment FlowGraphBuilder::Return(TokenPosition position) { | 2543 Fragment FlowGraphBuilder::Return(TokenPosition position) { |
| 2544 Fragment instructions; | 2544 Fragment instructions; |
| 2545 | 2545 |
| 2546 instructions += CheckReturnTypeInCheckedMode(); | 2546 instructions += CheckReturnTypeInCheckedMode(); |
| 2547 | 2547 |
| 2548 Value* value = Pop(); | 2548 Value* value = Pop(); |
| 2549 ASSERT(stack_ == NULL); | 2549 ASSERT(stack_ == NULL); |
| 2550 | 2550 |
| 2551 const Function& function = parsed_function_->function(); | 2551 if (NeedsDebugStepCheck(parsed_function_->function(), position)) { |
| 2552 if (FLAG_support_debugger && position.IsDebugPause() && | 2552 instructions += DebugStepCheck(position); |
| 2553 !function.is_native()) { | |
| 2554 instructions <<= | |
| 2555 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); | |
| 2556 } | 2553 } |
| 2557 | 2554 |
| 2558 ReturnInstr* return_instr = new (Z) ReturnInstr(position, value); | 2555 ReturnInstr* return_instr = new (Z) ReturnInstr(position, value); |
| 2559 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); | 2556 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); |
| 2560 | 2557 |
| 2561 instructions <<= return_instr; | 2558 instructions <<= return_instr; |
| 2562 | 2559 |
| 2563 return instructions.closed(); | 2560 return instructions.closed(); |
| 2564 } | 2561 } |
| 2565 | 2562 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2663 instructions += GuardFieldClass(field_clone, H.thread()->GetNextDeoptId()); | 2660 instructions += GuardFieldClass(field_clone, H.thread()->GetNextDeoptId()); |
| 2664 instructions += LoadLocal(store_expression); | 2661 instructions += LoadLocal(store_expression); |
| 2665 instructions += GuardFieldLength(field_clone, H.thread()->GetNextDeoptId()); | 2662 instructions += GuardFieldLength(field_clone, H.thread()->GetNextDeoptId()); |
| 2666 } | 2663 } |
| 2667 instructions += StoreInstanceField(field_clone, is_initialization_store); | 2664 instructions += StoreInstanceField(field_clone, is_initialization_store); |
| 2668 return instructions; | 2665 return instructions; |
| 2669 } | 2666 } |
| 2670 | 2667 |
| 2671 | 2668 |
| 2672 Fragment FlowGraphBuilder::StoreInstanceField( | 2669 Fragment FlowGraphBuilder::StoreInstanceField( |
| 2670 TokenPosition position, |
| 2673 intptr_t offset, | 2671 intptr_t offset, |
| 2674 StoreBarrierType emit_store_barrier) { | 2672 StoreBarrierType emit_store_barrier) { |
| 2675 Value* value = Pop(); | 2673 Value* value = Pop(); |
| 2676 if (value->BindsToConstant()) { | 2674 if (value->BindsToConstant()) { |
| 2677 emit_store_barrier = kNoStoreBarrier; | 2675 emit_store_barrier = kNoStoreBarrier; |
| 2678 } | 2676 } |
| 2679 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr( | 2677 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr( |
| 2680 offset, Pop(), value, emit_store_barrier, TokenPosition::kNoSource); | 2678 offset, Pop(), value, emit_store_barrier, position); |
| 2681 return Fragment(store); | 2679 return Fragment(store); |
| 2682 } | 2680 } |
| 2683 | 2681 |
| 2684 | 2682 |
| 2685 Fragment FlowGraphBuilder::StoreLocal(TokenPosition position, | 2683 Fragment FlowGraphBuilder::StoreLocal(TokenPosition position, |
| 2686 LocalVariable* variable) { | 2684 LocalVariable* variable) { |
| 2687 Fragment instructions; | 2685 Fragment instructions; |
| 2688 if (variable->is_captured()) { | 2686 if (variable->is_captured()) { |
| 2689 LocalVariable* value = MakeTemporary(); | 2687 LocalVariable* value = MakeTemporary(); |
| 2690 instructions += LoadContextAt(variable->owner()->context_level()); | 2688 instructions += LoadContextAt(variable->owner()->context_level()); |
| 2691 instructions += LoadLocal(value); | 2689 instructions += LoadLocal(value); |
| 2692 instructions += | 2690 instructions += StoreInstanceField( |
| 2693 StoreInstanceField(Context::variable_offset(variable->index())); | 2691 position, Context::variable_offset(variable->index())); |
| 2694 } else { | 2692 } else { |
| 2695 Value* value = Pop(); | 2693 Value* value = Pop(); |
| 2696 if (FLAG_support_debugger && position.IsDebugPause() && | |
| 2697 !variable->IsInternal()) { | |
| 2698 if (value->definition()->IsConstant() || | |
| 2699 value->definition()->IsAllocateObject() || | |
| 2700 (value->definition()->IsLoadLocal() && | |
| 2701 !value->definition()->AsLoadLocal()->local().IsInternal())) { | |
| 2702 instructions <<= new (Z) | |
| 2703 DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); | |
| 2704 } | |
| 2705 } | |
| 2706 | |
| 2707 StoreLocalInstr* store = | 2694 StoreLocalInstr* store = |
| 2708 new (Z) StoreLocalInstr(*variable, value, position); | 2695 new (Z) StoreLocalInstr(*variable, value, position); |
| 2709 instructions <<= store; | 2696 instructions <<= store; |
| 2710 Push(store); | 2697 Push(store); |
| 2711 } | 2698 } |
| 2712 return instructions; | 2699 return instructions; |
| 2713 } | 2700 } |
| 2714 | 2701 |
| 2715 | 2702 |
| 2716 Fragment FlowGraphBuilder::StoreStaticField(const dart::Field& field) { | 2703 Fragment FlowGraphBuilder::StoreStaticField(TokenPosition position, |
| 2717 return Fragment(new (Z) StoreStaticFieldInstr(MayCloneField(Z, field), Pop(), | 2704 const dart::Field& field) { |
| 2718 TokenPosition::kNoSource)); | 2705 return Fragment( |
| 2706 new (Z) StoreStaticFieldInstr(MayCloneField(Z, field), Pop(), position)); |
| 2719 } | 2707 } |
| 2720 | 2708 |
| 2721 | 2709 |
| 2722 Fragment FlowGraphBuilder::StringInterpolate(TokenPosition position) { | 2710 Fragment FlowGraphBuilder::StringInterpolate(TokenPosition position) { |
| 2723 Value* array = Pop(); | 2711 Value* array = Pop(); |
| 2724 StringInterpolateInstr* interpolate = | 2712 StringInterpolateInstr* interpolate = |
| 2725 new (Z) StringInterpolateInstr(array, position); | 2713 new (Z) StringInterpolateInstr(array, position); |
| 2726 Push(interpolate); | 2714 Push(interpolate); |
| 2727 return Fragment(interpolate); | 2715 return Fragment(interpolate); |
| 2728 } | 2716 } |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3079 parameter->set_index(parameter_index); | 3067 parameter->set_index(parameter_index); |
| 3080 // Mark the stack variable so it will be ignored by the code for | 3068 // Mark the stack variable so it will be ignored by the code for |
| 3081 // try/catch. | 3069 // try/catch. |
| 3082 parameter->set_is_captured_parameter(true); | 3070 parameter->set_is_captured_parameter(true); |
| 3083 | 3071 |
| 3084 // Copy the parameter from the stack to the context. Overwrite it | 3072 // Copy the parameter from the stack to the context. Overwrite it |
| 3085 // with a null constant on the stack so the original value is | 3073 // with a null constant on the stack so the original value is |
| 3086 // eligible for garbage collection. | 3074 // eligible for garbage collection. |
| 3087 body += LoadLocal(context); | 3075 body += LoadLocal(context); |
| 3088 body += LoadLocal(parameter); | 3076 body += LoadLocal(parameter); |
| 3089 body += StoreInstanceField(Context::variable_offset(variable->index())); | 3077 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3078 Context::variable_offset(variable->index())); |
| 3090 body += NullConstant(); | 3079 body += NullConstant(); |
| 3091 body += StoreLocal(TokenPosition::kNoSource, parameter); | 3080 body += StoreLocal(TokenPosition::kNoSource, parameter); |
| 3092 body += Drop(); | 3081 body += Drop(); |
| 3093 } | 3082 } |
| 3094 } | 3083 } |
| 3095 body += Drop(); // The context. | 3084 body += Drop(); // The context. |
| 3096 } | 3085 } |
| 3097 if (constructor != NULL) { | 3086 if (constructor != NULL) { |
| 3098 // TODO(27590): Currently the [VariableDeclaration]s from the | 3087 // TODO(27590): Currently the [VariableDeclaration]s from the |
| 3099 // initializers will be visible inside the entire body of the constructor. | 3088 // initializers will be visible inside the entire body of the constructor. |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3220 TargetEntryInstr* otherwise; | 3209 TargetEntryInstr* otherwise; |
| 3221 dispatch += LoadLocal(scopes_->switch_variable); | 3210 dispatch += LoadLocal(scopes_->switch_variable); |
| 3222 dispatch += IntConstant(i); | 3211 dispatch += IntConstant(i); |
| 3223 dispatch += BranchIfStrictEqual(&then, &otherwise); | 3212 dispatch += BranchIfStrictEqual(&then, &otherwise); |
| 3224 | 3213 |
| 3225 // True branch is linked to appropriate continuation point. | 3214 // True branch is linked to appropriate continuation point. |
| 3226 // Note: continuations start with nop DropTemps instruction | 3215 // Note: continuations start with nop DropTemps instruction |
| 3227 // which acts like an anchor, so we need to skip it. | 3216 // which acts like an anchor, so we need to skip it. |
| 3228 then->LinkTo(yield_continuations_[i].entry->next()); | 3217 then->LinkTo(yield_continuations_[i].entry->next()); |
| 3229 then->set_try_index(yield_continuations_[i].try_index); | 3218 then->set_try_index(yield_continuations_[i].try_index); |
| 3230 | |
| 3231 // False branch will contain the next comparison. | 3219 // False branch will contain the next comparison. |
| 3232 dispatch = Fragment(dispatch.entry, otherwise); | 3220 dispatch = Fragment(dispatch.entry, otherwise); |
| 3233 block = otherwise; | 3221 block = otherwise; |
| 3234 } | 3222 } |
| 3235 body = dispatch; | 3223 body = dispatch; |
| 3236 | 3224 |
| 3237 context_depth_ = current_context_depth; | 3225 context_depth_ = current_context_depth; |
| 3238 } | 3226 } |
| 3239 | 3227 |
| 3240 if (FLAG_support_debugger && function->position().IsDebugPause() && | 3228 if (NeedsDebugStepCheck(dart_function, function->position())) { |
| 3241 !dart_function.is_native() && dart_function.is_debuggable()) { | |
| 3242 // If a switch was added above: Start the switch by injecting a debugable | 3229 // If a switch was added above: Start the switch by injecting a debugable |
| 3243 // safepoint so stepping over an await works. | 3230 // safepoint so stepping over an await works. |
| 3244 // If not, still start the body with a debugable safepoint to ensure | 3231 // If not, still start the body with a debugable safepoint to ensure |
| 3245 // breaking on a method always happens, even if there are no | 3232 // breaking on a method always happens, even if there are no |
| 3246 // assignments/calls/runtimecalls in the first basic block. | 3233 // assignments/calls/runtimecalls in the first basic block. |
| 3247 // Place this check at the last parameter to ensure parameters | 3234 // Place this check at the last parameter to ensure parameters |
| 3248 // are in scope in the debugger at method entry. | 3235 // are in scope in the debugger at method entry. |
| 3249 const int num_params = dart_function.NumParameters(); | 3236 const int num_params = dart_function.NumParameters(); |
| 3250 TokenPosition check_pos = TokenPosition::kNoSource; | 3237 TokenPosition check_pos = TokenPosition::kNoSource; |
| 3251 if (num_params > 0) { | 3238 if (num_params > 0) { |
| 3252 LocalScope* scope = parsed_function_->node_sequence()->scope(); | 3239 LocalScope* scope = parsed_function_->node_sequence()->scope(); |
| 3253 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); | 3240 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); |
| 3254 check_pos = parameter.token_pos(); | 3241 check_pos = parameter.token_pos(); |
| 3255 } | 3242 } |
| 3256 if (!check_pos.IsDebugPause()) { | 3243 if (!check_pos.IsDebugPause()) { |
| 3257 // No parameters or synthetic parameters. | 3244 // No parameters or synthetic parameters. |
| 3258 check_pos = function->position(); | 3245 check_pos = function->position(); |
| 3259 ASSERT(check_pos.IsDebugPause()); | 3246 ASSERT(check_pos.IsDebugPause()); |
| 3260 } | 3247 } |
| 3261 Fragment check( | 3248 body = DebugStepCheck(check_pos) + body; |
| 3262 new (Z) DebugStepCheckInstr(check_pos, RawPcDescriptors::kRuntimeCall)); | |
| 3263 body = check + body; | |
| 3264 } | 3249 } |
| 3265 | 3250 |
| 3266 normal_entry->LinkTo(body.entry); | 3251 normal_entry->LinkTo(body.entry); |
| 3267 | 3252 |
| 3268 // When compiling for OSR, use a depth first search to prune instructions | 3253 // When compiling for OSR, use a depth first search to prune instructions |
| 3269 // unreachable from the OSR entry. Catch entries are always considered | 3254 // unreachable from the OSR entry. Catch entries are always considered |
| 3270 // reachable, even if they become unreachable after OSR. | 3255 // reachable, even if they become unreachable after OSR. |
| 3271 if (osr_id_ != Compiler::kNoOSRDeoptId) { | 3256 if (osr_id_ != Compiler::kNoOSRDeoptId) { |
| 3272 BitVector* block_marks = new (Z) BitVector(Z, next_block_id_); | 3257 BitVector* block_marks = new (Z) BitVector(Z, next_block_id_); |
| 3273 bool found = graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, | 3258 bool found = graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3358 break; | 3343 break; |
| 3359 case MethodRecognizer::kLinkedHashMap_getIndex: | 3344 case MethodRecognizer::kLinkedHashMap_getIndex: |
| 3360 body += LoadLocal(scopes_->this_variable); | 3345 body += LoadLocal(scopes_->this_variable); |
| 3361 body += LoadNativeField(kind, LinkedHashMap::index_offset(), | 3346 body += LoadNativeField(kind, LinkedHashMap::index_offset(), |
| 3362 Object::dynamic_type(), kDynamicCid); | 3347 Object::dynamic_type(), kDynamicCid); |
| 3363 break; | 3348 break; |
| 3364 case MethodRecognizer::kLinkedHashMap_setIndex: | 3349 case MethodRecognizer::kLinkedHashMap_setIndex: |
| 3365 body += LoadLocal(scopes_->this_variable); | 3350 body += LoadLocal(scopes_->this_variable); |
| 3366 body += LoadLocal( | 3351 body += LoadLocal( |
| 3367 LookupVariable(kernel_function->positional_parameters()[0])); | 3352 LookupVariable(kernel_function->positional_parameters()[0])); |
| 3368 body += StoreInstanceField(LinkedHashMap::index_offset()); | 3353 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3354 LinkedHashMap::index_offset()); |
| 3369 body += NullConstant(); | 3355 body += NullConstant(); |
| 3370 break; | 3356 break; |
| 3371 case MethodRecognizer::kLinkedHashMap_getData: | 3357 case MethodRecognizer::kLinkedHashMap_getData: |
| 3372 body += LoadLocal(scopes_->this_variable); | 3358 body += LoadLocal(scopes_->this_variable); |
| 3373 body += LoadNativeField(kind, LinkedHashMap::data_offset(), | 3359 body += LoadNativeField(kind, LinkedHashMap::data_offset(), |
| 3374 Object::dynamic_type(), kArrayCid); | 3360 Object::dynamic_type(), kArrayCid); |
| 3375 break; | 3361 break; |
| 3376 case MethodRecognizer::kLinkedHashMap_setData: | 3362 case MethodRecognizer::kLinkedHashMap_setData: |
| 3377 body += LoadLocal(scopes_->this_variable); | 3363 body += LoadLocal(scopes_->this_variable); |
| 3378 body += LoadLocal( | 3364 body += LoadLocal( |
| 3379 LookupVariable(kernel_function->positional_parameters()[0])); | 3365 LookupVariable(kernel_function->positional_parameters()[0])); |
| 3380 body += StoreInstanceField(LinkedHashMap::data_offset()); | 3366 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3367 LinkedHashMap::data_offset()); |
| 3381 body += NullConstant(); | 3368 body += NullConstant(); |
| 3382 break; | 3369 break; |
| 3383 case MethodRecognizer::kLinkedHashMap_getHashMask: | 3370 case MethodRecognizer::kLinkedHashMap_getHashMask: |
| 3384 body += LoadLocal(scopes_->this_variable); | 3371 body += LoadLocal(scopes_->this_variable); |
| 3385 body += LoadNativeField(kind, LinkedHashMap::hash_mask_offset(), | 3372 body += LoadNativeField(kind, LinkedHashMap::hash_mask_offset(), |
| 3386 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); | 3373 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); |
| 3387 break; | 3374 break; |
| 3388 case MethodRecognizer::kLinkedHashMap_setHashMask: | 3375 case MethodRecognizer::kLinkedHashMap_setHashMask: |
| 3389 body += LoadLocal(scopes_->this_variable); | 3376 body += LoadLocal(scopes_->this_variable); |
| 3390 body += LoadLocal( | 3377 body += LoadLocal( |
| 3391 LookupVariable(kernel_function->positional_parameters()[0])); | 3378 LookupVariable(kernel_function->positional_parameters()[0])); |
| 3392 body += StoreInstanceField(LinkedHashMap::hash_mask_offset(), | 3379 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3380 LinkedHashMap::hash_mask_offset(), |
| 3393 kNoStoreBarrier); | 3381 kNoStoreBarrier); |
| 3394 body += NullConstant(); | 3382 body += NullConstant(); |
| 3395 break; | 3383 break; |
| 3396 case MethodRecognizer::kLinkedHashMap_getUsedData: | 3384 case MethodRecognizer::kLinkedHashMap_getUsedData: |
| 3397 body += LoadLocal(scopes_->this_variable); | 3385 body += LoadLocal(scopes_->this_variable); |
| 3398 body += LoadNativeField(kind, LinkedHashMap::used_data_offset(), | 3386 body += LoadNativeField(kind, LinkedHashMap::used_data_offset(), |
| 3399 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); | 3387 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); |
| 3400 break; | 3388 break; |
| 3401 case MethodRecognizer::kLinkedHashMap_setUsedData: | 3389 case MethodRecognizer::kLinkedHashMap_setUsedData: |
| 3402 body += LoadLocal(scopes_->this_variable); | 3390 body += LoadLocal(scopes_->this_variable); |
| 3403 body += LoadLocal( | 3391 body += LoadLocal( |
| 3404 LookupVariable(kernel_function->positional_parameters()[0])); | 3392 LookupVariable(kernel_function->positional_parameters()[0])); |
| 3405 body += StoreInstanceField(LinkedHashMap::used_data_offset(), | 3393 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3394 LinkedHashMap::used_data_offset(), |
| 3406 kNoStoreBarrier); | 3395 kNoStoreBarrier); |
| 3407 body += NullConstant(); | 3396 body += NullConstant(); |
| 3408 break; | 3397 break; |
| 3409 case MethodRecognizer::kLinkedHashMap_getDeletedKeys: | 3398 case MethodRecognizer::kLinkedHashMap_getDeletedKeys: |
| 3410 body += LoadLocal(scopes_->this_variable); | 3399 body += LoadLocal(scopes_->this_variable); |
| 3411 body += LoadNativeField(kind, LinkedHashMap::deleted_keys_offset(), | 3400 body += LoadNativeField(kind, LinkedHashMap::deleted_keys_offset(), |
| 3412 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); | 3401 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); |
| 3413 break; | 3402 break; |
| 3414 case MethodRecognizer::kLinkedHashMap_setDeletedKeys: | 3403 case MethodRecognizer::kLinkedHashMap_setDeletedKeys: |
| 3415 body += LoadLocal(scopes_->this_variable); | 3404 body += LoadLocal(scopes_->this_variable); |
| 3416 body += LoadLocal( | 3405 body += LoadLocal( |
| 3417 LookupVariable(kernel_function->positional_parameters()[0])); | 3406 LookupVariable(kernel_function->positional_parameters()[0])); |
| 3418 body += StoreInstanceField(LinkedHashMap::deleted_keys_offset(), | 3407 body += StoreInstanceField(TokenPosition::kNoSource, |
| 3408 LinkedHashMap::deleted_keys_offset(), |
| 3419 kNoStoreBarrier); | 3409 kNoStoreBarrier); |
| 3420 body += NullConstant(); | 3410 body += NullConstant(); |
| 3421 break; | 3411 break; |
| 3422 case MethodRecognizer::kBigint_getNeg: | 3412 case MethodRecognizer::kBigint_getNeg: |
| 3423 body += LoadLocal(scopes_->this_variable); | 3413 body += LoadLocal(scopes_->this_variable); |
| 3424 body += LoadNativeField(kind, Bigint::neg_offset(), | 3414 body += LoadNativeField(kind, Bigint::neg_offset(), |
| 3425 Type::ZoneHandle(Z, Type::BoolType()), kBoolCid); | 3415 Type::ZoneHandle(Z, Type::BoolType()), kBoolCid); |
| 3426 break; | 3416 break; |
| 3427 default: { | 3417 default: { |
| 3428 dart::String& name = dart::String::ZoneHandle(Z, function.native_name()); | 3418 dart::String& name = dart::String::ZoneHandle(Z, function.native_name()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3449 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); | 3439 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); |
| 3450 | 3440 |
| 3451 Fragment body(normal_entry); | 3441 Fragment body(normal_entry); |
| 3452 if (is_setter) { | 3442 if (is_setter) { |
| 3453 if (is_method) { | 3443 if (is_method) { |
| 3454 body += LoadLocal(scopes_->this_variable); | 3444 body += LoadLocal(scopes_->this_variable); |
| 3455 body += LoadLocal(setter_value); | 3445 body += LoadLocal(setter_value); |
| 3456 body += StoreInstanceFieldGuarded(field, false); | 3446 body += StoreInstanceFieldGuarded(field, false); |
| 3457 } else { | 3447 } else { |
| 3458 body += LoadLocal(setter_value); | 3448 body += LoadLocal(setter_value); |
| 3459 body += StoreStaticField(field); | 3449 body += StoreStaticField(TokenPosition::kNoSource, field); |
| 3460 } | 3450 } |
| 3461 body += NullConstant(); | 3451 body += NullConstant(); |
| 3462 } else if (is_method) { | 3452 } else if (is_method) { |
| 3463 body += LoadLocal(scopes_->this_variable); | 3453 body += LoadLocal(scopes_->this_variable); |
| 3464 body += LoadField(field); | 3454 body += LoadField(field); |
| 3465 } else if (field.is_const()) { | 3455 } else if (field.is_const()) { |
| 3466 // If the parser needs to know the value of an uninitialized constant field | 3456 // If the parser needs to know the value of an uninitialized constant field |
| 3467 // it will set the value to the transition sentinel (used to detect circular | 3457 // it will set the value to the transition sentinel (used to detect circular |
| 3468 // initialization) and then call the implicit getter. Thus, the getter | 3458 // initialization) and then call the implicit getter. Thus, the getter |
| 3469 // cannot contain the InitStaticField instruction that normal static getters | 3459 // cannot contain the InitStaticField instruction that normal static getters |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3518 fragment += AllocateObject(closure_class, target); | 3508 fragment += AllocateObject(closure_class, target); |
| 3519 LocalVariable* closure = MakeTemporary(); | 3509 LocalVariable* closure = MakeTemporary(); |
| 3520 | 3510 |
| 3521 // Allocate a context that closes over `this`. | 3511 // Allocate a context that closes over `this`. |
| 3522 fragment += AllocateContext(1); | 3512 fragment += AllocateContext(1); |
| 3523 LocalVariable* context = MakeTemporary(); | 3513 LocalVariable* context = MakeTemporary(); |
| 3524 | 3514 |
| 3525 // Store the function and the context in the closure. | 3515 // Store the function and the context in the closure. |
| 3526 fragment += LoadLocal(closure); | 3516 fragment += LoadLocal(closure); |
| 3527 fragment += Constant(target); | 3517 fragment += Constant(target); |
| 3528 fragment += StoreInstanceField(Closure::function_offset()); | 3518 fragment += |
| 3519 StoreInstanceField(TokenPosition::kNoSource, Closure::function_offset()); |
| 3529 | 3520 |
| 3530 fragment += LoadLocal(closure); | 3521 fragment += LoadLocal(closure); |
| 3531 fragment += LoadLocal(context); | 3522 fragment += LoadLocal(context); |
| 3532 fragment += StoreInstanceField(Closure::context_offset()); | 3523 fragment += |
| 3524 StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset()); |
| 3533 | 3525 |
| 3534 // The context is on top of the operand stack. Store `this`. The context | 3526 // The context is on top of the operand stack. Store `this`. The context |
| 3535 // doesn't need a parent pointer because it doesn't close over anything | 3527 // doesn't need a parent pointer because it doesn't close over anything |
| 3536 // else. | 3528 // else. |
| 3537 fragment += LoadLocal(scopes_->this_variable); | 3529 fragment += LoadLocal(scopes_->this_variable); |
| 3538 fragment += StoreInstanceField(Context::variable_offset(0)); | 3530 fragment += |
| 3531 StoreInstanceField(TokenPosition::kNoSource, Context::variable_offset(0)); |
| 3539 | 3532 |
| 3540 return fragment; | 3533 return fragment; |
| 3541 } | 3534 } |
| 3542 | 3535 |
| 3543 | 3536 |
| 3544 Fragment FlowGraphBuilder::GuardFieldLength(const dart::Field& field, | 3537 Fragment FlowGraphBuilder::GuardFieldLength(const dart::Field& field, |
| 3545 intptr_t deopt_id) { | 3538 intptr_t deopt_id) { |
| 3546 return Fragment(new (Z) GuardFieldLengthInstr(Pop(), field, deopt_id)); | 3539 return Fragment(new (Z) GuardFieldLengthInstr(Pop(), field, deopt_id)); |
| 3547 } | 3540 } |
| 3548 | 3541 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3560 if (dst_type.IsMalformed()) { | 3553 if (dst_type.IsMalformed()) { |
| 3561 return ThrowTypeError(); | 3554 return ThrowTypeError(); |
| 3562 } | 3555 } |
| 3563 return CheckAssignableInCheckedMode(dst_type, | 3556 return CheckAssignableInCheckedMode(dst_type, |
| 3564 H.DartSymbol(variable->name())); | 3557 H.DartSymbol(variable->name())); |
| 3565 } | 3558 } |
| 3566 return Fragment(); | 3559 return Fragment(); |
| 3567 } | 3560 } |
| 3568 | 3561 |
| 3569 | 3562 |
| 3563 bool FlowGraphBuilder::NeedsDebugStepCheck(const Function& function, |
| 3564 TokenPosition position) { |
| 3565 return FLAG_support_debugger && position.IsDebugPause() && |
| 3566 !function.is_native() && function.is_debuggable(); |
| 3567 } |
| 3568 |
| 3569 |
| 3570 bool FlowGraphBuilder::NeedsDebugStepCheck(Value* value, |
| 3571 TokenPosition position) { |
| 3572 if (!FLAG_support_debugger || !position.IsDebugPause()) return false; |
| 3573 Definition* definition = value->definition(); |
| 3574 if (definition->IsConstant() || definition->IsLoadStaticField()) return true; |
| 3575 if (definition->IsAllocateObject()) { |
| 3576 return !definition->AsAllocateObject()->closure_function().IsNull(); |
| 3577 } |
| 3578 return definition->IsLoadLocal() && |
| 3579 !definition->AsLoadLocal()->local().IsInternal(); |
| 3580 } |
| 3581 |
| 3582 Fragment FlowGraphBuilder::DebugStepCheck(TokenPosition position) { |
| 3583 return Fragment( |
| 3584 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall)); |
| 3585 } |
| 3586 |
| 3587 |
| 3570 Fragment FlowGraphBuilder::EvaluateAssertion() { | 3588 Fragment FlowGraphBuilder::EvaluateAssertion() { |
| 3571 const dart::Class& klass = dart::Class::ZoneHandle( | 3589 const dart::Class& klass = dart::Class::ZoneHandle( |
| 3572 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); | 3590 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); |
| 3573 ASSERT(!klass.IsNull()); | 3591 ASSERT(!klass.IsNull()); |
| 3574 const dart::Function& target = | 3592 const dart::Function& target = |
| 3575 dart::Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate( | 3593 dart::Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate( |
| 3576 H.DartSymbol("_evaluateAssertion"))); | 3594 H.DartSymbol("_evaluateAssertion"))); |
| 3577 ASSERT(!target.IsNull()); | 3595 ASSERT(!target.IsNull()); |
| 3578 return StaticCall(TokenPosition::kNoSource, target, 1); | 3596 return StaticCall(TokenPosition::kNoSource, target, 1); |
| 3579 } | 3597 } |
| (...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4476 } | 4494 } |
| 4477 | 4495 |
| 4478 | 4496 |
| 4479 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { | 4497 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { |
| 4480 fragment_ = LoadLocal(LookupVariable(node->variable())); | 4498 fragment_ = LoadLocal(LookupVariable(node->variable())); |
| 4481 } | 4499 } |
| 4482 | 4500 |
| 4483 | 4501 |
| 4484 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { | 4502 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) { |
| 4485 Fragment instructions = TranslateExpression(node->expression()); | 4503 Fragment instructions = TranslateExpression(node->expression()); |
| 4504 if (NeedsDebugStepCheck(stack_, node->position())) { |
| 4505 instructions = DebugStepCheck(node->position()) + instructions; |
| 4506 } |
| 4486 instructions += CheckVariableTypeInCheckedMode(node->variable()); | 4507 instructions += CheckVariableTypeInCheckedMode(node->variable()); |
| 4487 instructions += | 4508 instructions += |
| 4488 StoreLocal(node->position(), LookupVariable(node->variable())); | 4509 StoreLocal(node->position(), LookupVariable(node->variable())); |
| 4489 fragment_ = instructions; | 4510 fragment_ = instructions; |
| 4490 } | 4511 } |
| 4491 | 4512 |
| 4492 | 4513 |
| 4493 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { | 4514 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) { |
| 4494 Member* target = node->target(); | 4515 Member* target = node->target(); |
| 4495 if (target->IsField()) { | 4516 if (target->IsField()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4528 | 4549 |
| 4529 | 4550 |
| 4530 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { | 4551 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) { |
| 4531 Member* target = node->target(); | 4552 Member* target = node->target(); |
| 4532 if (target->IsField()) { | 4553 if (target->IsField()) { |
| 4533 Field* kernel_field = Field::Cast(target); | 4554 Field* kernel_field = Field::Cast(target); |
| 4534 const dart::Field& field = | 4555 const dart::Field& field = |
| 4535 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); | 4556 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); |
| 4536 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); | 4557 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); |
| 4537 Fragment instructions = TranslateExpression(node->expression()); | 4558 Fragment instructions = TranslateExpression(node->expression()); |
| 4559 if (NeedsDebugStepCheck(stack_, node->position())) { |
| 4560 instructions = DebugStepCheck(node->position()) + instructions; |
| 4561 } |
| 4538 instructions += CheckAssignableInCheckedMode( | 4562 instructions += CheckAssignableInCheckedMode( |
| 4539 dst_type, dart::String::ZoneHandle(Z, field.name())); | 4563 dst_type, dart::String::ZoneHandle(Z, field.name())); |
| 4540 LocalVariable* variable = MakeTemporary(); | 4564 LocalVariable* variable = MakeTemporary(); |
| 4541 instructions += LoadLocal(variable); | 4565 instructions += LoadLocal(variable); |
| 4542 fragment_ = instructions + StoreStaticField(field); | 4566 fragment_ = instructions + StoreStaticField(node->position(), field); |
| 4543 } else { | 4567 } else { |
| 4544 ASSERT(target->IsProcedure()); | 4568 ASSERT(target->IsProcedure()); |
| 4545 | 4569 |
| 4546 // Evaluate the expression on the right hand side. | 4570 // Evaluate the expression on the right hand side. |
| 4547 Fragment instructions = TranslateExpression(node->expression()); | 4571 Fragment instructions = TranslateExpression(node->expression()); |
| 4548 LocalVariable* variable = MakeTemporary(); | 4572 LocalVariable* variable = MakeTemporary(); |
| 4549 | 4573 |
| 4550 // Prepare argument. | 4574 // Prepare argument. |
| 4551 instructions += LoadLocal(variable); | 4575 instructions += LoadLocal(variable); |
| 4552 instructions += PushArgument(); | 4576 instructions += PushArgument(); |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4958 instructions += LoadInstantiatorTypeArguments(); | 4982 instructions += LoadInstantiatorTypeArguments(); |
| 4959 } else { | 4983 } else { |
| 4960 instructions += NullConstant(); | 4984 instructions += NullConstant(); |
| 4961 } | 4985 } |
| 4962 instructions += PushArgument(); // Type arguments. | 4986 instructions += PushArgument(); // Type arguments. |
| 4963 | 4987 |
| 4964 instructions += Constant(type); | 4988 instructions += Constant(type); |
| 4965 instructions += PushArgument(); // Type. | 4989 instructions += PushArgument(); // Type. |
| 4966 | 4990 |
| 4967 instructions += InstanceCall( | 4991 instructions += InstanceCall( |
| 4968 TokenPosition::kNoSource, | 4992 node->position(), dart::Library::PrivateCoreLibName(Symbols::_as()), |
| 4969 dart::Library::PrivateCoreLibName(Symbols::_as()), Token::kAS, 3); | 4993 Token::kAS, 3); |
| 4970 } | 4994 } |
| 4971 | 4995 |
| 4972 fragment_ = instructions; | 4996 fragment_ = instructions; |
| 4973 } | 4997 } |
| 4974 | 4998 |
| 4975 | 4999 |
| 4976 void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) { | 5000 void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) { |
| 4977 bool negate; | 5001 bool negate; |
| 4978 Fragment instructions = TranslateCondition(node->condition(), &negate); | 5002 Fragment instructions = TranslateCondition(node->condition(), &negate); |
| 4979 | 5003 |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5183 Fragment instructions = TranslateStatement(node->variable()); | 5207 Fragment instructions = TranslateStatement(node->variable()); |
| 5184 instructions += TranslateExpression(node->body()); | 5208 instructions += TranslateExpression(node->body()); |
| 5185 fragment_ = instructions; | 5209 fragment_ = instructions; |
| 5186 } | 5210 } |
| 5187 | 5211 |
| 5188 | 5212 |
| 5189 void FlowGraphBuilder::VisitThrow(Throw* node) { | 5213 void FlowGraphBuilder::VisitThrow(Throw* node) { |
| 5190 Fragment instructions; | 5214 Fragment instructions; |
| 5191 | 5215 |
| 5192 instructions += TranslateExpression(node->expression()); | 5216 instructions += TranslateExpression(node->expression()); |
| 5217 if (NeedsDebugStepCheck(stack_, node->position())) { |
| 5218 instructions = DebugStepCheck(node->position()) + instructions; |
| 5219 } |
| 5193 instructions += PushArgument(); | 5220 instructions += PushArgument(); |
| 5194 instructions += ThrowException(node->position()); | 5221 instructions += ThrowException(node->position()); |
| 5195 ASSERT(instructions.is_closed()); | 5222 ASSERT(instructions.is_closed()); |
| 5196 | 5223 |
| 5197 fragment_ = instructions; | 5224 fragment_ = instructions; |
| 5198 } | 5225 } |
| 5199 | 5226 |
| 5200 | 5227 |
| 5201 void FlowGraphBuilder::VisitRethrow(Rethrow* node) { | 5228 void FlowGraphBuilder::VisitRethrow(Rethrow* node) { |
| 5202 Fragment instructions; | 5229 Fragment instructions; |
| 5203 | 5230 |
| 5231 instructions = DebugStepCheck(node->position()) + instructions; |
| 5204 instructions += LoadLocal(catch_block_->exception_var()); | 5232 instructions += LoadLocal(catch_block_->exception_var()); |
| 5205 instructions += PushArgument(); | 5233 instructions += PushArgument(); |
| 5206 instructions += LoadLocal(catch_block_->stack_trace_var()); | 5234 instructions += LoadLocal(catch_block_->stack_trace_var()); |
| 5207 instructions += PushArgument(); | 5235 instructions += PushArgument(); |
| 5208 instructions += RethrowException(catch_block_->catch_try_index()); | 5236 instructions += |
| 5237 RethrowException(node->position(), catch_block_->catch_try_index()); |
| 5209 | 5238 |
| 5210 fragment_ = instructions; | 5239 fragment_ = instructions; |
| 5211 } | 5240 } |
| 5212 | 5241 |
| 5213 | 5242 |
| 5214 Fragment FlowGraphBuilder::TranslateArguments(Arguments* node, | 5243 Fragment FlowGraphBuilder::TranslateArguments(Arguments* node, |
| 5215 Array* argument_names) { | 5244 Array* argument_names) { |
| 5216 Fragment instructions; | 5245 Fragment instructions; |
| 5217 | 5246 |
| 5218 List<Expression>& positional = node->positional(); | 5247 List<Expression>& positional = node->positional(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5261 | 5290 |
| 5262 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { | 5291 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { |
| 5263 bool inside_try_finally = try_finally_block_ != NULL; | 5292 bool inside_try_finally = try_finally_block_ != NULL; |
| 5264 | 5293 |
| 5265 Fragment instructions = node->expression() == NULL | 5294 Fragment instructions = node->expression() == NULL |
| 5266 ? NullConstant() | 5295 ? NullConstant() |
| 5267 : TranslateExpression(node->expression()); | 5296 : TranslateExpression(node->expression()); |
| 5268 if (instructions.is_open()) { | 5297 if (instructions.is_open()) { |
| 5269 if (inside_try_finally) { | 5298 if (inside_try_finally) { |
| 5270 ASSERT(scopes_->finally_return_variable != NULL); | 5299 ASSERT(scopes_->finally_return_variable != NULL); |
| 5271 instructions += StoreLocal(TokenPosition::kNoSource, | 5300 const Function& function = parsed_function_->function(); |
| 5272 scopes_->finally_return_variable); | 5301 if (NeedsDebugStepCheck(function, node->position())) { |
| 5302 instructions += DebugStepCheck(node->position()); |
| 5303 } |
| 5304 instructions += |
| 5305 StoreLocal(node->position(), scopes_->finally_return_variable); |
| 5273 instructions += Drop(); | 5306 instructions += Drop(); |
| 5274 instructions += TranslateFinallyFinalizers(NULL, -1); | 5307 instructions += TranslateFinallyFinalizers(NULL, -1); |
| 5275 if (instructions.is_open()) { | 5308 if (instructions.is_open()) { |
| 5276 instructions += LoadLocal(scopes_->finally_return_variable); | 5309 instructions += LoadLocal(scopes_->finally_return_variable); |
| 5277 instructions += Return(node->position()); | 5310 instructions += Return(TokenPosition::kNoSource); |
| 5278 } | 5311 } |
| 5279 } else { | 5312 } else { |
| 5280 instructions += Return(node->position()); | 5313 instructions += Return(node->position()); |
| 5281 } | 5314 } |
| 5282 } else { | 5315 } else { |
| 5283 Pop(); | 5316 Pop(); |
| 5284 } | 5317 } |
| 5285 fragment_ = instructions; | 5318 fragment_ = instructions; |
| 5286 } | 5319 } |
| 5287 | 5320 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 5304 if (node->IsConst()) { | 5337 if (node->IsConst()) { |
| 5305 const Instance& constant_value = | 5338 const Instance& constant_value = |
| 5306 constant_evaluator_.EvaluateExpression(initializer); | 5339 constant_evaluator_.EvaluateExpression(initializer); |
| 5307 variable->SetConstValue(constant_value); | 5340 variable->SetConstValue(constant_value); |
| 5308 instructions += Constant(constant_value); | 5341 instructions += Constant(constant_value); |
| 5309 } else { | 5342 } else { |
| 5310 instructions += TranslateExpression(initializer); | 5343 instructions += TranslateExpression(initializer); |
| 5311 instructions += CheckVariableTypeInCheckedMode(node); | 5344 instructions += CheckVariableTypeInCheckedMode(node); |
| 5312 } | 5345 } |
| 5313 } | 5346 } |
| 5314 instructions += StoreLocal(variable->token_pos(), variable); | 5347 // Use position of equal sign if it exists. If the equal sign does not exist |
| 5348 // use the position of the identifier. |
| 5349 TokenPosition debug_position = |
| 5350 Utils::Maximum(node->position(), node->equals_position()); |
| 5351 if (NeedsDebugStepCheck(stack_, debug_position)) { |
| 5352 instructions = DebugStepCheck(debug_position) + instructions; |
| 5353 } |
| 5354 instructions += StoreLocal(node->position(), variable); |
| 5315 instructions += Drop(); | 5355 instructions += Drop(); |
| 5316 fragment_ = instructions; | 5356 fragment_ = instructions; |
| 5317 } | 5357 } |
| 5318 | 5358 |
| 5319 | 5359 |
| 5320 void FlowGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { | 5360 void FlowGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) { |
| 5321 Fragment instructions = TranslateFunctionNode(node->function(), node); | 5361 Fragment instructions = DebugStepCheck(node->position()); |
| 5362 instructions += TranslateFunctionNode(node->function(), node); |
| 5322 instructions += | 5363 instructions += |
| 5323 StoreLocal(TokenPosition::kNoSource, LookupVariable(node->variable())); | 5364 StoreLocal(node->position(), LookupVariable(node->variable())); |
| 5324 instructions += Drop(); | 5365 instructions += Drop(); |
| 5325 fragment_ = instructions; | 5366 fragment_ = instructions; |
| 5326 } | 5367 } |
| 5327 | 5368 |
| 5328 | 5369 |
| 5329 void FlowGraphBuilder::VisitIfStatement(IfStatement* node) { | 5370 void FlowGraphBuilder::VisitIfStatement(IfStatement* node) { |
| 5330 bool negate; | 5371 bool negate; |
| 5331 Fragment instructions = TranslateCondition(node->condition(), &negate); | 5372 Fragment instructions = TranslateCondition(node->condition(), &negate); |
| 5332 TargetEntryInstr* then_entry; | 5373 TargetEntryInstr* then_entry; |
| 5333 TargetEntryInstr* otherwise_entry; | 5374 TargetEntryInstr* otherwise_entry; |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5552 void FlowGraphBuilder::VisitBreakStatement(BreakStatement* node) { | 5593 void FlowGraphBuilder::VisitBreakStatement(BreakStatement* node) { |
| 5553 TryFinallyBlock* outer_finally = NULL; | 5594 TryFinallyBlock* outer_finally = NULL; |
| 5554 intptr_t target_context_depth = -1; | 5595 intptr_t target_context_depth = -1; |
| 5555 JoinEntryInstr* destination = breakable_block_->BreakDestination( | 5596 JoinEntryInstr* destination = breakable_block_->BreakDestination( |
| 5556 node->target(), &outer_finally, &target_context_depth); | 5597 node->target(), &outer_finally, &target_context_depth); |
| 5557 | 5598 |
| 5558 Fragment instructions; | 5599 Fragment instructions; |
| 5559 instructions += | 5600 instructions += |
| 5560 TranslateFinallyFinalizers(outer_finally, target_context_depth); | 5601 TranslateFinallyFinalizers(outer_finally, target_context_depth); |
| 5561 if (instructions.is_open()) { | 5602 if (instructions.is_open()) { |
| 5603 if (NeedsDebugStepCheck(parsed_function_->function(), node->position())) { |
| 5604 instructions += DebugStepCheck(node->position()); |
| 5605 } |
| 5562 instructions += Goto(destination); | 5606 instructions += Goto(destination); |
| 5563 } | 5607 } |
| 5564 fragment_ = instructions; | 5608 fragment_ = instructions; |
| 5565 } | 5609 } |
| 5566 | 5610 |
| 5567 | 5611 |
| 5568 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) { | 5612 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) { |
| 5569 SwitchBlock block(this, node); | 5613 SwitchBlock block(this, node); |
| 5570 | 5614 |
| 5571 // Instead of using a variable we should reuse the expression on the stack, | 5615 // 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... |
| 5894 ++catch_depth_; | 5938 ++catch_depth_; |
| 5895 const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); | 5939 const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); |
| 5896 handler_types.SetAt(0, Object::dynamic_type()); | 5940 handler_types.SetAt(0, Object::dynamic_type()); |
| 5897 Fragment finally_body = CatchBlockEntry(handler_types, try_handler_index); | 5941 Fragment finally_body = CatchBlockEntry(handler_types, try_handler_index); |
| 5898 finally_body += TranslateStatement(node->finalizer()); | 5942 finally_body += TranslateStatement(node->finalizer()); |
| 5899 if (finally_body.is_open()) { | 5943 if (finally_body.is_open()) { |
| 5900 finally_body += LoadLocal(CurrentException()); | 5944 finally_body += LoadLocal(CurrentException()); |
| 5901 finally_body += PushArgument(); | 5945 finally_body += PushArgument(); |
| 5902 finally_body += LoadLocal(CurrentStackTrace()); | 5946 finally_body += LoadLocal(CurrentStackTrace()); |
| 5903 finally_body += PushArgument(); | 5947 finally_body += PushArgument(); |
| 5904 finally_body += RethrowException(try_handler_index); | 5948 finally_body += |
| 5949 RethrowException(TokenPosition::kNoSource, try_handler_index); |
| 5905 Drop(); | 5950 Drop(); |
| 5906 } | 5951 } |
| 5907 --catch_depth_; | 5952 --catch_depth_; |
| 5908 | 5953 |
| 5909 fragment_ = Fragment(try_body.entry, after_try); | 5954 fragment_ = Fragment(try_body.entry, after_try); |
| 5910 } | 5955 } |
| 5911 | 5956 |
| 5912 | 5957 |
| 5913 void FlowGraphBuilder::VisitTryCatch(class TryCatch* node) { | 5958 void FlowGraphBuilder::VisitTryCatch(class TryCatch* node) { |
| 5914 InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch"); | 5959 InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch"); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6005 } | 6050 } |
| 6006 | 6051 |
| 6007 // In case the last catch body was not handling the exception and branching to | 6052 // In case the last catch body was not handling the exception and branching to |
| 6008 // after the try block, we will rethrow the exception (i.e. no default catch | 6053 // after the try block, we will rethrow the exception (i.e. no default catch |
| 6009 // handler). | 6054 // handler). |
| 6010 if (catch_body.is_open()) { | 6055 if (catch_body.is_open()) { |
| 6011 catch_body += LoadLocal(CurrentException()); | 6056 catch_body += LoadLocal(CurrentException()); |
| 6012 catch_body += PushArgument(); | 6057 catch_body += PushArgument(); |
| 6013 catch_body += LoadLocal(CurrentStackTrace()); | 6058 catch_body += LoadLocal(CurrentStackTrace()); |
| 6014 catch_body += PushArgument(); | 6059 catch_body += PushArgument(); |
| 6015 catch_body += RethrowException(try_handler_index); | 6060 catch_body += RethrowException(TokenPosition::kNoSource, try_handler_index); |
| 6016 Drop(); | 6061 Drop(); |
| 6017 } | 6062 } |
| 6018 --catch_depth_; | 6063 --catch_depth_; |
| 6019 | 6064 |
| 6020 fragment_ = Fragment(try_body.entry, after_try); | 6065 fragment_ = Fragment(try_body.entry, after_try); |
| 6021 } | 6066 } |
| 6022 | 6067 |
| 6023 | 6068 |
| 6024 void FlowGraphBuilder::VisitYieldStatement(YieldStatement* node) { | 6069 void FlowGraphBuilder::VisitYieldStatement(YieldStatement* node) { |
| 6025 ASSERT(node->is_native()); // Must have been desugared. | 6070 ASSERT(node->is_native()); // Must have been desugared. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6080 TargetEntryInstr* error; | 6125 TargetEntryInstr* error; |
| 6081 | 6126 |
| 6082 continuation += LoadLocal(exception_var); | 6127 continuation += LoadLocal(exception_var); |
| 6083 continuation += BranchIfNull(&no_error, &error); | 6128 continuation += BranchIfNull(&no_error, &error); |
| 6084 | 6129 |
| 6085 Fragment rethrow(error); | 6130 Fragment rethrow(error); |
| 6086 rethrow += LoadLocal(exception_var); | 6131 rethrow += LoadLocal(exception_var); |
| 6087 rethrow += PushArgument(); | 6132 rethrow += PushArgument(); |
| 6088 rethrow += LoadLocal(stack_trace_var); | 6133 rethrow += LoadLocal(stack_trace_var); |
| 6089 rethrow += PushArgument(); | 6134 rethrow += PushArgument(); |
| 6090 rethrow += RethrowException(CatchClauseNode::kInvalidTryIndex); | 6135 rethrow += RethrowException(TokenPosition::kNoSource, |
| 6136 CatchClauseNode::kInvalidTryIndex); |
| 6091 Drop(); | 6137 Drop(); |
| 6092 | 6138 |
| 6093 | 6139 |
| 6094 continuation = Fragment(continuation.entry, no_error); | 6140 continuation = Fragment(continuation.entry, no_error); |
| 6095 } | 6141 } |
| 6096 | 6142 |
| 6097 fragment_ = continuation; | 6143 fragment_ = continuation; |
| 6098 } | 6144 } |
| 6099 | 6145 |
| 6100 | 6146 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6157 dart::Class::ZoneHandle(Z, I->object_store()->closure_class()); | 6203 dart::Class::ZoneHandle(Z, I->object_store()->closure_class()); |
| 6158 ASSERT(!closure_class.IsNull()); | 6204 ASSERT(!closure_class.IsNull()); |
| 6159 Fragment instructions = AllocateObject(closure_class, function); | 6205 Fragment instructions = AllocateObject(closure_class, function); |
| 6160 LocalVariable* closure = MakeTemporary(); | 6206 LocalVariable* closure = MakeTemporary(); |
| 6161 | 6207 |
| 6162 // TODO(27590): Generic closures need type arguments. | 6208 // TODO(27590): Generic closures need type arguments. |
| 6163 | 6209 |
| 6164 // Store the function and the context in the closure. | 6210 // Store the function and the context in the closure. |
| 6165 instructions += LoadLocal(closure); | 6211 instructions += LoadLocal(closure); |
| 6166 instructions += Constant(function); | 6212 instructions += Constant(function); |
| 6167 instructions += StoreInstanceField(Closure::function_offset()); | 6213 instructions += |
| 6214 StoreInstanceField(TokenPosition::kNoSource, Closure::function_offset()); |
| 6168 | 6215 |
| 6169 instructions += LoadLocal(closure); | 6216 instructions += LoadLocal(closure); |
| 6170 instructions += LoadLocal(parsed_function_->current_context_var()); | 6217 instructions += LoadLocal(parsed_function_->current_context_var()); |
| 6171 instructions += StoreInstanceField(Closure::context_offset()); | 6218 instructions += |
| 6219 StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset()); |
| 6172 | 6220 |
| 6173 return instructions; | 6221 return instructions; |
| 6174 } | 6222 } |
| 6175 | 6223 |
| 6176 | 6224 |
| 6177 RawObject* EvaluateMetadata(TreeNode* const kernel_node) { | 6225 RawObject* EvaluateMetadata(TreeNode* const kernel_node) { |
| 6178 LongJumpScope jump; | 6226 LongJumpScope jump; |
| 6179 if (setjmp(*jump.Set()) == 0) { | 6227 if (setjmp(*jump.Set()) == 0) { |
| 6180 Thread* thread = Thread::Current(); | 6228 Thread* thread = Thread::Current(); |
| 6181 Zone* zone_ = thread->zone(); | 6229 Zone* zone_ = thread->zone(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6280 thread->clear_sticky_error(); | 6328 thread->clear_sticky_error(); |
| 6281 return error.raw(); | 6329 return error.raw(); |
| 6282 } | 6330 } |
| 6283 } | 6331 } |
| 6284 | 6332 |
| 6285 | 6333 |
| 6286 } // namespace kernel | 6334 } // namespace kernel |
| 6287 } // namespace dart | 6335 } // namespace dart |
| 6288 | 6336 |
| 6289 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6337 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |