| Index: runtime/vm/parser.cc
|
| ===================================================================
|
| --- runtime/vm/parser.cc (revision 6144)
|
| +++ runtime/vm/parser.cc (working copy)
|
| @@ -100,8 +100,7 @@
|
| }
|
|
|
|
|
| -static ThrowNode* CreateEvalConstConstructorThrow(intptr_t token_pos,
|
| - const Object& obj) {
|
| +static ThrowNode* GenerateRethrow(intptr_t token_pos, const Object& obj) {
|
| UnhandledException& excp = UnhandledException::Handle();
|
| excp ^= obj.raw();
|
| const Instance& exception = Instance::ZoneHandle(excp.exception());
|
| @@ -5157,7 +5156,7 @@
|
| }
|
| if (!generic_catch_seen) {
|
| // No generic catch handler exists so execute this finally block
|
| - // before rethrowing the excetion.
|
| + // before rethrowing the exception.
|
| finally_block = ParseFinallyBlock();
|
| catch_handler_list->Add(finally_block);
|
| token_index_ = finally_pos;
|
| @@ -6179,9 +6178,12 @@
|
| AstNode* Parser::GenerateStaticFieldLookup(const Field& field,
|
| intptr_t ident_pos) {
|
| // Run static field initializer first if necessary.
|
| - RunStaticFieldInitializer(field);
|
| -
|
| - // Access the field
|
| + // May return an exception throwing ast node.
|
| + AstNode* throw_exception = RunStaticFieldInitializer(field);
|
| + if (throw_exception != NULL) {
|
| + return throw_exception;
|
| + }
|
| + // Access the field.
|
| if (field.is_final()) {
|
| return new LiteralNode(ident_pos, Instance::ZoneHandle(field.value()));
|
| } else {
|
| @@ -6648,7 +6650,10 @@
|
| }
|
|
|
|
|
| -void Parser::RunStaticFieldInitializer(const Field& field) {
|
| +// Returns null on success.
|
| +// Returns a throw node if evaluation of the static initializer results in an
|
| +// unhandled exception.
|
| +AstNode* Parser::RunStaticFieldInitializer(const Field& field) {
|
| ASSERT(field.is_static());
|
| const Instance& value = Instance::Handle(field.value());
|
| if (value.raw() == Object::transition_sentinel()) {
|
| @@ -6679,11 +6684,19 @@
|
| Object& const_value = Object::Handle(
|
| DartEntry::InvokeStatic(func, arguments, kNoArgumentNames));
|
| if (const_value.IsError()) {
|
| + Error& error = Error::Handle();
|
| + error ^= const_value.raw();
|
| if (const_value.IsUnhandledException()) {
|
| - ErrorMsg("exception thrown in Parser::RunStaticFieldInitializer");
|
| + // It is a compile-time error if evaluation of a compile-time constant
|
| + // would raise an exception.
|
| + if (field.is_final()) {
|
| + AppendErrorMsg(error, token_index_,
|
| + "error initializing final field '%s'",
|
| + String::Handle(field.name()).ToCString());
|
| + } else {
|
| + return GenerateRethrow(token_index_, const_value);
|
| + }
|
| } else {
|
| - Error& error = Error::Handle();
|
| - error ^= const_value.raw();
|
| Isolate::Current()->long_jump_base()->Jump(1, error);
|
| }
|
| }
|
| @@ -6695,6 +6708,7 @@
|
| }
|
| field.set_value(instance);
|
| }
|
| + return NULL;
|
| }
|
|
|
|
|
| @@ -7406,7 +7420,7 @@
|
| map_constr,
|
| constr_args));
|
| if (constructor_result.IsUnhandledException()) {
|
| - return CreateEvalConstConstructorThrow(literal_pos, constructor_result);
|
| + return GenerateRethrow(literal_pos, constructor_result);
|
| } else {
|
| Instance& const_instance = Instance::ZoneHandle();
|
| const_instance ^= constructor_result.raw();
|
| @@ -7674,7 +7688,7 @@
|
| constructor,
|
| arguments));
|
| if (constructor_result.IsUnhandledException()) {
|
| - new_object = CreateEvalConstConstructorThrow(new_pos, constructor_result);
|
| + new_object = GenerateRethrow(new_pos, constructor_result);
|
| } else {
|
| Instance& const_instance = Instance::ZoneHandle();
|
| const_instance ^= constructor_result.raw();
|
| @@ -7730,6 +7744,7 @@
|
| interpolate_arg,
|
| kNoArgumentNames);
|
| if (concatenated.IsUnhandledException()) {
|
| + // TODO(regis): Report
|
| ErrorMsg("Exception thrown in Parser::Interpolate");
|
| }
|
| concatenated = String::NewSymbol(concatenated);
|
|
|