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

Unified Diff: runtime/vm/parser.cc

Issue 973103002: One more fix to async machinery (rethrow in finally, issue 22595). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 44187)
+++ runtime/vm/parser.cc (working copy)
@@ -6034,9 +6034,15 @@
stack_trace_param.var,
new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
}
+ LocalVariable* saved_exception_var = current_block_->scope->LookupVariable(
+ Symbols::SavedExceptionVar(), false);
+ LocalVariable* saved_stack_trace_var = current_block_->scope->LookupVariable(
+ Symbols::SavedStackTraceVar(), false);
+ SaveExceptionAndStacktrace(exception_var,
+ stack_trace_var,
+ saved_exception_var,
+ saved_stack_trace_var);
- SaveExceptionAndStacktrace(exception_var, stack_trace_var);
-
// Catch block: add the error to the stream.
// :controller.AddError(:exception, :stack_trace);
// return; // The finally block will close the stream.
@@ -6109,6 +6115,8 @@
context_var,
exception_var,
stack_trace_var,
+ saved_exception_var,
+ saved_stack_trace_var,
AllocateTryIndex(),
true);
@@ -6178,9 +6186,15 @@
stack_trace_param.var,
new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
}
+ LocalVariable* saved_exception_var = current_block_->scope->LookupVariable(
+ Symbols::SavedExceptionVar(), false);
+ LocalVariable* saved_stack_trace_var = current_block_->scope->LookupVariable(
+ Symbols::SavedStackTraceVar(), false);
+ SaveExceptionAndStacktrace(exception_var,
+ stack_trace_var,
+ saved_exception_var,
+ saved_stack_trace_var);
- SaveExceptionAndStacktrace(exception_var, stack_trace_var);
-
// Complete the async future with an error. This catch block executes
// unconditionally, there is no need to generate a type check for.
LocalVariable* async_completer = current_block_->scope->LookupVariable(
@@ -6220,6 +6234,8 @@
context_var,
exception_var,
stack_trace_var,
+ saved_exception_var,
+ saved_stack_trace_var,
CatchClauseNode::kInvalidTryIndex,
true);
AstNode* try_catch_node = new (Z) TryCatchNode(
@@ -6239,6 +6255,7 @@
ASSERT(innermost_function().IsAsyncClosure() ||
innermost_function().IsAsyncGenClosure());
+ const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
LocalVariable* context_var =
current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar());
if (context_var == NULL) {
@@ -6245,7 +6262,7 @@
context_var = new(Z) LocalVariable(
TokenPos(),
Symbols::SavedTryContextVar(),
- Type::ZoneHandle(Z, Type::DynamicType()));
+ dynamic_type);
current_block_->scope->AddVariable(context_var);
}
LocalVariable* exception_var =
@@ -6254,7 +6271,7 @@
exception_var = new(Z) LocalVariable(
TokenPos(),
Symbols::ExceptionVar(),
- Type::ZoneHandle(Z, Type::DynamicType()));
+ dynamic_type);
current_block_->scope->AddVariable(exception_var);
}
LocalVariable* stack_trace_var =
@@ -6263,12 +6280,28 @@
stack_trace_var = new(Z) LocalVariable(
TokenPos(),
Symbols::StackTraceVar(),
- Type::ZoneHandle(Z, Type::DynamicType()));
+ dynamic_type);
current_block_->scope->AddVariable(stack_trace_var);
}
+ LocalVariable* saved_exception_var =
+ current_block_->scope->LocalLookupVariable(Symbols::SavedExceptionVar());
+ if (saved_exception_var == NULL) {
+ saved_exception_var = new(Z) LocalVariable(
+ TokenPos(),
+ Symbols::SavedExceptionVar(),
+ dynamic_type);
+ current_block_->scope->AddVariable(saved_exception_var);
+ }
+ LocalVariable* saved_stack_trace_var =
+ current_block_->scope->LocalLookupVariable(Symbols::SavedStackTraceVar());
+ if (saved_stack_trace_var == NULL) {
+ saved_stack_trace_var = new(Z) LocalVariable(
+ TokenPos(),
+ Symbols::SavedStackTraceVar(),
+ dynamic_type);
+ current_block_->scope->AddVariable(saved_stack_trace_var);
+ }
- SetupSavedExceptionAndStacktrace();
-
// Open the try block.
OpenBlock();
// This is the outermost try-catch in the function.
@@ -8652,45 +8685,14 @@
}
-// Populate current scope of the try block with the saved exception and saved
-// stack trace.
-void Parser::SetupSavedExceptionAndStacktrace() {
- ASSERT(innermost_function().IsAsyncClosure() ||
- innermost_function().IsAsyncFunction() ||
- innermost_function().IsSyncGenClosure() ||
- innermost_function().IsSyncGenerator() ||
- innermost_function().IsAsyncGenerator() ||
- innermost_function().IsAsyncGenClosure());
- // Add :saved_exception_var and :saved_stack_trace_var to current scope.
- // They will automatically get captured.
- // Parallel try statements share the same set of variables.
- LocalVariable* saved_exception_var =
- current_block_->scope->LocalLookupVariable(Symbols::SavedExceptionVar());
- if (saved_exception_var == NULL) {
- saved_exception_var = new (Z) LocalVariable(
- Scanner::kNoSourcePos,
- Symbols::SavedExceptionVar(),
- Type::ZoneHandle(Z, Type::DynamicType()));
- saved_exception_var->set_is_final();
- current_block_->scope->AddVariable(saved_exception_var);
- }
- LocalVariable* saved_stack_trace_var =
- current_block_->scope->LocalLookupVariable(Symbols::SavedStackTraceVar());
- if (saved_stack_trace_var == NULL) {
- saved_stack_trace_var = new (Z) LocalVariable(
- Scanner::kNoSourcePos,
- Symbols::SavedStackTraceVar(),
- Type::ZoneHandle(Z, Type::DynamicType()));
- saved_exception_var->set_is_final();
- current_block_->scope->AddVariable(saved_stack_trace_var);
- }
-}
-
-
// Generate code to load the exception object (:exception_var) into
// the saved exception variable (:saved_exception_var) used to rethrow.
+// Generate code to load the stack trace object (:stack_trace_var) into
+// the saved stacktrace variable (:saved_stack_trace_var) used to rethrow.
void Parser::SaveExceptionAndStacktrace(LocalVariable* exception_var,
- LocalVariable* stack_trace_var) {
+ LocalVariable* stack_trace_var,
+ LocalVariable* saved_exception_var,
+ LocalVariable* saved_stack_trace_var) {
ASSERT(innermost_function().IsAsyncClosure() ||
innermost_function().IsAsyncFunction() ||
innermost_function().IsSyncGenClosure() ||
@@ -8697,8 +8699,7 @@
innermost_function().IsSyncGenerator() ||
innermost_function().IsAsyncGenClosure() ||
innermost_function().IsAsyncGenerator());
- LocalVariable* saved_exception_var = current_block_->scope->LookupVariable(
- Symbols::SavedExceptionVar(), false);
+
ASSERT(saved_exception_var != NULL);
ASSERT(exception_var != NULL);
current_block_->statements->Add(new(Z) StoreLocalNode(
@@ -8706,10 +8707,6 @@
saved_exception_var,
new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
- // Generate code to load the stack trace object (:stack_trace_var) into
- // the saved stacktrace variable (:saved_stack_trace_var) used to rethrow.
- LocalVariable* saved_stack_trace_var = current_block_->scope->LookupVariable(
- Symbols::SavedStackTraceVar(), false);
ASSERT(saved_stack_trace_var != NULL);
ASSERT(stack_trace_var != NULL);
current_block_->statements->Add(new(Z) StoreLocalNode(
@@ -8810,6 +8807,8 @@
intptr_t handler_pos,
LocalVariable* exception_var,
LocalVariable* stack_trace_var,
+ LocalVariable* rethrow_exception_var,
+ LocalVariable* rethrow_stack_trace_var,
const GrowableObjectArray& handler_types,
bool* needs_stack_trace) {
// All catch blocks are merged into an if-then-else sequence of the
@@ -8902,7 +8901,10 @@
Z, scope->parent(), try_block->try_index()));
}
}
- SaveExceptionAndStacktrace(exception_var, stack_trace_var);
+ SaveExceptionAndStacktrace(exception_var,
+ stack_trace_var,
+ rethrow_exception_var,
+ rethrow_stack_trace_var);
}
current_block_->statements->Add(ParseNestedStatement(false, NULL));
@@ -9066,7 +9068,8 @@
// :exception_var and :stack_trace_var get set with the exception object
// and the stack trace object when an exception is thrown. These three
// implicit variables can never be captured.
- // Parallel try statements share the same set of variables.
+ const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
+ // Consecutive try statements share the same set of variables.
LocalVariable* context_var =
current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar());
if (context_var == NULL) {
@@ -9073,7 +9076,7 @@
context_var = new(Z) LocalVariable(
TokenPos(),
Symbols::SavedTryContextVar(),
- Type::ZoneHandle(Z, Type::DynamicType()));
+ dynamic_type);
current_block_->scope->AddVariable(context_var);
}
LocalVariable* exception_var =
@@ -9082,7 +9085,7 @@
exception_var = new(Z) LocalVariable(
TokenPos(),
Symbols::ExceptionVar(),
- Type::ZoneHandle(Z, Type::DynamicType()));
+ dynamic_type);
current_block_->scope->AddVariable(exception_var);
}
LocalVariable* stack_trace_var =
@@ -9091,17 +9094,36 @@
stack_trace_var = new(Z) LocalVariable(
TokenPos(),
Symbols::StackTraceVar(),
- Type::ZoneHandle(Z, Type::DynamicType()));
+ dynamic_type);
current_block_->scope->AddVariable(stack_trace_var);
}
-
- if (innermost_function().IsAsyncClosure() ||
- innermost_function().IsAsyncFunction() ||
- innermost_function().IsSyncGenClosure() ||
- innermost_function().IsSyncGenerator() ||
- innermost_function().IsAsyncGenClosure() ||
- innermost_function().IsAsyncGenerator()) {
- SetupSavedExceptionAndStacktrace();
+ LocalVariable* saved_exception_var = NULL;
+ LocalVariable* saved_stack_trace_var = NULL;
+ const bool is_async = innermost_function().IsAsyncClosure() ||
+ innermost_function().IsAsyncFunction() ||
+ innermost_function().IsSyncGenClosure() ||
+ innermost_function().IsSyncGenerator() ||
+ innermost_function().IsAsyncGenClosure() ||
+ innermost_function().IsAsyncGenerator();
+ if (is_async) {
+ saved_exception_var = current_block_->scope->LocalLookupVariable(
+ Symbols::SavedExceptionVar());
+ if (saved_exception_var == NULL) {
+ saved_exception_var = new(Z) LocalVariable(
+ TokenPos(),
+ Symbols::SavedExceptionVar(),
+ dynamic_type);
+ current_block_->scope->AddVariable(saved_exception_var);
+ }
+ saved_stack_trace_var = current_block_->scope->LocalLookupVariable(
+ Symbols::SavedStackTraceVar());
+ if (saved_stack_trace_var == NULL) {
+ saved_stack_trace_var = new(Z) LocalVariable(
+ TokenPos(),
+ Symbols::SavedStackTraceVar(),
+ dynamic_type);
+ current_block_->scope->AddVariable(saved_stack_trace_var);
+ }
}
const intptr_t try_pos = TokenPos();
@@ -9119,12 +9141,7 @@
PushTryBlock(current_block_);
ExpectToken(Token::kLBRACE);
- if (innermost_function().IsAsyncClosure() ||
- innermost_function().IsAsyncFunction() ||
- innermost_function().IsSyncGenClosure() ||
- innermost_function().IsSyncGenerator() ||
- innermost_function().IsAsyncGenerator() ||
- innermost_function().IsAsyncGenClosure()) {
+ if (is_async) {
SetupSavedTryContext(context_var);
}
@@ -9145,6 +9162,8 @@
bool needs_stack_trace = false;
SequenceNode* catch_handler_list =
ParseCatchClauses(handler_pos, exception_var, stack_trace_var,
+ is_async ? saved_exception_var : exception_var,
+ is_async ? saved_stack_trace_var : stack_trace_var,
handler_types, &needs_stack_trace);
TryBlocks* inner_try_block = PopTryBlock();
@@ -9184,6 +9203,8 @@
context_var,
exception_var,
stack_trace_var,
+ is_async ? saved_exception_var : exception_var,
+ is_async ? saved_stack_trace_var : stack_trace_var,
(finally_block != NULL) ?
AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex,
needs_stack_trace);
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698