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

Unified Diff: dart/runtime/vm/parser.cc

Issue 57813002: Version 0.8.10.3 (Closed) Base URL: http://dart.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 1 month 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 | « dart/runtime/vm/object.cc ('k') | dart/samples/dartiverse_search/github_search_engine.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dart/runtime/vm/parser.cc
===================================================================
--- dart/runtime/vm/parser.cc (revision 29802)
+++ dart/runtime/vm/parser.cc (working copy)
@@ -1015,23 +1015,17 @@
ident_pos,
field,
new LiteralNode(ident_pos, Object::transition_sentinel())));
- // TODO(hausner): If evaluation of the field value throws an exception,
- // we leave the field value as 'transition_sentinel', which is wrong.
- // A second reference to the field later throws a circular dependency
- // exception. The field should instead be set to null after an exception.
- const String& init_name =
- String::Handle(Symbols::New(String::Handle(
- String::Concat(Symbols::InitPrefix(), String::Handle(field.name())))));
+ const String& init_name = String::Handle(
+ Symbols::New(String::Handle(String::Concat(
+ Symbols::InitPrefix(), String::Handle(field.name())))));
const Function& init_function = Function::ZoneHandle(
field_class.LookupStaticFunction(init_name));
ASSERT(!init_function.IsNull());
ArgumentListNode* arguments = new ArgumentListNode(expr_pos);
StaticCallNode* init_call =
new StaticCallNode(expr_pos, init_function, arguments);
+ initialize_field->Add(init_call);
- initialize_field->Add(new StoreStaticFieldNode(ident_pos,
- field,
- init_call));
AstNode* uninitialized_check =
new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL);
current_block_->statements->Add(uninitialized_check);
@@ -1057,10 +1051,96 @@
OpenFunctionBlock(func);
AddFormalParamsToScope(&params, current_block_->scope);
- intptr_t expr_pos = func.token_pos();
+ // Move forward to the start of the initializer expression.
+ ExpectIdentifier("identifier expected");
+ ExpectToken(Token::kASSIGN);
+ intptr_t token_pos = TokenPos();
+
+ // Synthesize a try-catch block to wrap the initializer expression.
+ LocalVariable* context_var =
+ current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar());
+ if (context_var == NULL) {
+ context_var = new LocalVariable(token_pos,
+ Symbols::SavedTryContextVar(),
+ Type::ZoneHandle(Type::DynamicType()));
+ current_block_->scope->AddVariable(context_var);
+ }
+ LocalVariable* catch_excp_var =
+ current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar());
+ if (catch_excp_var == NULL) {
+ catch_excp_var = new LocalVariable(token_pos,
+ Symbols::ExceptionVar(),
+ Type::ZoneHandle(Type::DynamicType()));
+ current_block_->scope->AddVariable(catch_excp_var);
+ }
+ LocalVariable* catch_trace_var =
+ current_block_->scope->LocalLookupVariable(Symbols::StacktraceVar());
+ if (catch_trace_var == NULL) {
+ catch_trace_var = new LocalVariable(token_pos,
+ Symbols::StacktraceVar(),
+ Type::ZoneHandle(Type::DynamicType()));
+ current_block_->scope->AddVariable(catch_trace_var);
+ }
+
+ OpenBlock(); // Start try block.
AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
- ReturnNode* return_node = new ReturnNode(expr_pos, expr);
- current_block_->statements->Add(return_node);
+ const Field& field = Field::ZoneHandle(func.saved_static_field());
+ ASSERT(!field.is_const());
+ StoreStaticFieldNode* store = new StoreStaticFieldNode(field.token_pos(),
+ field,
+ expr);
+ current_block_->statements->Add(store);
+ SequenceNode* try_block = CloseBlock(); // End try block.
+
+ OpenBlock(); // Start catch handler list.
+ SourceLabel* end_catch_label =
+ SourceLabel::New(token_pos, NULL, SourceLabel::kCatch);
+ current_block_->scope->AddLabel(end_catch_label);
+
+ OpenBlock(); // Start catch clause.
+ AstNode* compare_transition_sentinel = new ComparisonNode(
+ token_pos,
+ Token::kEQ_STRICT,
+ new LoadStaticFieldNode(token_pos, field),
+ new LiteralNode(field.token_pos(), Object::transition_sentinel()));
+
+ SequenceNode* store_null = new SequenceNode(token_pos, NULL);
+ store_null->Add(new StoreStaticFieldNode(
+ field.token_pos(),
+ field,
+ new LiteralNode(token_pos, Instance::ZoneHandle())));
+ AstNode* transition_sentinel_check =
+ new IfNode(token_pos, compare_transition_sentinel, store_null, NULL);
+ current_block_->statements->Add(transition_sentinel_check);
+
+ current_block_->statements->Add(
+ new ThrowNode(token_pos,
+ new LoadLocalNode(token_pos, catch_excp_var),
+ new LoadLocalNode(token_pos, catch_trace_var)));
+ current_block_->statements->Add(
+ new JumpNode(token_pos, Token::kCONTINUE, end_catch_label));
+ SequenceNode* catch_clause = CloseBlock(); // End catch clause.
+
+ current_block_->statements->Add(catch_clause);
+ SequenceNode* catch_handler_list = CloseBlock(); // End catch handler list.
+ CatchClauseNode* catch_block =
+ new CatchClauseNode(token_pos,
+ catch_handler_list,
+ Array::ZoneHandle(Object::empty_array().raw()),
+ context_var,
+ catch_excp_var,
+ catch_trace_var,
+ CatchClauseNode::kInvalidTryIndex,
+ false); // No stack trace needed.
+
+ AstNode* try_catch_node = new TryCatchNode(token_pos,
+ try_block,
+ end_catch_label,
+ context_var,
+ catch_block,
+ NULL, // No finally block.
+ AllocateTryIndex());
+ current_block_->statements->Add(try_catch_node);
return CloseBlock();
}
@@ -3307,7 +3387,6 @@
Function& setter = Function::Handle();
Field& class_field = Field::ZoneHandle();
Instance& init_value = Instance::Handle();
- intptr_t expr_pos = -1;
while (true) {
bool has_initializer = CurrentToken() == Token::kASSIGN;
bool has_simple_literal = false;
@@ -3332,7 +3411,6 @@
(LookaheadToken(1) == Token::kSEMICOLON)) {
has_simple_literal = IsSimpleLiteral(*field->type, &init_value);
}
- expr_pos = TokenPos();
SkipExpr();
} else {
// Static const and static final fields must have an initializer.
@@ -3377,13 +3455,12 @@
getter.set_result_type(*field->type);
members->AddFunction(getter);
- // Create initializer function.
- const Function& init_function = Function::ZoneHandle(
- Function::NewStaticInitializer(*field->name,
- *field->type,
- current_class(),
- expr_pos));
- members->AddFunction(init_function);
+ // Create initializer function for non-const fields.
+ if (!class_field.is_const()) {
+ const Function& init_function = Function::ZoneHandle(
+ Function::NewStaticInitializer(class_field));
+ members->AddFunction(init_function);
+ }
}
}
@@ -4493,7 +4570,6 @@
if ((is_const || is_final) && (LookaheadToken(1) == Token::kSEMICOLON)) {
has_simple_literal = IsSimpleLiteral(type, &field_value);
}
- const intptr_t expr_pos = TokenPos();
SkipExpr();
field.set_value(field_value);
if (!has_simple_literal) {
@@ -4511,12 +4587,11 @@
top_level->functions.Add(getter);
// Create initializer function.
- const Function& init_function = Function::ZoneHandle(
- Function::NewStaticInitializer(var_name,
- type,
- current_class(),
- expr_pos));
- top_level->functions.Add(init_function);
+ if (!field.is_const()) {
+ const Function& init_function = Function::ZoneHandle(
+ Function::NewStaticInitializer(field));
+ top_level->functions.Add(init_function);
+ }
}
} else if (is_final) {
ErrorMsg(name_pos, "missing initializer for final or const variable");
@@ -6742,7 +6817,6 @@
// operator.
bool catch_seen = false;
bool generic_catch_seen = false;
- SequenceNode* catch_handler_list = NULL;
const intptr_t handler_pos = TokenPos();
OpenBlock(); // Start the catch block sequence.
current_block_->scope->AddLabel(end_catch_label);
@@ -6866,7 +6940,7 @@
// Add this individual catch handler to the catch handlers list.
current_block_->statements->Add(catch_clause);
}
- catch_handler_list = CloseBlock();
+ SequenceNode* catch_handler_list = CloseBlock();
TryBlocks* inner_try_block = PopTryBlock();
const intptr_t try_index = inner_try_block->try_index();
TryBlocks* outer_try_block = try_blocks_list_;
« no previous file with comments | « dart/runtime/vm/object.cc ('k') | dart/samples/dartiverse_search/github_search_engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698