Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/ast_printer.h" | |
|
srdjan
2014/09/05 19:32:10
Remove?
Michael Lippautz (Google)
2014/09/05 19:50:18
Done.
| |
| 9 #include "vm/ast_transformer.h" | 10 #include "vm/ast_transformer.h" |
| 10 #include "vm/bootstrap.h" | 11 #include "vm/bootstrap.h" |
| 11 #include "vm/class_finalizer.h" | 12 #include "vm/class_finalizer.h" |
| 12 #include "vm/compiler.h" | 13 #include "vm/compiler.h" |
| 13 #include "vm/compiler_stats.h" | 14 #include "vm/compiler_stats.h" |
| 14 #include "vm/dart_api_impl.h" | 15 #include "vm/dart_api_impl.h" |
| 15 #include "vm/dart_entry.h" | 16 #include "vm/dart_entry.h" |
| 16 #include "vm/flags.h" | 17 #include "vm/flags.h" |
| 17 #include "vm/growable_array.h" | 18 #include "vm/growable_array.h" |
| 18 #include "vm/handles.h" | 19 #include "vm/handles.h" |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 216 set_saved_entry_context_var(context_var); | 217 set_saved_entry_context_var(context_var); |
| 217 } | 218 } |
| 218 } | 219 } |
| 219 | 220 |
| 220 // Frame indices are relative to the frame pointer and are decreasing. | 221 // Frame indices are relative to the frame pointer and are decreasing. |
| 221 ASSERT(next_free_frame_index <= first_stack_local_index_); | 222 ASSERT(next_free_frame_index <= first_stack_local_index_); |
| 222 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; | 223 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; |
| 223 } | 224 } |
| 224 | 225 |
| 225 | 226 |
| 227 struct CatchParamDesc { | |
| 228 CatchParamDesc() | |
| 229 : token_pos(0), type(NULL), name(NULL), var(NULL) { } | |
| 230 intptr_t token_pos; | |
| 231 const AbstractType* type; | |
| 232 const String* name; | |
| 233 LocalVariable* var; | |
| 234 }; | |
| 235 | |
| 236 | |
| 226 struct Parser::Block : public ZoneAllocated { | 237 struct Parser::Block : public ZoneAllocated { |
| 227 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) | 238 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) |
| 228 : parent(outer_block), scope(local_scope), statements(seq) { | 239 : parent(outer_block), scope(local_scope), statements(seq) { |
| 229 ASSERT(scope != NULL); | 240 ASSERT(scope != NULL); |
| 230 ASSERT(statements != NULL); | 241 ASSERT(statements != NULL); |
| 231 } | 242 } |
| 232 Block* parent; // Enclosing block, or NULL if outermost. | 243 Block* parent; // Enclosing block, or NULL if outermost. |
| 233 LocalScope* scope; | 244 LocalScope* scope; |
| 234 SequenceNode* statements; | 245 SequenceNode* statements; |
| 235 }; | 246 }; |
| (...skipping 2751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2987 } | 2998 } |
| 2988 ASSERT((CurrentToken() == Token::kLPAREN) || | 2999 ASSERT((CurrentToken() == Token::kLPAREN) || |
| 2989 func.IsGetterFunction() || | 3000 func.IsGetterFunction() || |
| 2990 func.is_async_closure()); | 3001 func.is_async_closure()); |
| 2991 const bool allow_explicit_default_values = true; | 3002 const bool allow_explicit_default_values = true; |
| 2992 if (func.IsGetterFunction()) { | 3003 if (func.IsGetterFunction()) { |
| 2993 // Populate function scope with the formal parameters. Since in this case | 3004 // Populate function scope with the formal parameters. Since in this case |
| 2994 // we are compiling a getter this will at most populate the receiver. | 3005 // we are compiling a getter this will at most populate the receiver. |
| 2995 AddFormalParamsToScope(¶ms, current_block_->scope); | 3006 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 2996 } else if (func.is_async_closure()) { | 3007 } else if (func.is_async_closure()) { |
| 2997 // Async closures have one optional parameter for continuation results. | 3008 // Async closures have two optional parameters: |
| 3009 // * A continuation result. | |
| 3010 // * A continuation error. | |
| 3011 // | |
| 3012 // If the error!=null we rethrow the error at the next await. | |
| 3013 const Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType()); | |
| 2998 ParamDesc result_param; | 3014 ParamDesc result_param; |
| 2999 result_param.name = &Symbols::AsyncOperationParam(); | 3015 result_param.name = &Symbols::AsyncOperationParam(); |
| 3000 result_param.default_value = &Object::null_instance(); | 3016 result_param.default_value = &Object::null_instance(); |
| 3001 result_param.type = &Type::ZoneHandle(I, Type::DynamicType()); | 3017 result_param.type = &dynamic_type; |
| 3018 ParamDesc error_param; | |
| 3019 error_param.name = &Symbols::AsyncOperationErrorParam(); | |
| 3020 error_param.default_value = &Object::null_instance(); | |
| 3021 error_param.type = &dynamic_type; | |
| 3002 params.parameters->Add(result_param); | 3022 params.parameters->Add(result_param); |
| 3003 params.num_optional_parameters++; | 3023 params.parameters->Add(error_param); |
| 3024 params.num_optional_parameters += 2; | |
| 3004 params.has_optional_positional_parameters = true; | 3025 params.has_optional_positional_parameters = true; |
| 3005 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 3026 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 3006 AddFormalParamsToScope(¶ms, current_block_->scope); | 3027 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 3007 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 3028 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 3008 ASSERT(func.NumParameters() == params.parameters->length()); | 3029 ASSERT(func.NumParameters() == params.parameters->length()); |
| 3009 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { | 3030 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { |
| 3010 // Parse away any formal parameters, as they are accessed as as context | 3031 // Parse away any formal parameters, as they are accessed as as context |
| 3011 // variables. | 3032 // variables. |
| 3012 ParamList parse_away; | 3033 ParamList parse_away; |
| 3013 ParseFormalParameterList(allow_explicit_default_values, | 3034 ParseFormalParameterList(allow_explicit_default_values, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3055 } | 3076 } |
| 3056 | 3077 |
| 3057 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 3078 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
| 3058 func.set_modifier(func_modifier); | 3079 func.set_modifier(func_modifier); |
| 3059 | 3080 |
| 3060 OpenBlock(); // Open a nested scope for the outermost function block. | 3081 OpenBlock(); // Open a nested scope for the outermost function block. |
| 3061 | 3082 |
| 3062 Function& async_closure = Function::ZoneHandle(I); | 3083 Function& async_closure = Function::ZoneHandle(I); |
| 3063 if (func.IsAsyncFunction() && !func.is_async_closure()) { | 3084 if (func.IsAsyncFunction() && !func.is_async_closure()) { |
| 3064 async_closure = OpenAsyncFunction(formal_params_pos); | 3085 async_closure = OpenAsyncFunction(formal_params_pos); |
| 3065 async_temp_scope_ = current_block_->scope; | |
| 3066 } else if (func.is_async_closure()) { | 3086 } else if (func.is_async_closure()) { |
| 3067 OpenAsyncClosure(); | 3087 OpenAsyncClosure(); |
| 3068 async_temp_scope_ = current_block_->scope; | |
| 3069 } | 3088 } |
| 3070 | 3089 |
| 3071 bool saved_await_is_keyword = await_is_keyword_; | 3090 bool saved_await_is_keyword = await_is_keyword_; |
| 3072 if (func.IsAsyncFunction() || func.is_async_closure()) { | 3091 if (func.IsAsyncFunction() || func.is_async_closure()) { |
| 3073 await_is_keyword_ = true; | 3092 await_is_keyword_ = true; |
| 3074 } | 3093 } |
| 3075 | 3094 |
| 3076 intptr_t end_token_pos = 0; | 3095 intptr_t end_token_pos = 0; |
| 3077 if (CurrentToken() == Token::kLBRACE) { | 3096 if (CurrentToken() == Token::kLBRACE) { |
| 3078 ConsumeToken(); | 3097 ConsumeToken(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3129 UnexpectedToken(); | 3148 UnexpectedToken(); |
| 3130 } | 3149 } |
| 3131 | 3150 |
| 3132 ASSERT(func.end_token_pos() == func.token_pos() || | 3151 ASSERT(func.end_token_pos() == func.token_pos() || |
| 3133 func.end_token_pos() == end_token_pos); | 3152 func.end_token_pos() == end_token_pos); |
| 3134 func.set_end_token_pos(end_token_pos); | 3153 func.set_end_token_pos(end_token_pos); |
| 3135 SequenceNode* body = CloseBlock(); | 3154 SequenceNode* body = CloseBlock(); |
| 3136 if (func.IsAsyncFunction() && !func.is_async_closure()) { | 3155 if (func.IsAsyncFunction() && !func.is_async_closure()) { |
| 3137 body = CloseAsyncFunction(async_closure, body); | 3156 body = CloseAsyncFunction(async_closure, body); |
| 3138 } else if (func.is_async_closure()) { | 3157 } else if (func.is_async_closure()) { |
| 3139 CloseAsyncClosure(body); | 3158 body = CloseAsyncClosure(body); |
| 3140 } | 3159 } |
| 3141 current_block_->statements->Add(body); | 3160 current_block_->statements->Add(body); |
| 3142 innermost_function_ = saved_innermost_function.raw(); | 3161 innermost_function_ = saved_innermost_function.raw(); |
| 3143 last_used_try_index_ = saved_try_index; | 3162 last_used_try_index_ = saved_try_index; |
| 3144 await_is_keyword_ = saved_await_is_keyword; | 3163 await_is_keyword_ = saved_await_is_keyword; |
| 3145 async_temp_scope_ = saved_async_temp_scope; | 3164 async_temp_scope_ = saved_async_temp_scope; |
| 3146 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); | 3165 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); |
| 3147 parsed_function()->set_async_saved_try_ctx_name( | 3166 parsed_function()->set_async_saved_try_ctx_name( |
| 3148 saved_async_saved_try_ctx_name); | 3167 saved_async_saved_try_ctx_name); |
| 3149 return CloseBlock(); | 3168 return CloseBlock(); |
| (...skipping 2388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5538 new(I) LocalScope(current_block_->scope, | 5557 new(I) LocalScope(current_block_->scope, |
| 5539 current_block_->scope->function_level() + 1, | 5558 current_block_->scope->function_level() + 1, |
| 5540 0); | 5559 0); |
| 5541 } | 5560 } |
| 5542 ChainNewBlock(outer_scope); | 5561 ChainNewBlock(outer_scope); |
| 5543 } | 5562 } |
| 5544 | 5563 |
| 5545 | 5564 |
| 5546 void Parser::OpenAsyncClosure() { | 5565 void Parser::OpenAsyncClosure() { |
| 5547 TRACE_PARSER("OpenAsyncClosure"); | 5566 TRACE_PARSER("OpenAsyncClosure"); |
| 5567 | |
| 5568 async_temp_scope_ = current_block_->scope; | |
| 5569 | |
| 5570 OpenAsyncTryBlock(); | |
| 5548 } | 5571 } |
| 5549 | 5572 |
| 5550 | 5573 |
| 5574 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { | |
| 5575 try_blocks_list_->enter_catch(); | |
| 5576 | |
| 5577 OpenBlock(); | |
| 5578 OpenBlock(); | |
| 5579 const AbstractType& dynamic_type = | |
| 5580 AbstractType::ZoneHandle(I, Type::DynamicType()); | |
| 5581 CatchParamDesc exception_param; | |
| 5582 CatchParamDesc stack_trace_param; | |
| 5583 exception_param.token_pos = Scanner::kNoSourcePos; | |
| 5584 exception_param.type = &dynamic_type; | |
| 5585 exception_param.name = &Symbols::ExceptionParameter(); | |
| 5586 stack_trace_param.token_pos = Scanner::kNoSourcePos; | |
| 5587 stack_trace_param.type = &dynamic_type; | |
| 5588 stack_trace_param.name = &Symbols::StackTraceParameter(); | |
| 5589 | |
| 5590 AddCatchParamsToScope( | |
| 5591 &exception_param, &stack_trace_param, current_block_->scope); | |
| 5592 | |
| 5593 LocalVariable* context_var = current_block_->scope->LookupVariable( | |
| 5594 Symbols::SavedTryContextVar(), false); | |
| 5595 ASSERT(context_var != NULL); | |
| 5596 LocalVariable* exception_var = current_block_->scope->LookupVariable( | |
| 5597 Symbols::ExceptionVar(), false); | |
| 5598 if (exception_param.var != NULL) { | |
| 5599 // Generate code to load the exception object (:exception_var) into | |
| 5600 // the exception variable specified in this block. | |
| 5601 ASSERT(exception_var != NULL); | |
| 5602 current_block_->statements->Add(new(I) StoreLocalNode( | |
| 5603 Scanner::kNoSourcePos, | |
| 5604 exception_param.var, | |
| 5605 new(I) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); | |
| 5606 } | |
| 5607 LocalVariable* stack_trace_var = | |
| 5608 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false); | |
| 5609 if (stack_trace_param.var != NULL) { | |
| 5610 // A stack trace variable is specified in this block, so generate code | |
| 5611 // to load the stack trace object (:stack_trace_var) into the stack | |
| 5612 // trace variable specified in this block. | |
| 5613 ArgumentListNode* no_args = new(I) ArgumentListNode(Scanner::kNoSourcePos); | |
| 5614 ASSERT(stack_trace_var != NULL); | |
| 5615 current_block_->statements->Add(new(I) StoreLocalNode( | |
| 5616 Scanner::kNoSourcePos, | |
| 5617 stack_trace_param.var, | |
| 5618 new(I) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); | |
| 5619 current_block_->statements->Add(new(I) InstanceCallNode( | |
| 5620 Scanner::kNoSourcePos, | |
| 5621 new(I) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var), | |
| 5622 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), | |
| 5623 no_args)); | |
| 5624 } | |
| 5625 | |
| 5626 ASSERT(try_blocks_list_ != NULL); | |
| 5627 if (innermost_function().is_async_closure() || | |
| 5628 innermost_function().IsAsyncFunction()) { | |
| 5629 if ((try_blocks_list_->outer_try_block() != NULL) && | |
| 5630 (try_blocks_list_->outer_try_block()->try_block() | |
| 5631 ->scope->function_level() == | |
| 5632 current_block_->scope->function_level())) { | |
| 5633 // We need to unchain three scope levels: catch clause, catch | |
| 5634 // parameters, and the general try block. | |
| 5635 RestoreSavedTryContext( | |
| 5636 current_block_->scope->parent()->parent()->parent(), | |
| 5637 try_blocks_list_->outer_try_block()->try_index(), | |
| 5638 current_block_->statements); | |
| 5639 } else { | |
| 5640 parsed_function()->reset_saved_try_ctx_vars(); | |
| 5641 } | |
| 5642 } | |
| 5643 | |
| 5644 // Complete the async future with an error. | |
| 5645 // Since we control the catch block there is no need to generate a nested | |
| 5646 // if/then/else. | |
| 5647 LocalVariable* async_completer = current_block_->scope->LookupVariable( | |
| 5648 Symbols::AsyncCompleter(), false); | |
| 5649 ASSERT(async_completer != NULL); | |
| 5650 ArgumentListNode* completer_args = | |
| 5651 new (I) ArgumentListNode(Scanner::kNoSourcePos); | |
| 5652 completer_args->Add( | |
| 5653 new (I) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); | |
| 5654 completer_args->Add( | |
| 5655 new (I) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var)); | |
| 5656 current_block_->statements->Add(new (I) InstanceCallNode( | |
| 5657 Scanner::kNoSourcePos, | |
| 5658 new (I) LoadLocalNode(Scanner::kNoSourcePos, async_completer), | |
| 5659 Symbols::CompleterCompleteError(), | |
| 5660 completer_args)); | |
| 5661 ReturnNode* return_node = new (I) ReturnNode(Scanner::kNoSourcePos); | |
| 5662 // Behavior like a continuation return, i.e,. don't call a completer. | |
| 5663 return_node->set_return_type(ReturnNode::kContinuation); | |
| 5664 current_block_->statements->Add(return_node); | |
| 5665 AstNode* catch_block = CloseBlock(); | |
| 5666 current_block_->statements->Add(catch_block); | |
| 5667 SequenceNode* catch_handler_list = CloseBlock(); | |
| 5668 | |
| 5669 const GrowableObjectArray& handler_types = | |
| 5670 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | |
| 5671 handler_types.SetLength(0); | |
| 5672 handler_types.Add(*exception_param.type); | |
| 5673 | |
| 5674 TryBlocks* inner_try_block = PopTryBlock(); | |
| 5675 const intptr_t try_index = inner_try_block->try_index(); | |
| 5676 | |
| 5677 CatchClauseNode* catch_clause = new (I) CatchClauseNode( | |
| 5678 Scanner::kNoSourcePos, | |
| 5679 catch_handler_list, | |
| 5680 Array::ZoneHandle(I, Array::MakeArray(handler_types)), | |
| 5681 context_var, | |
| 5682 exception_var, | |
| 5683 stack_trace_var, | |
| 5684 CatchClauseNode::kInvalidTryIndex, | |
| 5685 true); | |
| 5686 AstNode* try_catch_node = new (I) TryCatchNode( | |
| 5687 Scanner::kNoSourcePos, | |
| 5688 try_block, | |
| 5689 context_var, | |
| 5690 catch_clause, | |
| 5691 NULL, | |
| 5692 try_index); | |
| 5693 current_block_->statements->Add(try_catch_node); | |
| 5694 return CloseBlock(); | |
| 5695 } | |
| 5696 | |
| 5697 | |
| 5698 void Parser::OpenAsyncTryBlock() { | |
| 5699 // Manually wrapping the actual body into a try/catch block. | |
| 5700 LocalVariable* context_var = | |
| 5701 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | |
| 5702 if (context_var == NULL) { | |
| 5703 context_var = new(I) LocalVariable( | |
| 5704 TokenPos(), | |
| 5705 Symbols::SavedTryContextVar(), | |
| 5706 Type::ZoneHandle(I, Type::DynamicType())); | |
| 5707 current_block_->scope->AddVariable(context_var); | |
| 5708 } | |
| 5709 LocalVariable* exception_var = | |
| 5710 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); | |
| 5711 if (exception_var == NULL) { | |
| 5712 exception_var = new(I) LocalVariable( | |
| 5713 TokenPos(), | |
| 5714 Symbols::ExceptionVar(), | |
| 5715 Type::ZoneHandle(I, Type::DynamicType())); | |
| 5716 current_block_->scope->AddVariable(exception_var); | |
| 5717 } | |
| 5718 LocalVariable* stack_trace_var = | |
| 5719 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); | |
| 5720 if (stack_trace_var == NULL) { | |
| 5721 stack_trace_var = new(I) LocalVariable( | |
| 5722 TokenPos(), | |
| 5723 Symbols::StackTraceVar(), | |
| 5724 Type::ZoneHandle(I, Type::DynamicType())); | |
| 5725 current_block_->scope->AddVariable(stack_trace_var); | |
| 5726 } | |
| 5727 | |
| 5728 // Open the try block. | |
| 5729 OpenBlock(); | |
| 5730 PushTryBlock(current_block_); | |
| 5731 | |
| 5732 if (innermost_function().is_async_closure() || | |
| 5733 innermost_function().IsAsyncFunction()) { | |
| 5734 SetupSavedTryContext(context_var); | |
| 5735 } | |
| 5736 } | |
| 5737 | |
| 5738 | |
| 5551 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) { | 5739 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) { |
| 5552 TRACE_PARSER("OpenAsyncFunction"); | 5740 TRACE_PARSER("OpenAsyncFunction"); |
| 5553 | 5741 |
| 5554 AddAsyncClosureVariables(); | 5742 AddAsyncClosureVariables(); |
| 5555 | 5743 |
| 5556 // Create the closure containing the old body of this function. | 5744 // Create the closure containing the old body of this function. |
| 5557 Class& sig_cls = Class::ZoneHandle(I); | 5745 Class& sig_cls = Class::ZoneHandle(I); |
| 5558 Type& sig_type = Type::ZoneHandle(I); | 5746 Type& sig_type = Type::ZoneHandle(I); |
| 5559 Function& closure = Function::ZoneHandle(I); | 5747 Function& closure = Function::ZoneHandle(I); |
| 5560 String& sig = String::ZoneHandle(I); | 5748 String& sig = String::ZoneHandle(I); |
| 5561 ParamList closure_params; | 5749 ParamList closure_params; |
| 5750 const Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType()); | |
| 5562 closure_params.AddFinalParameter( | 5751 closure_params.AddFinalParameter( |
| 5563 formal_param_pos, | 5752 formal_param_pos, &Symbols::ClosureParameter(), &dynamic_type); |
| 5564 &Symbols::ClosureParameter(), | |
| 5565 &Type::ZoneHandle(I, Type::DynamicType())); | |
| 5566 ParamDesc result_param; | 5753 ParamDesc result_param; |
| 5567 result_param.name = &Symbols::AsyncOperationParam(); | 5754 result_param.name = &Symbols::AsyncOperationParam(); |
| 5568 result_param.default_value = &Object::null_instance(); | 5755 result_param.default_value = &Object::null_instance(); |
| 5569 result_param.type = &Type::ZoneHandle(I, Type::DynamicType()); | 5756 result_param.type = &dynamic_type; |
| 5757 ParamDesc error_param; | |
| 5758 error_param.name = &Symbols::AsyncOperationErrorParam(); | |
| 5759 error_param.default_value = &Object::null_instance(); | |
| 5760 error_param.type = &dynamic_type; | |
| 5570 closure_params.parameters->Add(result_param); | 5761 closure_params.parameters->Add(result_param); |
| 5762 closure_params.parameters->Add(error_param); | |
| 5571 closure_params.has_optional_positional_parameters = true; | 5763 closure_params.has_optional_positional_parameters = true; |
| 5572 closure_params.num_optional_parameters++; | 5764 closure_params.num_optional_parameters += 2; |
| 5573 closure = Function::NewClosureFunction( | 5765 closure = Function::NewClosureFunction( |
| 5574 Symbols::AnonymousClosure(), | 5766 Symbols::AnonymousClosure(), |
| 5575 innermost_function(), | 5767 innermost_function(), |
| 5576 formal_param_pos); | 5768 formal_param_pos); |
| 5577 AddFormalParamsToFunction(&closure_params, closure); | 5769 AddFormalParamsToFunction(&closure_params, closure); |
| 5578 closure.set_is_async_closure(true); | 5770 closure.set_is_async_closure(true); |
| 5579 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); | 5771 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); |
| 5580 sig = closure.Signature(); | 5772 sig = closure.Signature(); |
| 5581 sig_cls = library_.LookupLocalClass(sig); | 5773 sig_cls = library_.LookupLocalClass(sig); |
| 5582 if (sig_cls.IsNull()) { | 5774 if (sig_cls.IsNull()) { |
| 5583 sig_cls = Class::NewSignatureClass(sig, closure, script_, formal_param_pos); | 5775 sig_cls = Class::NewSignatureClass(sig, closure, script_, formal_param_pos); |
| 5584 library_.AddClass(sig_cls); | 5776 library_.AddClass(sig_cls); |
| 5585 } | 5777 } |
| 5586 closure.set_signature_class(sig_cls); | 5778 closure.set_signature_class(sig_cls); |
| 5587 sig_type = sig_cls.SignatureType(); | 5779 sig_type = sig_cls.SignatureType(); |
| 5588 if (!sig_type.IsFinalized()) { | 5780 if (!sig_type.IsFinalized()) { |
| 5589 ClassFinalizer::FinalizeType( | 5781 ClassFinalizer::FinalizeType( |
| 5590 sig_cls, sig_type, ClassFinalizer::kCanonicalize); | 5782 sig_cls, sig_type, ClassFinalizer::kCanonicalize); |
| 5591 } | 5783 } |
| 5592 ASSERT(AbstractType::Handle(I, closure.result_type()).IsResolved()); | 5784 ASSERT(AbstractType::Handle(I, closure.result_type()).IsResolved()); |
| 5593 ASSERT(closure.NumParameters() == closure_params.parameters->length()); | 5785 ASSERT(closure.NumParameters() == closure_params.parameters->length()); |
| 5594 OpenFunctionBlock(closure); | 5786 OpenFunctionBlock(closure); |
| 5595 AddFormalParamsToScope(&closure_params, current_block_->scope); | 5787 AddFormalParamsToScope(&closure_params, current_block_->scope); |
| 5596 OpenBlock(); | 5788 OpenBlock(); |
| 5789 | |
| 5790 async_temp_scope_ = current_block_->scope; | |
| 5791 | |
| 5597 return closure.raw(); | 5792 return closure.raw(); |
| 5598 } | 5793 } |
| 5599 | 5794 |
| 5600 | 5795 |
| 5601 void Parser::AddAsyncClosureVariables() { | 5796 void Parser::AddAsyncClosureVariables() { |
| 5602 // Add to AST: | 5797 // Add to AST: |
| 5603 // var :await_jump_var; | 5798 // var :await_jump_var; |
| 5604 // var :await_ctx_var; | 5799 // var :await_ctx_var; |
| 5605 // var :async_op; | 5800 // var :async_op; |
| 5606 // var :async_completer; | 5801 // var :async_completer; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5730 Scanner::kNoSourcePos, | 5925 Scanner::kNoSourcePos, |
| 5731 new (I) LoadLocalNode( | 5926 new (I) LoadLocalNode( |
| 5732 Scanner::kNoSourcePos, | 5927 Scanner::kNoSourcePos, |
| 5733 async_completer), | 5928 async_completer), |
| 5734 Symbols::CompleterFuture())); | 5929 Symbols::CompleterFuture())); |
| 5735 current_block_->statements->Add(return_node); | 5930 current_block_->statements->Add(return_node); |
| 5736 return CloseBlock(); | 5931 return CloseBlock(); |
| 5737 } | 5932 } |
| 5738 | 5933 |
| 5739 | 5934 |
| 5740 void Parser::CloseAsyncClosure(SequenceNode* body) { | 5935 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) { |
| 5741 TRACE_PARSER("CloseAsyncClosure"); | 5936 TRACE_PARSER("CloseAsyncClosure"); |
| 5937 | |
| 5742 // We need a temporary expression to store intermediate return values. | 5938 // We need a temporary expression to store intermediate return values. |
| 5743 parsed_function()->EnsureExpressionTemp(); | 5939 parsed_function()->EnsureExpressionTemp(); |
| 5744 // Implicitly mark those variables below as captured. We currently mark all | 5940 // Implicitly mark those variables below as captured. We currently mark all |
| 5745 // variables of all scopes as captured (below), but as soon as we do something | 5941 // variables of all scopes as captured (below), but as soon as we do something |
| 5746 // smarter we rely on these internal variables to be available. | 5942 // smarter we rely on these internal variables to be available. |
| 5747 body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); | 5943 SequenceNode* new_body = CloseAsyncTryBlock(body); |
| 5748 body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); | 5944 ASSERT(new_body != NULL); |
| 5749 body->scope()->LookupVariable(Symbols::AsyncCompleter(), false); | 5945 ASSERT(new_body->scope() != NULL); |
| 5750 body->scope()->RecursivelyCaptureAllVariables(); | 5946 new_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 5947 new_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); | |
| 5948 new_body->scope()->LookupVariable(Symbols::AsyncCompleter(), false); | |
| 5949 new_body->scope()->RecursivelyCaptureAllVariables(); | |
| 5950 return new_body; | |
| 5751 } | 5951 } |
| 5752 | 5952 |
| 5753 | 5953 |
| 5754 // Set up default values for all optional parameters to the function. | 5954 // Set up default values for all optional parameters to the function. |
| 5755 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, | 5955 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, |
| 5756 Array* default_values) { | 5956 Array* default_values) { |
| 5757 if (params->num_optional_parameters > 0) { | 5957 if (params->num_optional_parameters > 0) { |
| 5758 // Build array of default parameter values. | 5958 // Build array of default parameter values. |
| 5759 ParamDesc* param = | 5959 ParamDesc* param = |
| 5760 params->parameters->data() + params->num_fixed_parameters; | 5960 params->parameters->data() + params->num_fixed_parameters; |
| (...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7263 condition = new(I) UnaryOpNode(condition_pos, Token::kNOT, condition); | 7463 condition = new(I) UnaryOpNode(condition_pos, Token::kNOT, condition); |
| 7264 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); | 7464 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); |
| 7265 return new(I) IfNode( | 7465 return new(I) IfNode( |
| 7266 condition_pos, | 7466 condition_pos, |
| 7267 condition, | 7467 condition, |
| 7268 NodeAsSequenceNode(condition_pos, assert_throw, NULL), | 7468 NodeAsSequenceNode(condition_pos, assert_throw, NULL), |
| 7269 NULL); | 7469 NULL); |
| 7270 } | 7470 } |
| 7271 | 7471 |
| 7272 | 7472 |
| 7273 struct CatchParamDesc { | |
| 7274 CatchParamDesc() | |
| 7275 : token_pos(0), type(NULL), name(NULL), var(NULL) { } | |
| 7276 intptr_t token_pos; | |
| 7277 const AbstractType* type; | |
| 7278 const String* name; | |
| 7279 LocalVariable* var; | |
| 7280 }; | |
| 7281 | |
| 7282 | |
| 7283 // Populate local scope of the catch block with the catch parameters. | 7473 // Populate local scope of the catch block with the catch parameters. |
| 7284 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, | 7474 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, |
| 7285 CatchParamDesc* stack_trace_param, | 7475 CatchParamDesc* stack_trace_param, |
| 7286 LocalScope* scope) { | 7476 LocalScope* scope) { |
| 7287 if (exception_param->name != NULL) { | 7477 if (exception_param->name != NULL) { |
| 7288 LocalVariable* var = new(I) LocalVariable( | 7478 LocalVariable* var = new(I) LocalVariable( |
| 7289 exception_param->token_pos, | 7479 exception_param->token_pos, |
| 7290 *exception_param->name, | 7480 *exception_param->name, |
| 7291 *exception_param->type); | 7481 *exception_param->type); |
| 7292 var->set_is_final(); | 7482 var->set_is_final(); |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7576 type_tests.RemoveLast(); | 7766 type_tests.RemoveLast(); |
| 7577 current_block_->statements->Add(catch_blocks.RemoveLast()); | 7767 current_block_->statements->Add(catch_blocks.RemoveLast()); |
| 7578 current = CloseBlock(); | 7768 current = CloseBlock(); |
| 7579 } | 7769 } |
| 7580 // If the last body was entered conditionally and there is no need to add | 7770 // If the last body was entered conditionally and there is no need to add |
| 7581 // a rethrow, use an empty else body (current = NULL above). | 7771 // a rethrow, use an empty else body (current = NULL above). |
| 7582 | 7772 |
| 7583 while (!type_tests.is_empty()) { | 7773 while (!type_tests.is_empty()) { |
| 7584 AstNode* type_test = type_tests.RemoveLast(); | 7774 AstNode* type_test = type_tests.RemoveLast(); |
| 7585 SequenceNode* catch_block = catch_blocks.RemoveLast(); | 7775 SequenceNode* catch_block = catch_blocks.RemoveLast(); |
| 7776 | |
| 7777 // In case of async closures we need to restore the saved try index of an | |
| 7778 // outer try block (if it exists). | |
| 7779 ASSERT(try_blocks_list_ != NULL); | |
| 7780 if (innermost_function().is_async_closure() || | |
| 7781 innermost_function().IsAsyncFunction()) { | |
| 7782 if ((try_blocks_list_->outer_try_block() != NULL) && | |
| 7783 (try_blocks_list_->outer_try_block()->try_block() | |
| 7784 ->scope->function_level() == | |
| 7785 current_block_->scope->function_level())) { | |
| 7786 // We need to unchain three scope levels: catch clause, catch | |
| 7787 // parameters, and the general try block. | |
| 7788 RestoreSavedTryContext( | |
| 7789 current_block_->scope->parent()->parent(), | |
| 7790 try_blocks_list_->outer_try_block()->try_index(), | |
| 7791 current_block_->statements); | |
| 7792 } else { | |
| 7793 parsed_function()->reset_saved_try_ctx_vars(); | |
| 7794 } | |
| 7795 } | |
| 7796 | |
| 7586 current_block_->statements->Add(new(I) IfNode( | 7797 current_block_->statements->Add(new(I) IfNode( |
| 7587 type_test->token_pos(), type_test, catch_block, current)); | 7798 type_test->token_pos(), type_test, catch_block, current)); |
| 7588 current = CloseBlock(); | 7799 current = CloseBlock(); |
| 7589 } | 7800 } |
| 7590 return current; | 7801 return current; |
| 7591 } | 7802 } |
| 7592 | 7803 |
| 7593 | 7804 |
| 7594 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { | 7805 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { |
| 7595 const String& async_saved_try_ctx_name = | 7806 const String& async_saved_try_ctx_name = |
| (...skipping 3968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11564 void Parser::SkipQualIdent() { | 11775 void Parser::SkipQualIdent() { |
| 11565 ASSERT(IsIdentifier()); | 11776 ASSERT(IsIdentifier()); |
| 11566 ConsumeToken(); | 11777 ConsumeToken(); |
| 11567 if (CurrentToken() == Token::kPERIOD) { | 11778 if (CurrentToken() == Token::kPERIOD) { |
| 11568 ConsumeToken(); // Consume the kPERIOD token. | 11779 ConsumeToken(); // Consume the kPERIOD token. |
| 11569 ExpectIdentifier("identifier expected after '.'"); | 11780 ExpectIdentifier("identifier expected after '.'"); |
| 11570 } | 11781 } |
| 11571 } | 11782 } |
| 11572 | 11783 |
| 11573 } // namespace dart | 11784 } // namespace dart |
| OLD | NEW |