| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |