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

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

Issue 484933003: Await it! (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase 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/scopes.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_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 5407 matching lines...) Expand 10 before | Expand all | Expand 10 after
5418 current_block_->scope->function_level() + 1, 5418 current_block_->scope->function_level() + 1,
5419 0); 5419 0);
5420 } 5420 }
5421 ChainNewBlock(outer_scope); 5421 ChainNewBlock(outer_scope);
5422 } 5422 }
5423 5423
5424 5424
5425 void Parser::OpenAsyncClosure() { 5425 void Parser::OpenAsyncClosure() {
5426 TRACE_PARSER("OpenAsyncClosure"); 5426 TRACE_PARSER("OpenAsyncClosure");
5427 parsed_function()->set_await_temps_scope(current_block_->scope); 5427 parsed_function()->set_await_temps_scope(current_block_->scope);
5428 // TODO(mlippautz): Set up explicit jump table for await continuations.
5429 } 5428 }
5430 5429
5431 5430
5432 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) { 5431 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) {
5433 TRACE_PARSER("OpenAsyncFunction"); 5432 TRACE_PARSER("OpenAsyncFunction");
5434 // Create the closure containing the old body of this function. 5433 // Create the closure containing the old body of this function.
5435 Class& sig_cls = Class::ZoneHandle(I); 5434 Class& sig_cls = Class::ZoneHandle(I);
5436 Type& sig_type = Type::ZoneHandle(I); 5435 Type& sig_type = Type::ZoneHandle(I);
5437 Function& closure = Function::ZoneHandle(I); 5436 Function& closure = Function::ZoneHandle(I);
5438 String& sig = String::ZoneHandle(I); 5437 String& sig = String::ZoneHandle(I);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
5482 // Record the begin and end token index of the scope. 5481 // Record the begin and end token index of the scope.
5483 ASSERT(statements != NULL); 5482 ASSERT(statements != NULL);
5484 current_block_->scope->set_begin_token_pos(statements->token_pos()); 5483 current_block_->scope->set_begin_token_pos(statements->token_pos());
5485 current_block_->scope->set_end_token_pos(TokenPos()); 5484 current_block_->scope->set_end_token_pos(TokenPos());
5486 } 5485 }
5487 current_block_ = current_block_->parent; 5486 current_block_ = current_block_->parent;
5488 return statements; 5487 return statements;
5489 } 5488 }
5490 5489
5491 5490
5491 static inline String& BuildAsyncSavedTryContextName(Isolate* isolate,
5492 int16_t id) {
5493 const char* async_saved_prefix = ":async_saved_try_ctx_var_";
5494 // Can be a regular handle since we only use it to build an actual symbol.
5495 const String& cnt_str = String::Handle(
5496 String::NewFormatted("%s%d", async_saved_prefix, id));
5497 return String::ZoneHandle(isolate, Symbols::New(cnt_str));
5498 }
5499
5500
5492 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, 5501 SequenceNode* Parser::CloseAsyncFunction(const Function& closure,
5493 SequenceNode* closure_body) { 5502 SequenceNode* closure_body) {
5494 TRACE_PARSER("CloseAsyncFunction"); 5503 TRACE_PARSER("CloseAsyncFunction");
5495 ASSERT(!closure.IsNull()); 5504 ASSERT(!closure.IsNull());
5496 ASSERT(closure_body != NULL); 5505 ASSERT(closure_body != NULL);
5497 // The block for the async closure body has already been closed. Close the 5506 // The block for the async closure body has already been closed. Close the
5498 // corresponding function block. 5507 // corresponding function block.
5499 CloseBlock(); 5508 CloseBlock();
5500 5509
5501 // Create and return a new future that executes a closure with the current 5510 // Create and return a new future that executes a closure with the current
5502 // body. 5511 // body.
5503 5512
5504 bool found = false;
5505
5506 // No need to capture parameters or other variables, since they have already 5513 // No need to capture parameters or other variables, since they have already
5507 // been captured in the corresponding scope as the body has been parsed within 5514 // been captured in the corresponding scope as the body has been parsed within
5508 // a nested block (contained in the async funtion's block). 5515 // a nested block (contained in the async funtion's block).
5509 const Class& future = Class::ZoneHandle(I, 5516 const Class& future = Class::ZoneHandle(I,
5510 GetClassForAsync(Symbols::Future())); 5517 GetClassForAsync(Symbols::Future()));
5511 ASSERT(!future.IsNull()); 5518 ASSERT(!future.IsNull());
5512 const Function& constructor = Function::ZoneHandle(I, 5519 const Function& constructor = Function::ZoneHandle(I,
5513 future.LookupFunction(Symbols::FutureConstructor())); 5520 future.LookupFunction(Symbols::FutureConstructor()));
5514 ASSERT(!constructor.IsNull()); 5521 ASSERT(!constructor.IsNull());
5515 const Class& completer = Class::ZoneHandle(I, 5522 const Class& completer = Class::ZoneHandle(I,
5516 GetClassForAsync(Symbols::Completer())); 5523 GetClassForAsync(Symbols::Completer()));
5517 ASSERT(!completer.IsNull()); 5524 ASSERT(!completer.IsNull());
5518 const Function& completer_constructor = Function::ZoneHandle(I, 5525 const Function& completer_constructor = Function::ZoneHandle(I,
5519 completer.LookupFunction(Symbols::CompleterConstructor())); 5526 completer.LookupFunction(Symbols::CompleterConstructor()));
5520 ASSERT(!completer_constructor.IsNull()); 5527 ASSERT(!completer_constructor.IsNull());
5521 5528
5529 bool found = false;
5522 // Add to AST: 5530 // Add to AST:
5523 // var :async_op; 5531 // var :async_op;
5524 // var :async_completer; 5532 // var :async_completer;
5533 // var :await_jump_var;
5534 // var :await_ctx_var;
5535 // Add as many variables to saved the try block ctx as there were try blocks.
5536 // var :async_saved_try_ctx_var_<x>;
5537 const Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType());
5525 LocalVariable* async_op_var = new (I) LocalVariable( 5538 LocalVariable* async_op_var = new (I) LocalVariable(
5526 Scanner::kNoSourcePos, 5539 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
5527 Symbols::AsyncOperation(),
5528 Type::ZoneHandle(I, Type::DynamicType()));
5529 current_block_->scope->AddVariable(async_op_var); 5540 current_block_->scope->AddVariable(async_op_var);
5530 found = closure_body->scope()->CaptureVariable(Symbols::AsyncOperation()); 5541 found = closure_body->scope()->CaptureVariable(Symbols::AsyncOperation());
5531 ASSERT(found); 5542 ASSERT(found);
5532 LocalVariable* async_completer = new (I) LocalVariable( 5543 LocalVariable* async_completer = new (I) LocalVariable(
5533 Scanner::kNoSourcePos, 5544 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
5534 Symbols::AsyncCompleter(),
5535 Type::ZoneHandle(I, Type::DynamicType()));
5536 current_block_->scope->AddVariable(async_completer); 5545 current_block_->scope->AddVariable(async_completer);
5537 found = closure_body->scope()->CaptureVariable(Symbols::AsyncCompleter()); 5546 found = closure_body->scope()->CaptureVariable(Symbols::AsyncCompleter());
5538 ASSERT(found); 5547 ASSERT(found);
5548 LocalVariable* await_jump_var = new (I) LocalVariable(
5549 Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type);
5550 current_block_->scope->AddVariable(await_jump_var);
5551 found = closure_body->scope()->CaptureVariable(Symbols::AwaitJumpVar());
5552 ASSERT(found);
5553 LocalVariable* await_ctx_var = new (I) LocalVariable(
5554 Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type);
5555 current_block_->scope->AddVariable(await_ctx_var);
5556 found = closure_body->scope()->CaptureVariable(Symbols::AwaitContextVar());
5557 ASSERT(found);
5558 LocalVariable* async_saved_try_ctx_var;
5559 for (int16_t i = 0; i < last_used_try_index_; i++) {
5560 String& async_saved_try_ctx_name = BuildAsyncSavedTryContextName(I, i);
5561 async_saved_try_ctx_var = new (I) LocalVariable(
5562 Scanner::kNoSourcePos, async_saved_try_ctx_name, dynamic_type);
5563 current_block_->scope->AddVariable(async_saved_try_ctx_var);
5564 found = closure_body->scope()->CaptureVariable(async_saved_try_ctx_name);
5565 ASSERT(found);
5566 }
5539 5567
5540 // Add to AST: 5568 // Add to AST:
5541 // :async_completer = new Completer(); 5569 // :async_completer = new Completer();
5542 ArgumentListNode* empty_args = new (I) ArgumentListNode( 5570 ArgumentListNode* empty_args =
5543 Scanner::kNoSourcePos); 5571 new (I) ArgumentListNode(Scanner::kNoSourcePos);
5544 ConstructorCallNode* completer_constructor_node = new (I) ConstructorCallNode( 5572 ConstructorCallNode* completer_constructor_node = new (I) ConstructorCallNode(
5545 Scanner::kNoSourcePos, 5573 Scanner::kNoSourcePos,
5546 TypeArguments::ZoneHandle(I), 5574 TypeArguments::ZoneHandle(I),
5547 completer_constructor, 5575 completer_constructor,
5548 empty_args); 5576 empty_args);
5549 StoreLocalNode* store_completer = new (I) StoreLocalNode( 5577 StoreLocalNode* store_completer = new (I) StoreLocalNode(
5550 Scanner::kNoSourcePos, 5578 Scanner::kNoSourcePos,
5551 async_completer, 5579 async_completer,
5552 completer_constructor_node); 5580 completer_constructor_node);
5553 current_block_->statements->Add(store_completer); 5581 current_block_->statements->Add(store_completer);
(...skipping 30 matching lines...) Expand all
5584 Symbols::CompleterFuture())); 5612 Symbols::CompleterFuture()));
5585 current_block_->statements->Add(return_node); 5613 current_block_->statements->Add(return_node);
5586 return CloseBlock(); 5614 return CloseBlock();
5587 } 5615 }
5588 5616
5589 5617
5590 void Parser::CloseAsyncClosure(SequenceNode* body) { 5618 void Parser::CloseAsyncClosure(SequenceNode* body) {
5591 TRACE_PARSER("CloseAsyncClosure"); 5619 TRACE_PARSER("CloseAsyncClosure");
5592 // We need a temporary expression to store intermediate return values. 5620 // We need a temporary expression to store intermediate return values.
5593 parsed_function()->EnsureExpressionTemp(); 5621 parsed_function()->EnsureExpressionTemp();
5622 // Implicitly mark those variables below as captured. We currently mark all
5623 // variables of all scopes as captured (below), but as soon as we do something
5624 // smarter we rely on these internal variables to be available.
5625 body->scope()->LookupVariable(Symbols::Completer(), false);
5626 body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
5627 body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
5628 body->scope()->RecursivelyCaptureAllVariables();
5594 } 5629 }
5595 5630
5596 5631
5597 // Set up default values for all optional parameters to the function. 5632 // Set up default values for all optional parameters to the function.
5598 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, 5633 void Parser::SetupDefaultsForOptionalParams(const ParamList* params,
5599 Array* default_values) { 5634 Array* default_values) {
5600 if (params->num_optional_parameters > 0) { 5635 if (params->num_optional_parameters > 0) {
5601 // Build array of default parameter values. 5636 // Build array of default parameter values.
5602 ParamDesc* param = 5637 ParamDesc* param =
5603 params->parameters->data() + params->num_fixed_parameters; 5638 params->parameters->data() + params->num_fixed_parameters;
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after
7118 } 7153 }
7119 stack_trace_param->var = var; 7154 stack_trace_param->var = var;
7120 } 7155 }
7121 } 7156 }
7122 7157
7123 7158
7124 SequenceNode* Parser::ParseFinallyBlock() { 7159 SequenceNode* Parser::ParseFinallyBlock() {
7125 TRACE_PARSER("ParseFinallyBlock"); 7160 TRACE_PARSER("ParseFinallyBlock");
7126 OpenBlock(); 7161 OpenBlock();
7127 ExpectToken(Token::kLBRACE); 7162 ExpectToken(Token::kLBRACE);
7163
7164 // In case of async closures we need to restore the saved try index of an
7165 // outer try block (if it exists). The current try block has already been
7166 // removed from the stack of try blocks.
7167 if (current_function().is_async_closure() && (try_blocks_list_ != NULL)) {
7168 // We need two unchain two scopes: finally clause, and the try block level.
7169 SetupSavedTryContext(current_block_->scope->parent()->parent(),
7170 try_blocks_list_->try_index(),
7171 current_block_->statements);
7172 } else {
7173 parsed_function()->reset_saved_try_ctx_vars();
7174 }
7175
7128 ParseStatementSequence(); 7176 ParseStatementSequence();
7129 ExpectToken(Token::kRBRACE); 7177 ExpectToken(Token::kRBRACE);
7130 SequenceNode* finally_block = CloseBlock(); 7178 SequenceNode* finally_block = CloseBlock();
7131 return finally_block; 7179 return finally_block;
7132 } 7180 }
7133 7181
7134 7182
7135 void Parser::PushTryBlock(Block* try_block) { 7183 void Parser::PushTryBlock(Block* try_block) {
7136 intptr_t try_index = AllocateTryIndex(); 7184 intptr_t try_index = AllocateTryIndex();
7137 TryBlocks* block = new(I) TryBlocks( 7185 TryBlocks* block = new(I) TryBlocks(
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
7263 current_block_->statements->Add(new(I) InstanceCallNode( 7311 current_block_->statements->Add(new(I) InstanceCallNode(
7264 catch_pos, 7312 catch_pos,
7265 new(I) LoadLocalNode(catch_pos, stack_trace_param.var), 7313 new(I) LoadLocalNode(catch_pos, stack_trace_param.var),
7266 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), 7314 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()),
7267 no_args)); 7315 no_args));
7268 } 7316 }
7269 7317
7270 // Add nested block with user-defined code. This blocks allows 7318 // Add nested block with user-defined code. This blocks allows
7271 // declarations in the body to shadow the catch parameters. 7319 // declarations in the body to shadow the catch parameters.
7272 CheckToken(Token::kLBRACE); 7320 CheckToken(Token::kLBRACE);
7321
7322 // In case of async closures we need to restore the saved try index of an
7323 // outer try block (if it exists).
7324 ASSERT(try_blocks_list_ != NULL);
7325 if (current_function().is_async_closure() &&
7326 (try_blocks_list_->outer_try_block() != NULL)) {
7327 // We need to unchain three scope levels: catch clause, catch parameters,
7328 // and the general try block.
7329 SetupSavedTryContext(current_block_->scope->parent()->parent()->parent(),
7330 try_blocks_list_->outer_try_block()->try_index(),
7331 current_block_->statements);
7332 } else {
7333 parsed_function()->reset_saved_try_ctx_vars();
7334 }
7335
7273 current_block_->statements->Add(ParseNestedStatement(false, NULL)); 7336 current_block_->statements->Add(ParseNestedStatement(false, NULL));
7274 catch_blocks.Add(CloseBlock()); 7337 catch_blocks.Add(CloseBlock());
7275 7338
7276 const bool is_bad_type = 7339 const bool is_bad_type =
7277 exception_param.type->IsMalformed() || 7340 exception_param.type->IsMalformed() ||
7278 exception_param.type->IsMalbounded(); 7341 exception_param.type->IsMalbounded();
7279 if (exception_param.type->IsDynamicType() || is_bad_type) { 7342 if (exception_param.type->IsDynamicType() || is_bad_type) {
7280 // There is no exception type or else it is malformed or malbounded. 7343 // There is no exception type or else it is malformed or malbounded.
7281 // In the first case, unconditionally execute the catch body. In the 7344 // In the first case, unconditionally execute the catch body. In the
7282 // second case, unconditionally throw. 7345 // second case, unconditionally throw.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
7358 AstNode* type_test = type_tests.RemoveLast(); 7421 AstNode* type_test = type_tests.RemoveLast();
7359 SequenceNode* catch_block = catch_blocks.RemoveLast(); 7422 SequenceNode* catch_block = catch_blocks.RemoveLast();
7360 current_block_->statements->Add(new(I) IfNode( 7423 current_block_->statements->Add(new(I) IfNode(
7361 type_test->token_pos(), type_test, catch_block, current)); 7424 type_test->token_pos(), type_test, catch_block, current));
7362 current = CloseBlock(); 7425 current = CloseBlock();
7363 } 7426 }
7364 return current; 7427 return current;
7365 } 7428 }
7366 7429
7367 7430
7431 // Set up the currently relevant :saved_try_context_var on the stack:
7432 // * Try blocks: Set the context variable for this try block.
7433 // * Catch/finally blocks: Set the context variable for any outer try block (if
7434 // existent).
7435 //
7436 // Also save the captured variable and the stack variable to be able to set
7437 // it after a function continues execution (await).
7438 void Parser::SetupSavedTryContext(LocalScope* saved_try_context_scope,
7439 int16_t try_index,
7440 SequenceNode* target) {
7441 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable(
7442 Symbols::SavedTryContextVar(), false);
7443 ASSERT((saved_try_ctx != NULL) && !saved_try_ctx->is_captured());
7444 const String& async_saved_try_ctx_name =
7445 BuildAsyncSavedTryContextName(I, try_index);
7446 LocalVariable* async_saved_try_ctx =
7447 target->scope()->LookupVariable(async_saved_try_ctx_name, false);
7448 ASSERT((async_saved_try_ctx != NULL) && async_saved_try_ctx->is_captured());
7449 target->Add(new (I) StoreLocalNode(
7450 Scanner::kNoSourcePos, saved_try_ctx, new (I) LoadLocalNode(
7451 Scanner::kNoSourcePos, async_saved_try_ctx)));
7452
7453 parsed_function()->set_saved_try_ctx(saved_try_ctx);
7454 parsed_function()->set_async_saved_try_ctx(async_saved_try_ctx);
7455 }
7456
7457
7368 AstNode* Parser::ParseTryStatement(String* label_name) { 7458 AstNode* Parser::ParseTryStatement(String* label_name) {
7369 TRACE_PARSER("ParseTryStatement"); 7459 TRACE_PARSER("ParseTryStatement");
7370 7460
7371 // We create three variables for exceptions here: 7461 // We create three variables for exceptions here:
7372 // ':saved_try_context_var' - Used to save the context before the start of 7462 // ':saved_try_context_var' - Used to save the context before the start of
7373 // the try block. The context register is 7463 // the try block. The context register is
7374 // restored from this variable before 7464 // restored from this variable before
7375 // processing the catch block handler. 7465 // processing the catch block handler.
7376 // ':exception_var' - Used to save the current exception object that was 7466 // ':exception_var' - Used to save the current exception object that was
7377 // thrown. 7467 // thrown.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
7416 if (label_name != NULL) { 7506 if (label_name != NULL) {
7417 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); 7507 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement);
7418 OpenBlock(); 7508 OpenBlock();
7419 current_block_->scope->AddLabel(try_label); 7509 current_block_->scope->AddLabel(try_label);
7420 } 7510 }
7421 7511
7422 // Now parse the 'try' block. 7512 // Now parse the 'try' block.
7423 OpenBlock(); 7513 OpenBlock();
7424 PushTryBlock(current_block_); 7514 PushTryBlock(current_block_);
7425 ExpectToken(Token::kLBRACE); 7515 ExpectToken(Token::kLBRACE);
7516
7517 if (current_function().is_async_closure()) {
7518 const String& async_saved_try_ctx_name =
7519 BuildAsyncSavedTryContextName(I, last_used_try_index_ - 1);
7520 LocalVariable* async_saved_try_ctx =
7521 current_block_->scope->LookupVariable(
7522 async_saved_try_ctx_name, false);
7523 ASSERT(async_saved_try_ctx != NULL);
7524 ASSERT(context_var != NULL);
7525 current_block_->statements->Add(new (I) StoreLocalNode(
7526 Scanner::kNoSourcePos, async_saved_try_ctx, new (I) LoadLocalNode(
7527 Scanner::kNoSourcePos, context_var)));
7528 parsed_function()->set_saved_try_ctx(context_var);
7529 parsed_function()->set_async_saved_try_ctx(async_saved_try_ctx);
7530 }
7531
7426 ParseStatementSequence(); 7532 ParseStatementSequence();
7427 ExpectToken(Token::kRBRACE); 7533 ExpectToken(Token::kRBRACE);
7428 SequenceNode* try_block = CloseBlock(); 7534 SequenceNode* try_block = CloseBlock();
7429 7535
7430 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && 7536 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") &&
7431 (CurrentToken() != Token::kFINALLY)) { 7537 (CurrentToken() != Token::kFINALLY)) {
7432 ReportError("catch or finally clause expected"); 7538 ReportError("catch or finally clause expected");
7433 } 7539 }
7434 7540
7435 // Now parse the 'catch' blocks if any. 7541 // Now parse the 'catch' blocks if any.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
7488 // and attach the label to it. 7594 // and attach the label to it.
7489 AstNode* try_catch_node = new(I) TryCatchNode( 7595 AstNode* try_catch_node = new(I) TryCatchNode(
7490 try_pos, try_block, context_var, catch_clause, finally_block, try_index); 7596 try_pos, try_block, context_var, catch_clause, finally_block, try_index);
7491 7597
7492 if (try_label != NULL) { 7598 if (try_label != NULL) {
7493 current_block_->statements->Add(try_catch_node); 7599 current_block_->statements->Add(try_catch_node);
7494 SequenceNode* sequence = CloseBlock(); 7600 SequenceNode* sequence = CloseBlock();
7495 sequence->set_label(try_label); 7601 sequence->set_label(try_label);
7496 try_catch_node = sequence; 7602 try_catch_node = sequence;
7497 } 7603 }
7604
7605 // In case of async closures we need to restore the saved try index of an
7606 // outer try block (if it exists).
7607 if (current_function().is_async_closure() &&
7608 (outer_try_index != CatchClauseNode::kInvalidTryIndex)) {
7609 SequenceNode* try_catch_and_restore_try_ctx = new (I) SequenceNode(
7610 Scanner::kNoSourcePos, current_block_->scope);
7611 try_catch_and_restore_try_ctx->Add(try_catch_node);
7612 SetupSavedTryContext(
7613 current_block_->scope, outer_try_index, try_catch_and_restore_try_ctx);
7614 return try_catch_and_restore_try_ctx;
7615 } else {
7616 parsed_function()->reset_saved_try_ctx_vars();
7617 }
7618
7498 return try_catch_node; 7619 return try_catch_node;
7499 } 7620 }
7500 7621
7501 7622
7502 AstNode* Parser::ParseJump(String* label_name) { 7623 AstNode* Parser::ParseJump(String* label_name) {
7503 TRACE_PARSER("ParseJump"); 7624 TRACE_PARSER("ParseJump");
7504 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); 7625 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE);
7505 Token::Kind jump_kind = CurrentToken(); 7626 Token::Kind jump_kind = CurrentToken();
7506 const intptr_t jump_pos = TokenPos(); 7627 const intptr_t jump_pos = TokenPos();
7507 SourceLabel* target = NULL; 7628 SourceLabel* target = NULL;
(...skipping 3758 matching lines...) Expand 10 before | Expand all | Expand 10 after
11266 void Parser::SkipQualIdent() { 11387 void Parser::SkipQualIdent() {
11267 ASSERT(IsIdentifier()); 11388 ASSERT(IsIdentifier());
11268 ConsumeToken(); 11389 ConsumeToken();
11269 if (CurrentToken() == Token::kPERIOD) { 11390 if (CurrentToken() == Token::kPERIOD) {
11270 ConsumeToken(); // Consume the kPERIOD token. 11391 ConsumeToken(); // Consume the kPERIOD token.
11271 ExpectIdentifier("identifier expected after '.'"); 11392 ExpectIdentifier("identifier expected after '.'");
11272 } 11393 }
11273 } 11394 }
11274 11395
11275 } // namespace dart 11396 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698