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