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

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

Issue 9958091: Add missing type checks for top level static initializers (issue 1980 and (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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') | tests/co19/co19-runtime.status » ('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 "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 for (int i = 0; i < objs.Length(); i++) { 93 for (int i = 0; i < objs.Length(); i++) {
94 type ^= objs.At(i); 94 type ^= objs.At(i);
95 a.SetTypeAt(i, type); 95 a.SetTypeAt(i, type);
96 } 96 }
97 // Cannot canonicalize TypeArgument yet as its types may not have been 97 // Cannot canonicalize TypeArgument yet as its types may not have been
98 // finalized yet. 98 // finalized yet.
99 return a.raw(); 99 return a.raw();
100 } 100 }
101 101
102 102
103 static ThrowNode* CreateEvalConstConstructorThrow(intptr_t token_pos, 103 static ThrowNode* GenerateRethrow(intptr_t token_pos, const Object& obj) {
104 const Object& obj) {
105 UnhandledException& excp = UnhandledException::Handle(); 104 UnhandledException& excp = UnhandledException::Handle();
106 excp ^= obj.raw(); 105 excp ^= obj.raw();
107 const Instance& exception = Instance::ZoneHandle(excp.exception()); 106 const Instance& exception = Instance::ZoneHandle(excp.exception());
108 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace()); 107 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace());
109 return new ThrowNode(token_pos, 108 return new ThrowNode(token_pos,
110 new LiteralNode(token_pos, exception), 109 new LiteralNode(token_pos, exception),
111 new LiteralNode(token_pos, stack_trace)); 110 new LiteralNode(token_pos, stack_trace));
112 } 111 }
113 112
114 113
(...skipping 5035 matching lines...) Expand 10 before | Expand all | Expand 10 after
5150 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, 5149 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos,
5151 finally_block, 5150 finally_block,
5152 *context_var); 5151 *context_var);
5153 AddFinallyBlockToNode(node_to_inline, node); 5152 AddFinallyBlockToNode(node_to_inline, node);
5154 node_index += 1; 5153 node_index += 1;
5155 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); 5154 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index);
5156 token_index_ = finally_pos; 5155 token_index_ = finally_pos;
5157 } 5156 }
5158 if (!generic_catch_seen) { 5157 if (!generic_catch_seen) {
5159 // No generic catch handler exists so execute this finally block 5158 // No generic catch handler exists so execute this finally block
5160 // before rethrowing the excetion. 5159 // before rethrowing the exception.
5161 finally_block = ParseFinallyBlock(); 5160 finally_block = ParseFinallyBlock();
5162 catch_handler_list->Add(finally_block); 5161 catch_handler_list->Add(finally_block);
5163 token_index_ = finally_pos; 5162 token_index_ = finally_pos;
5164 } 5163 }
5165 finally_block = ParseFinallyBlock(); 5164 finally_block = ParseFinallyBlock();
5166 } else { 5165 } else {
5167 if (!catch_seen) { 5166 if (!catch_seen) {
5168 ErrorMsg("'catch' or 'finally' expected"); 5167 ErrorMsg("'catch' or 'finally' expected");
5169 } 5168 }
5170 } 5169 }
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after
6172 } else { 6171 } else {
6173 access = CallGetter(call_pos, receiver, field_name); 6172 access = CallGetter(call_pos, receiver, field_name);
6174 } 6173 }
6175 return access; 6174 return access;
6176 } 6175 }
6177 6176
6178 6177
6179 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, 6178 AstNode* Parser::GenerateStaticFieldLookup(const Field& field,
6180 intptr_t ident_pos) { 6179 intptr_t ident_pos) {
6181 // Run static field initializer first if necessary. 6180 // Run static field initializer first if necessary.
6182 RunStaticFieldInitializer(field); 6181 // May return an exception throwing ast node.
6183 6182 AstNode* throw_exception = RunStaticFieldInitializer(field);
6184 // Access the field 6183 if (throw_exception != NULL) {
6184 return throw_exception;
6185 }
6186 // Access the field.
6185 if (field.is_final()) { 6187 if (field.is_final()) {
6186 return new LiteralNode(ident_pos, Instance::ZoneHandle(field.value())); 6188 return new LiteralNode(ident_pos, Instance::ZoneHandle(field.value()));
6187 } else { 6189 } else {
6188 return new LoadStaticFieldNode(ident_pos, 6190 return new LoadStaticFieldNode(ident_pos,
6189 Field::ZoneHandle(field.raw())); 6191 Field::ZoneHandle(field.raw()));
6190 } 6192 }
6191 } 6193 }
6192 6194
6193 6195
6194 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, 6196 AstNode* Parser::ParseStaticFieldAccess(const Class& cls,
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
6641 while (outer_function.IsLocalFunction()) { 6643 while (outer_function.IsLocalFunction()) {
6642 outer_function = outer_function.parent_function(); 6644 outer_function = outer_function.parent_function();
6643 } 6645 }
6644 if (outer_function.IsFactory() || !outer_function.is_static()) { 6646 if (outer_function.IsFactory() || !outer_function.is_static()) {
6645 return current_class().NumTypeParameters() > 0; 6647 return current_class().NumTypeParameters() > 0;
6646 } 6648 }
6647 return false; 6649 return false;
6648 } 6650 }
6649 6651
6650 6652
6651 void Parser::RunStaticFieldInitializer(const Field& field) { 6653 // Returns null on success.
6654 // Returns a throw node if evaluation of the static initializer results in an
6655 // unhandled exception.
6656 AstNode* Parser::RunStaticFieldInitializer(const Field& field) {
6652 ASSERT(field.is_static()); 6657 ASSERT(field.is_static());
6653 const Instance& value = Instance::Handle(field.value()); 6658 const Instance& value = Instance::Handle(field.value());
6654 if (value.raw() == Object::transition_sentinel()) { 6659 if (value.raw() == Object::transition_sentinel()) {
6655 ErrorMsg("circular dependency while initializing static field '%s'", 6660 ErrorMsg("circular dependency while initializing static field '%s'",
6656 String::Handle(field.name()).ToCString()); 6661 String::Handle(field.name()).ToCString());
6657 6662
6658 } else if (value.raw() == Object::sentinel()) { 6663 } else if (value.raw() == Object::sentinel()) {
6659 // This field has not been referenced yet and thus the value has 6664 // This field has not been referenced yet and thus the value has
6660 // not been evaluated. Call the static getter method to evaluate 6665 // not been evaluated. Call the static getter method to evaluate
6661 // the expression and canonicalize the value. 6666 // the expression and canonicalize the value.
(...skipping 10 matching lines...) Expand all
6672 Function::Handle(Resolver::ResolveStatic(cls, 6677 Function::Handle(Resolver::ResolveStatic(cls,
6673 getter_name, 6678 getter_name,
6674 kNumArguments, 6679 kNumArguments,
6675 kNoArgumentNames, 6680 kNoArgumentNames,
6676 Resolver::kIsQualified)); 6681 Resolver::kIsQualified));
6677 ASSERT(!func.IsNull()); 6682 ASSERT(!func.IsNull());
6678 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); 6683 ASSERT(func.kind() == RawFunction::kConstImplicitGetter);
6679 Object& const_value = Object::Handle( 6684 Object& const_value = Object::Handle(
6680 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames)); 6685 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames));
6681 if (const_value.IsError()) { 6686 if (const_value.IsError()) {
6687 Error& error = Error::Handle();
6688 error ^= const_value.raw();
6682 if (const_value.IsUnhandledException()) { 6689 if (const_value.IsUnhandledException()) {
6683 ErrorMsg("exception thrown in Parser::RunStaticFieldInitializer"); 6690 // It is a compile-time error if evaluation of a compile-time constant
6691 // would raise an exception.
6692 if (field.is_final()) {
6693 AppendErrorMsg(error, token_index_,
6694 "error initializing final field '%s'",
6695 String::Handle(field.name()).ToCString());
6696 } else {
6697 return GenerateRethrow(token_index_, const_value);
6698 }
6684 } else { 6699 } else {
6685 Error& error = Error::Handle();
6686 error ^= const_value.raw();
6687 Isolate::Current()->long_jump_base()->Jump(1, error); 6700 Isolate::Current()->long_jump_base()->Jump(1, error);
6688 } 6701 }
6689 } 6702 }
6690 ASSERT(const_value.IsNull() || const_value.IsInstance()); 6703 ASSERT(const_value.IsNull() || const_value.IsInstance());
6691 Instance& instance = Instance::Handle(); 6704 Instance& instance = Instance::Handle();
6692 instance ^= const_value.raw(); 6705 instance ^= const_value.raw();
6693 if (!instance.IsNull()) { 6706 if (!instance.IsNull()) {
6694 instance ^= instance.Canonicalize(); 6707 instance ^= instance.Canonicalize();
6695 } 6708 }
6696 field.set_value(instance); 6709 field.set_value(instance);
6697 } 6710 }
6711 return NULL;
6698 } 6712 }
6699 6713
6700 6714
6701 RawObject* Parser::EvaluateConstConstructorCall( 6715 RawObject* Parser::EvaluateConstConstructorCall(
6702 const Class& type_class, 6716 const Class& type_class,
6703 const AbstractTypeArguments& type_arguments, 6717 const AbstractTypeArguments& type_arguments,
6704 const Function& constructor, 6718 const Function& constructor,
6705 ArgumentListNode* arguments) { 6719 ArgumentListNode* arguments) {
6706 // +2 for implicit receiver and construction phase arguments. 6720 // +2 for implicit receiver and construction phase arguments.
6707 GrowableArray<const Object*> arg_values(arguments->length() + 2); 6721 GrowableArray<const Object*> arg_values(arguments->length() + 2);
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
7399 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); 7413 String::Handle(String::NewSymbol(kImmutableMapConstructorName));
7400 const Function& map_constr = Function::ZoneHandle( 7414 const Function& map_constr = Function::ZoneHandle(
7401 immutable_map_class.LookupConstructor(constr_name)); 7415 immutable_map_class.LookupConstructor(constr_name));
7402 ASSERT(!map_constr.IsNull()); 7416 ASSERT(!map_constr.IsNull());
7403 const Object& constructor_result = Object::Handle( 7417 const Object& constructor_result = Object::Handle(
7404 EvaluateConstConstructorCall(immutable_map_class, 7418 EvaluateConstConstructorCall(immutable_map_class,
7405 map_type_arguments, 7419 map_type_arguments,
7406 map_constr, 7420 map_constr,
7407 constr_args)); 7421 constr_args));
7408 if (constructor_result.IsUnhandledException()) { 7422 if (constructor_result.IsUnhandledException()) {
7409 return CreateEvalConstConstructorThrow(literal_pos, constructor_result); 7423 return GenerateRethrow(literal_pos, constructor_result);
7410 } else { 7424 } else {
7411 Instance& const_instance = Instance::ZoneHandle(); 7425 Instance& const_instance = Instance::ZoneHandle();
7412 const_instance ^= constructor_result.raw(); 7426 const_instance ^= constructor_result.raw();
7413 return new LiteralNode(literal_pos, const_instance); 7427 return new LiteralNode(literal_pos, const_instance);
7414 } 7428 }
7415 } else { 7429 } else {
7416 // Factory call at runtime. 7430 // Factory call at runtime.
7417 String& map_literal_factory_class_name = String::Handle( 7431 String& map_literal_factory_class_name = String::Handle(
7418 String::NewSymbol(kMapLiteralFactoryClassName)); 7432 String::NewSymbol(kMapLiteralFactoryClassName));
7419 const Class& map_literal_factory_class = 7433 const Class& map_literal_factory_class =
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
7667 if (type.IsMalformed()) { 7681 if (type.IsMalformed()) {
7668 // Compile the throw of a dynamic type error due to a bound error. 7682 // Compile the throw of a dynamic type error due to a bound error.
7669 return ThrowTypeError(type_pos, type); 7683 return ThrowTypeError(type_pos, type);
7670 } 7684 }
7671 const Object& constructor_result = Object::Handle( 7685 const Object& constructor_result = Object::Handle(
7672 EvaluateConstConstructorCall(constructor_class, 7686 EvaluateConstConstructorCall(constructor_class,
7673 type_arguments, 7687 type_arguments,
7674 constructor, 7688 constructor,
7675 arguments)); 7689 arguments));
7676 if (constructor_result.IsUnhandledException()) { 7690 if (constructor_result.IsUnhandledException()) {
7677 new_object = CreateEvalConstConstructorThrow(new_pos, constructor_result); 7691 new_object = GenerateRethrow(new_pos, constructor_result);
7678 } else { 7692 } else {
7679 Instance& const_instance = Instance::ZoneHandle(); 7693 Instance& const_instance = Instance::ZoneHandle();
7680 const_instance ^= constructor_result.raw(); 7694 const_instance ^= constructor_result.raw();
7681 new_object = new LiteralNode(new_pos, const_instance); 7695 new_object = new LiteralNode(new_pos, const_instance);
7682 } 7696 }
7683 } else { 7697 } else {
7684 CheckFunctionIsCallable(new_pos, constructor); 7698 CheckFunctionIsCallable(new_pos, constructor);
7685 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); 7699 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments);
7686 if (!type_arguments.IsNull() && 7700 if (!type_arguments.IsNull() &&
7687 !type_arguments.IsInstantiated() && 7701 !type_arguments.IsInstantiated() &&
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
7723 GrowableArray<const Object*> interpolate_arg; 7737 GrowableArray<const Object*> interpolate_arg;
7724 interpolate_arg.Add(&value_arr); 7738 interpolate_arg.Add(&value_arr);
7725 const Array& kNoArgumentNames = Array::Handle(); 7739 const Array& kNoArgumentNames = Array::Handle();
7726 7740
7727 // Call interpolation function. 7741 // Call interpolation function.
7728 String& concatenated = String::ZoneHandle(); 7742 String& concatenated = String::ZoneHandle();
7729 concatenated ^= DartEntry::InvokeStatic(func, 7743 concatenated ^= DartEntry::InvokeStatic(func,
7730 interpolate_arg, 7744 interpolate_arg,
7731 kNoArgumentNames); 7745 kNoArgumentNames);
7732 if (concatenated.IsUnhandledException()) { 7746 if (concatenated.IsUnhandledException()) {
7747 // TODO(regis): Report
7733 ErrorMsg("Exception thrown in Parser::Interpolate"); 7748 ErrorMsg("Exception thrown in Parser::Interpolate");
7734 } 7749 }
7735 concatenated = String::NewSymbol(concatenated); 7750 concatenated = String::NewSymbol(concatenated);
7736 return concatenated; 7751 return concatenated;
7737 } 7752 }
7738 7753
7739 7754
7740 // A string literal consists of the concatenation of the next n tokens 7755 // A string literal consists of the concatenation of the next n tokens
7741 // that satisfy the EBNF grammar: 7756 // that satisfy the EBNF grammar:
7742 // literal = kSTRING {{ interpol } kSTRING } 7757 // literal = kSTRING {{ interpol } kSTRING }
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
8265 void Parser::SkipQualIdent() { 8280 void Parser::SkipQualIdent() {
8266 ASSERT(IsIdentifier()); 8281 ASSERT(IsIdentifier());
8267 ConsumeToken(); 8282 ConsumeToken();
8268 if (CurrentToken() == Token::kPERIOD) { 8283 if (CurrentToken() == Token::kPERIOD) {
8269 ConsumeToken(); // Consume the kPERIOD token. 8284 ConsumeToken(); // Consume the kPERIOD token.
8270 ExpectIdentifier("identifier expected after '.'"); 8285 ExpectIdentifier("identifier expected after '.'");
8271 } 8286 }
8272 } 8287 }
8273 8288
8274 } // namespace dart 8289 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698