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

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

Issue 542893004: Bubble up exceptions throw async/await. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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"
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
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
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(&params, current_block_->scope); 3006 AddFormalParamsToScope(&params, 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 one optional parameter for continuation results.
hausner 2014/09/05 17:52:26 This comment is no longer correct I think.
Michael Lippautz (Google) 2014/09/05 18:03:29 Done.
3009 const Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType());
2998 ParamDesc result_param; 3010 ParamDesc result_param;
2999 result_param.name = &Symbols::AsyncOperationParam(); 3011 result_param.name = &Symbols::AsyncOperationParam();
3000 result_param.default_value = &Object::null_instance(); 3012 result_param.default_value = &Object::null_instance();
3001 result_param.type = &Type::ZoneHandle(I, Type::DynamicType()); 3013 result_param.type = &dynamic_type;
3014 ParamDesc error_param;
3015 error_param.name = &Symbols::AsyncOperationErrorParam();
3016 error_param.default_value = &Object::null_instance();
3017 error_param.type = &dynamic_type;
3002 params.parameters->Add(result_param); 3018 params.parameters->Add(result_param);
3003 params.num_optional_parameters++; 3019 params.parameters->Add(error_param);
3020 params.num_optional_parameters += 2;
3004 params.has_optional_positional_parameters = true; 3021 params.has_optional_positional_parameters = true;
3005 SetupDefaultsForOptionalParams(&params, default_parameter_values); 3022 SetupDefaultsForOptionalParams(&params, default_parameter_values);
3006 AddFormalParamsToScope(&params, current_block_->scope); 3023 AddFormalParamsToScope(&params, current_block_->scope);
3007 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); 3024 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved());
3008 ASSERT(func.NumParameters() == params.parameters->length()); 3025 ASSERT(func.NumParameters() == params.parameters->length());
3009 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { 3026 if (!Function::Handle(func.parent_function()).IsGetterFunction()) {
3010 // Parse away any formal parameters, as they are accessed as as context 3027 // Parse away any formal parameters, as they are accessed as as context
3011 // variables. 3028 // variables.
3012 ParamList parse_away; 3029 ParamList parse_away;
3013 ParseFormalParameterList(allow_explicit_default_values, 3030 ParseFormalParameterList(allow_explicit_default_values,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3055 } 3072 }
3056 3073
3057 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); 3074 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier();
3058 func.set_modifier(func_modifier); 3075 func.set_modifier(func_modifier);
3059 3076
3060 OpenBlock(); // Open a nested scope for the outermost function block. 3077 OpenBlock(); // Open a nested scope for the outermost function block.
3061 3078
3062 Function& async_closure = Function::ZoneHandle(I); 3079 Function& async_closure = Function::ZoneHandle(I);
3063 if (func.IsAsyncFunction() && !func.is_async_closure()) { 3080 if (func.IsAsyncFunction() && !func.is_async_closure()) {
3064 async_closure = OpenAsyncFunction(formal_params_pos); 3081 async_closure = OpenAsyncFunction(formal_params_pos);
3065 async_temp_scope_ = current_block_->scope;
3066 } else if (func.is_async_closure()) { 3082 } else if (func.is_async_closure()) {
3067 OpenAsyncClosure(); 3083 OpenAsyncClosure();
3068 async_temp_scope_ = current_block_->scope;
3069 } 3084 }
3070 3085
3071 bool saved_await_is_keyword = await_is_keyword_; 3086 bool saved_await_is_keyword = await_is_keyword_;
3072 if (func.IsAsyncFunction() || func.is_async_closure()) { 3087 if (func.IsAsyncFunction() || func.is_async_closure()) {
3073 await_is_keyword_ = true; 3088 await_is_keyword_ = true;
3074 } 3089 }
3075 3090
3076 intptr_t end_token_pos = 0; 3091 intptr_t end_token_pos = 0;
3077 if (CurrentToken() == Token::kLBRACE) { 3092 if (CurrentToken() == Token::kLBRACE) {
3078 ConsumeToken(); 3093 ConsumeToken();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3129 UnexpectedToken(); 3144 UnexpectedToken();
3130 } 3145 }
3131 3146
3132 ASSERT(func.end_token_pos() == func.token_pos() || 3147 ASSERT(func.end_token_pos() == func.token_pos() ||
3133 func.end_token_pos() == end_token_pos); 3148 func.end_token_pos() == end_token_pos);
3134 func.set_end_token_pos(end_token_pos); 3149 func.set_end_token_pos(end_token_pos);
3135 SequenceNode* body = CloseBlock(); 3150 SequenceNode* body = CloseBlock();
3136 if (func.IsAsyncFunction() && !func.is_async_closure()) { 3151 if (func.IsAsyncFunction() && !func.is_async_closure()) {
3137 body = CloseAsyncFunction(async_closure, body); 3152 body = CloseAsyncFunction(async_closure, body);
3138 } else if (func.is_async_closure()) { 3153 } else if (func.is_async_closure()) {
3139 CloseAsyncClosure(body); 3154 body = CloseAsyncClosure(body);
3140 } 3155 }
3141 current_block_->statements->Add(body); 3156 current_block_->statements->Add(body);
3142 innermost_function_ = saved_innermost_function.raw(); 3157 innermost_function_ = saved_innermost_function.raw();
3143 last_used_try_index_ = saved_try_index; 3158 last_used_try_index_ = saved_try_index;
3144 await_is_keyword_ = saved_await_is_keyword; 3159 await_is_keyword_ = saved_await_is_keyword;
3145 async_temp_scope_ = saved_async_temp_scope; 3160 async_temp_scope_ = saved_async_temp_scope;
3146 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); 3161 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx);
3147 parsed_function()->set_async_saved_try_ctx_name( 3162 parsed_function()->set_async_saved_try_ctx_name(
3148 saved_async_saved_try_ctx_name); 3163 saved_async_saved_try_ctx_name);
3149 return CloseBlock(); 3164 return CloseBlock();
(...skipping 2388 matching lines...) Expand 10 before | Expand all | Expand 10 after
5538 new(I) LocalScope(current_block_->scope, 5553 new(I) LocalScope(current_block_->scope,
5539 current_block_->scope->function_level() + 1, 5554 current_block_->scope->function_level() + 1,
5540 0); 5555 0);
5541 } 5556 }
5542 ChainNewBlock(outer_scope); 5557 ChainNewBlock(outer_scope);
5543 } 5558 }
5544 5559
5545 5560
5546 void Parser::OpenAsyncClosure() { 5561 void Parser::OpenAsyncClosure() {
5547 TRACE_PARSER("OpenAsyncClosure"); 5562 TRACE_PARSER("OpenAsyncClosure");
5563
5564 async_temp_scope_ = current_block_->scope;
5565
5566 OpenAsyncTryBlock();
5548 } 5567 }
5549 5568
5550 5569
5570 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) {
5571 try_blocks_list_->enter_catch();
5572
5573 OpenBlock();
5574 OpenBlock();
5575 const AbstractType& dynamic_type =
5576 AbstractType::ZoneHandle(I, Type::DynamicType());
5577 CatchParamDesc exception_param;
5578 CatchParamDesc stack_trace_param;
5579 exception_param.token_pos = Scanner::kNoSourcePos;
5580 exception_param.type = &dynamic_type;
5581 exception_param.name = &Symbols::ExceptionParameter();
5582 stack_trace_param.token_pos = Scanner::kNoSourcePos;
5583 stack_trace_param.type = &dynamic_type;
5584 stack_trace_param.name = &Symbols::StackTraceParameter();
5585
5586 AddCatchParamsToScope(
5587 &exception_param, &stack_trace_param, current_block_->scope);
5588
5589 LocalVariable* context_var = current_block_->scope->LookupVariable(
5590 Symbols::SavedTryContextVar(), false);
5591 ASSERT(context_var != NULL);
5592 LocalVariable* exception_var = current_block_->scope->LookupVariable(
5593 Symbols::ExceptionVar(), false);
5594 if (exception_param.var != NULL) {
5595 // Generate code to load the exception object (:exception_var) into
5596 // the exception variable specified in this block.
5597 ASSERT(exception_var != NULL);
5598 current_block_->statements->Add(new(I) StoreLocalNode(
5599 Scanner::kNoSourcePos,
5600 exception_param.var,
5601 new(I) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
5602 }
5603 LocalVariable* stack_trace_var =
5604 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false);
5605 if (stack_trace_param.var != NULL) {
5606 // A stack trace variable is specified in this block, so generate code
5607 // to load the stack trace object (:stack_trace_var) into the stack
5608 // trace variable specified in this block.
5609 ArgumentListNode* no_args = new(I) ArgumentListNode(Scanner::kNoSourcePos);
5610 ASSERT(stack_trace_var != NULL);
5611 current_block_->statements->Add(new(I) StoreLocalNode(
5612 Scanner::kNoSourcePos,
5613 stack_trace_param.var,
5614 new(I) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
5615 current_block_->statements->Add(new(I) InstanceCallNode(
5616 Scanner::kNoSourcePos,
5617 new(I) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var),
5618 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()),
5619 no_args));
5620 }
5621
5622 ASSERT(try_blocks_list_ != NULL);
5623 if (innermost_function().is_async_closure() ||
5624 innermost_function().IsAsyncFunction()) {
5625 if ((try_blocks_list_->outer_try_block() != NULL) &&
5626 (try_blocks_list_->outer_try_block()->try_block()
5627 ->scope->function_level() ==
5628 current_block_->scope->function_level())) {
5629 // We need to unchain three scope levels: catch clause, catch
5630 // parameters, and the general try block.
5631 RestoreSavedTryContext(
5632 current_block_->scope->parent()->parent()->parent(),
5633 try_blocks_list_->outer_try_block()->try_index(),
5634 current_block_->statements);
5635 } else {
5636 parsed_function()->reset_saved_try_ctx_vars();
5637 }
5638 }
5639
5640 // Complete the async future with an error.
5641 // Since we control the catch block there is no need to generate a nested
5642 // if/then/else.
5643 LocalVariable* async_completer = current_block_->scope->LookupVariable(
5644 Symbols::AsyncCompleter(), false);
5645 ASSERT(async_completer != NULL);
5646 ArgumentListNode* completer_args =
5647 new (I) ArgumentListNode(Scanner::kNoSourcePos);
5648 completer_args->Add(
5649 new (I) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var));
5650 completer_args->Add(
5651 new (I) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var));
5652 current_block_->statements->Add(new (I) InstanceCallNode(
5653 Scanner::kNoSourcePos,
5654 new (I) LoadLocalNode(Scanner::kNoSourcePos, async_completer),
5655 Symbols::CompleterCompleteError(),
5656 completer_args));
5657 ReturnNode* return_node = new (I) ReturnNode(Scanner::kNoSourcePos);
5658 // Behavior like a continuation return, i.e,. don't call a completer.
5659 return_node->set_return_type(ReturnNode::kContinuation);
5660 current_block_->statements->Add(return_node);
5661 AstNode* catch_block = CloseBlock();
5662 current_block_->statements->Add(catch_block);
5663 SequenceNode* catch_handler_list = CloseBlock();
5664
5665 const GrowableObjectArray& handler_types =
5666 GrowableObjectArray::Handle(I, GrowableObjectArray::New());
5667 handler_types.SetLength(0);
5668 handler_types.Add(*exception_param.type);
5669
5670 TryBlocks* inner_try_block = PopTryBlock();
5671 const intptr_t try_index = inner_try_block->try_index();
5672
5673 CatchClauseNode* catch_clause = new (I) CatchClauseNode(
5674 Scanner::kNoSourcePos,
5675 catch_handler_list,
5676 Array::ZoneHandle(I, Array::MakeArray(handler_types)),
5677 context_var,
5678 exception_var,
5679 stack_trace_var,
5680 CatchClauseNode::kInvalidTryIndex,
5681 true);
5682 AstNode* try_catch_node = new (I) TryCatchNode(
5683 Scanner::kNoSourcePos,
5684 try_block,
5685 context_var,
5686 catch_clause,
5687 NULL,
5688 try_index);
5689 current_block_->statements->Add(try_catch_node);
5690 return CloseBlock();
5691 }
5692
5693
5694 void Parser::OpenAsyncTryBlock() {
5695 // Manually wrapping the actual body into a try/catch block.
5696 LocalVariable* context_var =
5697 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar());
5698 if (context_var == NULL) {
5699 context_var = new(I) LocalVariable(
5700 TokenPos(),
5701 Symbols::SavedTryContextVar(),
5702 Type::ZoneHandle(I, Type::DynamicType()));
5703 current_block_->scope->AddVariable(context_var);
5704 }
5705 LocalVariable* exception_var =
5706 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar());
5707 if (exception_var == NULL) {
5708 exception_var = new(I) LocalVariable(
5709 TokenPos(),
5710 Symbols::ExceptionVar(),
5711 Type::ZoneHandle(I, Type::DynamicType()));
5712 current_block_->scope->AddVariable(exception_var);
5713 }
5714 LocalVariable* stack_trace_var =
5715 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar());
5716 if (stack_trace_var == NULL) {
5717 stack_trace_var = new(I) LocalVariable(
5718 TokenPos(),
5719 Symbols::StackTraceVar(),
5720 Type::ZoneHandle(I, Type::DynamicType()));
5721 current_block_->scope->AddVariable(stack_trace_var);
5722 }
5723
5724 // Open the try block.
5725 OpenBlock();
5726 PushTryBlock(current_block_);
5727
5728 if (innermost_function().is_async_closure() ||
5729 innermost_function().IsAsyncFunction()) {
5730 SetupSavedTryContext(context_var);
5731 }
5732 }
5733
5734
5551 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) { 5735 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) {
5552 TRACE_PARSER("OpenAsyncFunction"); 5736 TRACE_PARSER("OpenAsyncFunction");
5553 5737
5554 AddAsyncClosureVariables(); 5738 AddAsyncClosureVariables();
5555 5739
5556 // Create the closure containing the old body of this function. 5740 // Create the closure containing the old body of this function.
5557 Class& sig_cls = Class::ZoneHandle(I); 5741 Class& sig_cls = Class::ZoneHandle(I);
5558 Type& sig_type = Type::ZoneHandle(I); 5742 Type& sig_type = Type::ZoneHandle(I);
5559 Function& closure = Function::ZoneHandle(I); 5743 Function& closure = Function::ZoneHandle(I);
5560 String& sig = String::ZoneHandle(I); 5744 String& sig = String::ZoneHandle(I);
5561 ParamList closure_params; 5745 ParamList closure_params;
5746 const Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType());
5562 closure_params.AddFinalParameter( 5747 closure_params.AddFinalParameter(
5563 formal_param_pos, 5748 formal_param_pos, &Symbols::ClosureParameter(), &dynamic_type);
5564 &Symbols::ClosureParameter(),
5565 &Type::ZoneHandle(I, Type::DynamicType()));
5566 ParamDesc result_param; 5749 ParamDesc result_param;
5567 result_param.name = &Symbols::AsyncOperationParam(); 5750 result_param.name = &Symbols::AsyncOperationParam();
5568 result_param.default_value = &Object::null_instance(); 5751 result_param.default_value = &Object::null_instance();
5569 result_param.type = &Type::ZoneHandle(I, Type::DynamicType()); 5752 result_param.type = &dynamic_type;
5753 ParamDesc error_param;
5754 error_param.name = &Symbols::AsyncOperationErrorParam();
5755 error_param.default_value = &Object::null_instance();
5756 error_param.type = &dynamic_type;
5570 closure_params.parameters->Add(result_param); 5757 closure_params.parameters->Add(result_param);
5758 closure_params.parameters->Add(error_param);
5571 closure_params.has_optional_positional_parameters = true; 5759 closure_params.has_optional_positional_parameters = true;
5572 closure_params.num_optional_parameters++; 5760 closure_params.num_optional_parameters += 2;
5573 closure = Function::NewClosureFunction( 5761 closure = Function::NewClosureFunction(
5574 Symbols::AnonymousClosure(), 5762 Symbols::AnonymousClosure(),
5575 innermost_function(), 5763 innermost_function(),
5576 formal_param_pos); 5764 formal_param_pos);
5577 AddFormalParamsToFunction(&closure_params, closure); 5765 AddFormalParamsToFunction(&closure_params, closure);
5578 closure.set_is_async_closure(true); 5766 closure.set_is_async_closure(true);
5579 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); 5767 closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
5580 sig = closure.Signature(); 5768 sig = closure.Signature();
5581 sig_cls = library_.LookupLocalClass(sig); 5769 sig_cls = library_.LookupLocalClass(sig);
5582 if (sig_cls.IsNull()) { 5770 if (sig_cls.IsNull()) {
5583 sig_cls = Class::NewSignatureClass(sig, closure, script_, formal_param_pos); 5771 sig_cls = Class::NewSignatureClass(sig, closure, script_, formal_param_pos);
5584 library_.AddClass(sig_cls); 5772 library_.AddClass(sig_cls);
5585 } 5773 }
5586 closure.set_signature_class(sig_cls); 5774 closure.set_signature_class(sig_cls);
5587 sig_type = sig_cls.SignatureType(); 5775 sig_type = sig_cls.SignatureType();
5588 if (!sig_type.IsFinalized()) { 5776 if (!sig_type.IsFinalized()) {
5589 ClassFinalizer::FinalizeType( 5777 ClassFinalizer::FinalizeType(
5590 sig_cls, sig_type, ClassFinalizer::kCanonicalize); 5778 sig_cls, sig_type, ClassFinalizer::kCanonicalize);
5591 } 5779 }
5592 ASSERT(AbstractType::Handle(I, closure.result_type()).IsResolved()); 5780 ASSERT(AbstractType::Handle(I, closure.result_type()).IsResolved());
5593 ASSERT(closure.NumParameters() == closure_params.parameters->length()); 5781 ASSERT(closure.NumParameters() == closure_params.parameters->length());
5594 OpenFunctionBlock(closure); 5782 OpenFunctionBlock(closure);
5595 AddFormalParamsToScope(&closure_params, current_block_->scope); 5783 AddFormalParamsToScope(&closure_params, current_block_->scope);
5596 OpenBlock(); 5784 OpenBlock();
5785
5786 async_temp_scope_ = current_block_->scope;
5787
5597 return closure.raw(); 5788 return closure.raw();
5598 } 5789 }
5599 5790
5600 5791
5601 void Parser::AddAsyncClosureVariables() { 5792 void Parser::AddAsyncClosureVariables() {
5602 // Add to AST: 5793 // Add to AST:
5603 // var :await_jump_var; 5794 // var :await_jump_var;
5604 // var :await_ctx_var; 5795 // var :await_ctx_var;
5605 // var :async_op; 5796 // var :async_op;
5606 // var :async_completer; 5797 // var :async_completer;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
5730 Scanner::kNoSourcePos, 5921 Scanner::kNoSourcePos,
5731 new (I) LoadLocalNode( 5922 new (I) LoadLocalNode(
5732 Scanner::kNoSourcePos, 5923 Scanner::kNoSourcePos,
5733 async_completer), 5924 async_completer),
5734 Symbols::CompleterFuture())); 5925 Symbols::CompleterFuture()));
5735 current_block_->statements->Add(return_node); 5926 current_block_->statements->Add(return_node);
5736 return CloseBlock(); 5927 return CloseBlock();
5737 } 5928 }
5738 5929
5739 5930
5740 void Parser::CloseAsyncClosure(SequenceNode* body) { 5931 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) {
5741 TRACE_PARSER("CloseAsyncClosure"); 5932 TRACE_PARSER("CloseAsyncClosure");
5933
5742 // We need a temporary expression to store intermediate return values. 5934 // We need a temporary expression to store intermediate return values.
5743 parsed_function()->EnsureExpressionTemp(); 5935 parsed_function()->EnsureExpressionTemp();
5744 // Implicitly mark those variables below as captured. We currently mark all 5936 // 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 5937 // 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. 5938 // smarter we rely on these internal variables to be available.
5747 body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); 5939 SequenceNode* new_body = CloseAsyncTryBlock(body);
5748 body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); 5940 ASSERT(new_body != NULL);
5749 body->scope()->LookupVariable(Symbols::AsyncCompleter(), false); 5941 ASSERT(new_body->scope() != NULL);
5750 body->scope()->RecursivelyCaptureAllVariables(); 5942 new_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
5943 new_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
5944 new_body->scope()->LookupVariable(Symbols::AsyncCompleter(), false);
5945 new_body->scope()->RecursivelyCaptureAllVariables();
5946 return new_body;
5751 } 5947 }
5752 5948
5753 5949
5754 // Set up default values for all optional parameters to the function. 5950 // Set up default values for all optional parameters to the function.
5755 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, 5951 void Parser::SetupDefaultsForOptionalParams(const ParamList* params,
5756 Array* default_values) { 5952 Array* default_values) {
5757 if (params->num_optional_parameters > 0) { 5953 if (params->num_optional_parameters > 0) {
5758 // Build array of default parameter values. 5954 // Build array of default parameter values.
5759 ParamDesc* param = 5955 ParamDesc* param =
5760 params->parameters->data() + params->num_fixed_parameters; 5956 params->parameters->data() + params->num_fixed_parameters;
(...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after
7263 condition = new(I) UnaryOpNode(condition_pos, Token::kNOT, condition); 7459 condition = new(I) UnaryOpNode(condition_pos, Token::kNOT, condition);
7264 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); 7460 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end);
7265 return new(I) IfNode( 7461 return new(I) IfNode(
7266 condition_pos, 7462 condition_pos,
7267 condition, 7463 condition,
7268 NodeAsSequenceNode(condition_pos, assert_throw, NULL), 7464 NodeAsSequenceNode(condition_pos, assert_throw, NULL),
7269 NULL); 7465 NULL);
7270 } 7466 }
7271 7467
7272 7468
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. 7469 // Populate local scope of the catch block with the catch parameters.
7284 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, 7470 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param,
7285 CatchParamDesc* stack_trace_param, 7471 CatchParamDesc* stack_trace_param,
7286 LocalScope* scope) { 7472 LocalScope* scope) {
7287 if (exception_param->name != NULL) { 7473 if (exception_param->name != NULL) {
7288 LocalVariable* var = new(I) LocalVariable( 7474 LocalVariable* var = new(I) LocalVariable(
7289 exception_param->token_pos, 7475 exception_param->token_pos,
7290 *exception_param->name, 7476 *exception_param->name,
7291 *exception_param->type); 7477 *exception_param->type);
7292 var->set_is_final(); 7478 var->set_is_final();
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
7576 type_tests.RemoveLast(); 7762 type_tests.RemoveLast();
7577 current_block_->statements->Add(catch_blocks.RemoveLast()); 7763 current_block_->statements->Add(catch_blocks.RemoveLast());
7578 current = CloseBlock(); 7764 current = CloseBlock();
7579 } 7765 }
7580 // If the last body was entered conditionally and there is no need to add 7766 // 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). 7767 // a rethrow, use an empty else body (current = NULL above).
7582 7768
7583 while (!type_tests.is_empty()) { 7769 while (!type_tests.is_empty()) {
7584 AstNode* type_test = type_tests.RemoveLast(); 7770 AstNode* type_test = type_tests.RemoveLast();
7585 SequenceNode* catch_block = catch_blocks.RemoveLast(); 7771 SequenceNode* catch_block = catch_blocks.RemoveLast();
7772
7773 // In case of async closures we need to restore the saved try index of an
7774 // outer try block (if it exists).
7775 ASSERT(try_blocks_list_ != NULL);
7776 if (innermost_function().is_async_closure() ||
7777 innermost_function().IsAsyncFunction()) {
7778 if ((try_blocks_list_->outer_try_block() != NULL) &&
7779 (try_blocks_list_->outer_try_block()->try_block()
7780 ->scope->function_level() ==
7781 current_block_->scope->function_level())) {
7782 // We need to unchain three scope levels: catch clause, catch
7783 // parameters, and the general try block.
7784 RestoreSavedTryContext(
7785 current_block_->scope->parent()->parent(),
7786 try_blocks_list_->outer_try_block()->try_index(),
7787 current_block_->statements);
7788 } else {
7789 parsed_function()->reset_saved_try_ctx_vars();
7790 }
7791 }
7792
7586 current_block_->statements->Add(new(I) IfNode( 7793 current_block_->statements->Add(new(I) IfNode(
7587 type_test->token_pos(), type_test, catch_block, current)); 7794 type_test->token_pos(), type_test, catch_block, current));
7588 current = CloseBlock(); 7795 current = CloseBlock();
7589 } 7796 }
7590 return current; 7797 return current;
7591 } 7798 }
7592 7799
7593 7800
7594 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { 7801 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) {
7595 const String& async_saved_try_ctx_name = 7802 const String& async_saved_try_ctx_name =
(...skipping 3968 matching lines...) Expand 10 before | Expand all | Expand 10 after
11564 void Parser::SkipQualIdent() { 11771 void Parser::SkipQualIdent() {
11565 ASSERT(IsIdentifier()); 11772 ASSERT(IsIdentifier());
11566 ConsumeToken(); 11773 ConsumeToken();
11567 if (CurrentToken() == Token::kPERIOD) { 11774 if (CurrentToken() == Token::kPERIOD) {
11568 ConsumeToken(); // Consume the kPERIOD token. 11775 ConsumeToken(); // Consume the kPERIOD token.
11569 ExpectIdentifier("identifier expected after '.'"); 11776 ExpectIdentifier("identifier expected after '.'");
11570 } 11777 }
11571 } 11778 }
11572 11779
11573 } // namespace dart 11780 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698