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

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: finally try to catch all issues in try/catch/finally 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
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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
5494 TRACE_PARSER("CloseAsyncFunction"); 5493 TRACE_PARSER("CloseAsyncFunction");
5495 ASSERT(!closure.IsNull()); 5494 ASSERT(!closure.IsNull());
5496 ASSERT(closure_body != NULL); 5495 ASSERT(closure_body != NULL);
5497 // The block for the async closure body has already been closed. Close the 5496 // The block for the async closure body has already been closed. Close the
5498 // corresponding function block. 5497 // corresponding function block.
5499 CloseBlock(); 5498 CloseBlock();
5500 5499
5501 // Create and return a new future that executes a closure with the current 5500 // Create and return a new future that executes a closure with the current
5502 // body. 5501 // body.
5503 5502
5504 bool found = false;
5505
5506 // No need to capture parameters or other variables, since they have already 5503 // 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 5504 // been captured in the corresponding scope as the body has been parsed within
5508 // a nested block (contained in the async funtion's block). 5505 // a nested block (contained in the async funtion's block).
5509 const Class& future = Class::ZoneHandle(I, 5506 const Class& future = Class::ZoneHandle(I,
5510 GetClassForAsync(Symbols::Future())); 5507 GetClassForAsync(Symbols::Future()));
5511 ASSERT(!future.IsNull()); 5508 ASSERT(!future.IsNull());
5512 const Function& constructor = Function::ZoneHandle(I, 5509 const Function& constructor = Function::ZoneHandle(I,
5513 future.LookupFunction(Symbols::FutureConstructor())); 5510 future.LookupFunction(Symbols::FutureConstructor()));
5514 ASSERT(!constructor.IsNull()); 5511 ASSERT(!constructor.IsNull());
5515 const Class& completer = Class::ZoneHandle(I, 5512 const Class& completer = Class::ZoneHandle(I,
5516 GetClassForAsync(Symbols::Completer())); 5513 GetClassForAsync(Symbols::Completer()));
5517 ASSERT(!completer.IsNull()); 5514 ASSERT(!completer.IsNull());
5518 const Function& completer_constructor = Function::ZoneHandle(I, 5515 const Function& completer_constructor = Function::ZoneHandle(I,
5519 completer.LookupFunction(Symbols::CompleterConstructor())); 5516 completer.LookupFunction(Symbols::CompleterConstructor()));
5520 ASSERT(!completer_constructor.IsNull()); 5517 ASSERT(!completer_constructor.IsNull());
5521 5518
5519 bool found = false;
5522 // Add to AST: 5520 // Add to AST:
5523 // var :async_op; 5521 // var :async_op;
5524 // var :async_completer; 5522 // var :async_completer;
5523 // var :await_jump_var;
5524 // var :await_ctx_var;
5525 // Add as many variables to saved the try block ctx as there were try blocks.
5526 // var :await_saved_try_ctx_var_<x>;
hausner 2014/08/25 20:26:14 is the name :await_saved_try_ctx_var_ or :async_sa
Michael Lippautz (Google) 2014/08/26 16:45:48 Done. Using :async_...
5527 Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType());
hausner 2014/08/25 20:26:14 const
Michael Lippautz (Google) 2014/08/26 16:45:48 Done.
5525 LocalVariable* async_op_var = new (I) LocalVariable( 5528 LocalVariable* async_op_var = new (I) LocalVariable(
5526 Scanner::kNoSourcePos, 5529 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
5527 Symbols::AsyncOperation(),
5528 Type::ZoneHandle(I, Type::DynamicType()));
5529 current_block_->scope->AddVariable(async_op_var); 5530 current_block_->scope->AddVariable(async_op_var);
5530 found = closure_body->scope()->CaptureVariable(Symbols::AsyncOperation()); 5531 found = closure_body->scope()->CaptureVariable(Symbols::AsyncOperation());
5531 ASSERT(found); 5532 ASSERT(found);
5532 LocalVariable* async_completer = new (I) LocalVariable( 5533 LocalVariable* async_completer = new (I) LocalVariable(
5533 Scanner::kNoSourcePos, 5534 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
5534 Symbols::AsyncCompleter(),
5535 Type::ZoneHandle(I, Type::DynamicType()));
5536 current_block_->scope->AddVariable(async_completer); 5535 current_block_->scope->AddVariable(async_completer);
5537 found = closure_body->scope()->CaptureVariable(Symbols::AsyncCompleter()); 5536 found = closure_body->scope()->CaptureVariable(Symbols::AsyncCompleter());
5538 ASSERT(found); 5537 ASSERT(found);
5538 LocalVariable* await_jump_var = new (I) LocalVariable(
5539 Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type);
5540 current_block_->scope->AddVariable(await_jump_var);
5541 found = closure_body->scope()->CaptureVariable(Symbols::AwaitJumpVar());
5542 ASSERT(found);
5543 LocalVariable* await_ctx_var = new (I) LocalVariable(
5544 Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type);
5545 current_block_->scope->AddVariable(await_ctx_var);
5546 found = closure_body->scope()->CaptureVariable(Symbols::AwaitContextVar());
5547 ASSERT(found);
5548 LocalVariable* async_saved_try_ctx_var;
5549 const char* async_saved_prefix = ":async_saved_try_ctx_var_";
5550 for (int16_t i = 0; i < last_used_try_index_; i++) {
5551 const String& cnt_str = String::ZoneHandle(
hausner 2014/08/25 20:26:14 cnt_str can be a regular handle, need not be a zon
Michael Lippautz (Google) 2014/08/26 16:45:48 Done: BuildAsyncSavedTryContextName()
5552 I, String::NewFormatted("%s%d", async_saved_prefix, i));
5553 const String& symbol = String::ZoneHandle(I, Symbols::New(cnt_str));
5554 async_saved_try_ctx_var = new (I) LocalVariable(
5555 Scanner::kNoSourcePos, symbol, dynamic_type);
5556 current_block_->scope->AddVariable(async_saved_try_ctx_var);
5557 found = closure_body->scope()->CaptureVariable(symbol);
5558 ASSERT(found);
5559 }
5539 5560
5540 // Add to AST: 5561 // Add to AST:
5541 // :async_completer = new Completer(); 5562 // :async_completer = new Completer();
5542 ArgumentListNode* empty_args = new (I) ArgumentListNode( 5563 ArgumentListNode* empty_args =
5543 Scanner::kNoSourcePos); 5564 new (I) ArgumentListNode(Scanner::kNoSourcePos);
5544 ConstructorCallNode* completer_constructor_node = new (I) ConstructorCallNode( 5565 ConstructorCallNode* completer_constructor_node = new (I) ConstructorCallNode(
5545 Scanner::kNoSourcePos, 5566 Scanner::kNoSourcePos,
5546 TypeArguments::ZoneHandle(I), 5567 TypeArguments::ZoneHandle(I),
5547 completer_constructor, 5568 completer_constructor,
5548 empty_args); 5569 empty_args);
5549 StoreLocalNode* store_completer = new (I) StoreLocalNode( 5570 StoreLocalNode* store_completer = new (I) StoreLocalNode(
5550 Scanner::kNoSourcePos, 5571 Scanner::kNoSourcePos,
5551 async_completer, 5572 async_completer,
5552 completer_constructor_node); 5573 completer_constructor_node);
5553 current_block_->statements->Add(store_completer); 5574 current_block_->statements->Add(store_completer);
(...skipping 30 matching lines...) Expand all
5584 Symbols::CompleterFuture())); 5605 Symbols::CompleterFuture()));
5585 current_block_->statements->Add(return_node); 5606 current_block_->statements->Add(return_node);
5586 return CloseBlock(); 5607 return CloseBlock();
5587 } 5608 }
5588 5609
5589 5610
5590 void Parser::CloseAsyncClosure(SequenceNode* body) { 5611 void Parser::CloseAsyncClosure(SequenceNode* body) {
5591 TRACE_PARSER("CloseAsyncClosure"); 5612 TRACE_PARSER("CloseAsyncClosure");
5592 // We need a temporary expression to store intermediate return values. 5613 // We need a temporary expression to store intermediate return values.
5593 parsed_function()->EnsureExpressionTemp(); 5614 parsed_function()->EnsureExpressionTemp();
5615 // Implicitly mark those variables below as captured. We currently mark all
5616 // variables of all scopes as captured (below), but as soon as we do something
5617 // smarter we rely on these internal variables to be available.
5618 body->scope()->LookupVariable(Symbols::Completer(), false);
5619 body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
5620 body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
5621 body->scope()->RecursivelyCaptureAllVariables();
5594 } 5622 }
5595 5623
5596 5624
5597 // Set up default values for all optional parameters to the function. 5625 // Set up default values for all optional parameters to the function.
5598 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, 5626 void Parser::SetupDefaultsForOptionalParams(const ParamList* params,
5599 Array* default_values) { 5627 Array* default_values) {
5600 if (params->num_optional_parameters > 0) { 5628 if (params->num_optional_parameters > 0) {
5601 // Build array of default parameter values. 5629 // Build array of default parameter values.
5602 ParamDesc* param = 5630 ParamDesc* param =
5603 params->parameters->data() + params->num_fixed_parameters; 5631 params->parameters->data() + params->num_fixed_parameters;
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after
7118 } 7146 }
7119 stack_trace_param->var = var; 7147 stack_trace_param->var = var;
7120 } 7148 }
7121 } 7149 }
7122 7150
7123 7151
7124 SequenceNode* Parser::ParseFinallyBlock() { 7152 SequenceNode* Parser::ParseFinallyBlock() {
7125 TRACE_PARSER("ParseFinallyBlock"); 7153 TRACE_PARSER("ParseFinallyBlock");
7126 OpenBlock(); 7154 OpenBlock();
7127 ExpectToken(Token::kLBRACE); 7155 ExpectToken(Token::kLBRACE);
7156
7157 // In case of async closures we need to restore the saved try index of an
7158 // outer try block (if it exists). The current try block has already been
7159 // removed from the stack of try blocks.
7160 if (current_function().is_async_closure() && (try_blocks_list_ != NULL)) {
7161 // We need two unchain two scopes: finally clause, and the try block level.
7162 SetupSavedTryContext(current_block_->scope->parent()->parent(),
7163 try_blocks_list_->try_index(),
7164 current_block_->statements);
7165 } else {
7166 parsed_function()->reset_saved_try_ctx_vars();
7167 }
7168
7128 ParseStatementSequence(); 7169 ParseStatementSequence();
7129 ExpectToken(Token::kRBRACE); 7170 ExpectToken(Token::kRBRACE);
7130 SequenceNode* finally_block = CloseBlock(); 7171 SequenceNode* finally_block = CloseBlock();
7131 return finally_block; 7172 return finally_block;
7132 } 7173 }
7133 7174
7134 7175
7135 void Parser::PushTryBlock(Block* try_block) { 7176 void Parser::PushTryBlock(Block* try_block) {
7136 intptr_t try_index = AllocateTryIndex(); 7177 intptr_t try_index = AllocateTryIndex();
7137 TryBlocks* block = new(I) TryBlocks( 7178 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( 7304 current_block_->statements->Add(new(I) InstanceCallNode(
7264 catch_pos, 7305 catch_pos,
7265 new(I) LoadLocalNode(catch_pos, stack_trace_param.var), 7306 new(I) LoadLocalNode(catch_pos, stack_trace_param.var),
7266 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), 7307 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()),
7267 no_args)); 7308 no_args));
7268 } 7309 }
7269 7310
7270 // Add nested block with user-defined code. This blocks allows 7311 // Add nested block with user-defined code. This blocks allows
7271 // declarations in the body to shadow the catch parameters. 7312 // declarations in the body to shadow the catch parameters.
7272 CheckToken(Token::kLBRACE); 7313 CheckToken(Token::kLBRACE);
7314
7315 // In case of async closures we need to restore the saved try index of an
7316 // outer try block (if it exists).
7317 ASSERT(try_blocks_list_ != NULL);
7318 if (current_function().is_async_closure() &&
7319 (try_blocks_list_->outer_try_block() != NULL)) {
7320 // We need to unchain three scope levels: catch clause, catch parameters,
7321 // and the general try block.
7322 SetupSavedTryContext(current_block_->scope->parent()->parent()->parent(),
7323 try_blocks_list_->outer_try_block()->try_index(),
7324 current_block_->statements);
7325 } else {
7326 parsed_function()->reset_saved_try_ctx_vars();
7327 }
7328
7273 current_block_->statements->Add(ParseNestedStatement(false, NULL)); 7329 current_block_->statements->Add(ParseNestedStatement(false, NULL));
7274 catch_blocks.Add(CloseBlock()); 7330 catch_blocks.Add(CloseBlock());
7275 7331
7276 const bool is_bad_type = 7332 const bool is_bad_type =
7277 exception_param.type->IsMalformed() || 7333 exception_param.type->IsMalformed() ||
7278 exception_param.type->IsMalbounded(); 7334 exception_param.type->IsMalbounded();
7279 if (exception_param.type->IsDynamicType() || is_bad_type) { 7335 if (exception_param.type->IsDynamicType() || is_bad_type) {
7280 // There is no exception type or else it is malformed or malbounded. 7336 // There is no exception type or else it is malformed or malbounded.
7281 // In the first case, unconditionally execute the catch body. In the 7337 // In the first case, unconditionally execute the catch body. In the
7282 // second case, unconditionally throw. 7338 // second case, unconditionally throw.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
7357 while (!type_tests.is_empty()) { 7413 while (!type_tests.is_empty()) {
7358 AstNode* type_test = type_tests.RemoveLast(); 7414 AstNode* type_test = type_tests.RemoveLast();
7359 SequenceNode* catch_block = catch_blocks.RemoveLast(); 7415 SequenceNode* catch_block = catch_blocks.RemoveLast();
7360 current_block_->statements->Add(new(I) IfNode( 7416 current_block_->statements->Add(new(I) IfNode(
7361 type_test->token_pos(), type_test, catch_block, current)); 7417 type_test->token_pos(), type_test, catch_block, current));
7362 current = CloseBlock(); 7418 current = CloseBlock();
7363 } 7419 }
7364 return current; 7420 return current;
7365 } 7421 }
7366 7422
7367 7423
hausner 2014/08/25 20:26:14 Could you add a short comment describing what this
Michael Lippautz (Google) 2014/08/26 16:45:48 Done.
7424 void Parser::SetupSavedTryContext(LocalScope* saved_try_context_scope,
7425 int16_t try_index,
7426 SequenceNode* target) {
7427 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable(
7428 Symbols::SavedTryContextVar(), false);
7429 ASSERT((saved_try_ctx != NULL) && !saved_try_ctx->is_captured());
7430 const char* async_saved_prefix = ":async_saved_try_ctx_var_";
7431 const String& cnt_str = String::ZoneHandle(
hausner 2014/08/25 20:26:14 cnt_str probably doesn't need to be a ZoneHandle;
Michael Lippautz (Google) 2014/08/26 16:45:48 Done.
7432 I, String::NewFormatted("%s%d", async_saved_prefix, try_index));
7433 const String& current_await_saved_try_ctx_symbol = String::ZoneHandle(
7434 I, Symbols::New(cnt_str));
7435 LocalVariable* async_saved_try_ctx =
7436 target->scope()->LookupVariable(
7437 current_await_saved_try_ctx_symbol, false);
7438 ASSERT((async_saved_try_ctx != NULL) && async_saved_try_ctx->is_captured());
7439 target->Add(new (I) StoreLocalNode(
7440 Scanner::kNoSourcePos, saved_try_ctx, new (I) LoadLocalNode(
7441 Scanner::kNoSourcePos, async_saved_try_ctx)));
7442
7443 parsed_function()->set_saved_try_ctx(saved_try_ctx);
7444 parsed_function()->set_async_saved_try_ctx(async_saved_try_ctx);
7445 }
7446
7447
7368 AstNode* Parser::ParseTryStatement(String* label_name) { 7448 AstNode* Parser::ParseTryStatement(String* label_name) {
7369 TRACE_PARSER("ParseTryStatement"); 7449 TRACE_PARSER("ParseTryStatement");
7370 7450
7371 // We create three variables for exceptions here: 7451 // We create three variables for exceptions here:
7372 // ':saved_try_context_var' - Used to save the context before the start of 7452 // ':saved_try_context_var' - Used to save the context before the start of
7373 // the try block. The context register is 7453 // the try block. The context register is
7374 // restored from this variable before 7454 // restored from this variable before
7375 // processing the catch block handler. 7455 // processing the catch block handler.
7376 // ':exception_var' - Used to save the current exception object that was 7456 // ':exception_var' - Used to save the current exception object that was
7377 // thrown. 7457 // thrown.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
7416 if (label_name != NULL) { 7496 if (label_name != NULL) {
7417 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); 7497 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement);
7418 OpenBlock(); 7498 OpenBlock();
7419 current_block_->scope->AddLabel(try_label); 7499 current_block_->scope->AddLabel(try_label);
7420 } 7500 }
7421 7501
7422 // Now parse the 'try' block. 7502 // Now parse the 'try' block.
7423 OpenBlock(); 7503 OpenBlock();
7424 PushTryBlock(current_block_); 7504 PushTryBlock(current_block_);
7425 ExpectToken(Token::kLBRACE); 7505 ExpectToken(Token::kLBRACE);
7506
7507 const char* async_saved_prefix = ":async_saved_try_ctx_var_";
7508 if (current_function().is_async_closure()) {
7509 const String& cnt_str = String::ZoneHandle(
srdjan 2014/08/26 15:54:33 Regular handle: use ZoneHandle-s only if the varia
Michael Lippautz (Google) 2014/08/26 16:45:48 Done. Code is now refactored but uses a regular ha
7510 I, String::NewFormatted("%s%d",
7511 async_saved_prefix, last_used_try_index_-1));
7512 const String& current_await_saved_try_ctx_symbol =
7513 String::ZoneHandle(I, Symbols::New(cnt_str));
7514 LocalVariable* async_saved_try_ctx =
7515 current_block_->scope->LookupVariable(
7516 current_await_saved_try_ctx_symbol, false);
7517 ASSERT(async_saved_try_ctx != NULL);
7518 ASSERT(context_var);
7519 current_block_->statements->Add(new (I) StoreLocalNode(
7520 Scanner::kNoSourcePos, async_saved_try_ctx, new (I) LoadLocalNode(
7521 Scanner::kNoSourcePos, context_var)));
7522 parsed_function()->set_saved_try_ctx(context_var);
7523 parsed_function()->set_async_saved_try_ctx(async_saved_try_ctx);
7524 }
7525
7426 ParseStatementSequence(); 7526 ParseStatementSequence();
7427 ExpectToken(Token::kRBRACE); 7527 ExpectToken(Token::kRBRACE);
7428 SequenceNode* try_block = CloseBlock(); 7528 SequenceNode* try_block = CloseBlock();
7429 7529
7430 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && 7530 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") &&
7431 (CurrentToken() != Token::kFINALLY)) { 7531 (CurrentToken() != Token::kFINALLY)) {
7432 ReportError("catch or finally clause expected"); 7532 ReportError("catch or finally clause expected");
7433 } 7533 }
7434 7534
7435 // Now parse the 'catch' blocks if any. 7535 // 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. 7588 // and attach the label to it.
7489 AstNode* try_catch_node = new(I) TryCatchNode( 7589 AstNode* try_catch_node = new(I) TryCatchNode(
7490 try_pos, try_block, context_var, catch_clause, finally_block, try_index); 7590 try_pos, try_block, context_var, catch_clause, finally_block, try_index);
7491 7591
7492 if (try_label != NULL) { 7592 if (try_label != NULL) {
7493 current_block_->statements->Add(try_catch_node); 7593 current_block_->statements->Add(try_catch_node);
7494 SequenceNode* sequence = CloseBlock(); 7594 SequenceNode* sequence = CloseBlock();
7495 sequence->set_label(try_label); 7595 sequence->set_label(try_label);
7496 try_catch_node = sequence; 7596 try_catch_node = sequence;
7497 } 7597 }
7598
7599 // In case of async closures we need to restore the saved try index of an
7600 // outer try block (if it exists).
7601 if (current_function().is_async_closure() &&
7602 (outer_try_index != CatchClauseNode::kInvalidTryIndex)) {
7603 SequenceNode* try_catch_and_restore_try_ctx = new (I) SequenceNode(
7604 Scanner::kNoSourcePos, current_block_->scope);
7605 try_catch_and_restore_try_ctx->Add(try_catch_node);
7606 SetupSavedTryContext(
7607 current_block_->scope, outer_try_index, try_catch_and_restore_try_ctx);
7608 return try_catch_and_restore_try_ctx;
7609 } else {
7610 parsed_function()->reset_saved_try_ctx_vars();
7611 }
7612
7498 return try_catch_node; 7613 return try_catch_node;
7499 } 7614 }
7500 7615
7501 7616
7502 AstNode* Parser::ParseJump(String* label_name) { 7617 AstNode* Parser::ParseJump(String* label_name) {
7503 TRACE_PARSER("ParseJump"); 7618 TRACE_PARSER("ParseJump");
7504 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); 7619 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE);
7505 Token::Kind jump_kind = CurrentToken(); 7620 Token::Kind jump_kind = CurrentToken();
7506 const intptr_t jump_pos = TokenPos(); 7621 const intptr_t jump_pos = TokenPos();
7507 SourceLabel* target = NULL; 7622 SourceLabel* target = NULL;
(...skipping 3758 matching lines...) Expand 10 before | Expand all | Expand 10 after
11266 void Parser::SkipQualIdent() { 11381 void Parser::SkipQualIdent() {
11267 ASSERT(IsIdentifier()); 11382 ASSERT(IsIdentifier());
11268 ConsumeToken(); 11383 ConsumeToken();
11269 if (CurrentToken() == Token::kPERIOD) { 11384 if (CurrentToken() == Token::kPERIOD) {
11270 ConsumeToken(); // Consume the kPERIOD token. 11385 ConsumeToken(); // Consume the kPERIOD token.
11271 ExpectIdentifier("identifier expected after '.'"); 11386 ExpectIdentifier("identifier expected after '.'");
11272 } 11387 }
11273 } 11388 }
11274 11389
11275 } // namespace dart 11390 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698