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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 | 267 |
268 // For parsing a compilation unit. | 268 // For parsing a compilation unit. |
269 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) | 269 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) |
270 : isolate_(Isolate::Current()), | 270 : isolate_(Isolate::Current()), |
271 script_(Script::Handle(isolate_, script.raw())), | 271 script_(Script::Handle(isolate_, script.raw())), |
272 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), | 272 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), |
273 token_pos), | 273 token_pos), |
274 token_kind_(Token::kILLEGAL), | 274 token_kind_(Token::kILLEGAL), |
275 current_block_(NULL), | 275 current_block_(NULL), |
276 is_top_level_(false), | 276 is_top_level_(false), |
277 parsing_metadata_(false), | |
278 current_member_(NULL), | 277 current_member_(NULL), |
279 allow_function_literals_(true), | 278 allow_function_literals_(true), |
280 parsed_function_(NULL), | 279 parsed_function_(NULL), |
281 innermost_function_(Function::Handle(isolate_)), | 280 innermost_function_(Function::Handle(isolate_)), |
282 literal_token_(LiteralToken::Handle(isolate_)), | 281 literal_token_(LiteralToken::Handle(isolate_)), |
283 current_class_(Class::Handle(isolate_)), | 282 current_class_(Class::Handle(isolate_)), |
284 library_(Library::Handle(isolate_, library.raw())), | 283 library_(Library::Handle(isolate_, library.raw())), |
285 try_blocks_list_(NULL), | 284 try_blocks_list_(NULL), |
286 last_used_try_index_(0), | 285 last_used_try_index_(0), |
287 unregister_pending_function_(false) { | 286 unregister_pending_function_(false) { |
288 ASSERT(tokens_iterator_.IsValid()); | 287 ASSERT(tokens_iterator_.IsValid()); |
289 ASSERT(!library.IsNull()); | 288 ASSERT(!library.IsNull()); |
290 } | 289 } |
291 | 290 |
292 | 291 |
293 // For parsing a function. | 292 // For parsing a function. |
294 Parser::Parser(const Script& script, | 293 Parser::Parser(const Script& script, |
295 ParsedFunction* parsed_function, | 294 ParsedFunction* parsed_function, |
296 intptr_t token_position) | 295 intptr_t token_position) |
297 : isolate_(Isolate::Current()), | 296 : isolate_(Isolate::Current()), |
298 script_(Script::Handle(isolate_, script.raw())), | 297 script_(Script::Handle(isolate_, script.raw())), |
299 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), | 298 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), |
300 token_position), | 299 token_position), |
301 token_kind_(Token::kILLEGAL), | 300 token_kind_(Token::kILLEGAL), |
302 current_block_(NULL), | 301 current_block_(NULL), |
303 is_top_level_(false), | 302 is_top_level_(false), |
304 parsing_metadata_(false), | |
305 current_member_(NULL), | 303 current_member_(NULL), |
306 allow_function_literals_(true), | 304 allow_function_literals_(true), |
307 parsed_function_(parsed_function), | 305 parsed_function_(parsed_function), |
308 innermost_function_(Function::Handle(isolate_, | 306 innermost_function_(Function::Handle(isolate_, |
309 parsed_function->function().raw())), | 307 parsed_function->function().raw())), |
310 literal_token_(LiteralToken::Handle(isolate_)), | 308 literal_token_(LiteralToken::Handle(isolate_)), |
311 current_class_(Class::Handle(isolate_, | 309 current_class_(Class::Handle(isolate_, |
312 parsed_function->function().Owner())), | 310 parsed_function->function().Owner())), |
313 library_(Library::Handle(isolate_, Class::Handle( | 311 library_(Library::Handle(isolate_, Class::Handle( |
314 isolate_, | 312 isolate_, |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 parsed_function->set_default_parameter_values(default_parameter_values); | 877 parsed_function->set_default_parameter_values(default_parameter_values); |
880 } | 878 } |
881 | 879 |
882 | 880 |
883 RawObject* Parser::ParseMetadata(const Class& cls, intptr_t token_pos) { | 881 RawObject* Parser::ParseMetadata(const Class& cls, intptr_t token_pos) { |
884 Isolate* isolate = Isolate::Current(); | 882 Isolate* isolate = Isolate::Current(); |
885 StackZone zone(isolate); | 883 StackZone zone(isolate); |
886 LongJumpScope jump; | 884 LongJumpScope jump; |
887 if (setjmp(*jump.Set()) == 0) { | 885 if (setjmp(*jump.Set()) == 0) { |
888 const Script& script = Script::Handle(isolate, cls.script()); | 886 const Script& script = Script::Handle(isolate, cls.script()); |
889 const Library& lib = Library::Handle(isolate, cls.library()); | 887 // Parsing metadata can involve following paths in the parser that are |
890 Parser parser(script, lib, token_pos); | 888 // normally used for expressions and assume current_function is non-null, |
| 889 // so we create a fake function to use as the current_function rather than |
| 890 // scattering special cases throughout the parser. |
| 891 const Function& fake_function = Function::ZoneHandle(Function::New( |
| 892 Symbols::At(), |
| 893 RawFunction::kRegularFunction, |
| 894 true, // is_static |
| 895 false, // is_const |
| 896 false, // is_abstract |
| 897 false, // is_external |
| 898 false, // is_native |
| 899 cls, |
| 900 token_pos)); |
| 901 ParsedFunction* parsed_function = |
| 902 new ParsedFunction(isolate, fake_function); |
| 903 Parser parser(script, parsed_function, token_pos); |
891 parser.set_current_class(cls); | 904 parser.set_current_class(cls); |
892 parser.set_parsing_metadata(true); | |
893 | 905 |
894 RawObject* metadata = parser.EvaluateMetadata(); | 906 RawObject* metadata = parser.EvaluateMetadata(); |
895 return metadata; | 907 return metadata; |
896 } else { | 908 } else { |
897 Error& error = Error::Handle(isolate); | 909 Error& error = Error::Handle(isolate); |
898 error = isolate->object_store()->sticky_error(); | 910 error = isolate->object_store()->sticky_error(); |
899 isolate->object_store()->clear_sticky_error(); | 911 isolate->object_store()->clear_sticky_error(); |
900 return error.raw(); | 912 return error.raw(); |
901 } | 913 } |
902 UNREACHABLE(); | 914 UNREACHABLE(); |
(...skipping 7580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8483 } | 8495 } |
8484 PrimaryNode* primary = node->AsPrimaryNode(); | 8496 PrimaryNode* primary = node->AsPrimaryNode(); |
8485 if (primary->primary().IsString()) { | 8497 if (primary->primary().IsString()) { |
8486 if (primary->IsSuper()) { | 8498 if (primary->IsSuper()) { |
8487 return primary; | 8499 return primary; |
8488 } | 8500 } |
8489 // In a static method, evaluation of an unresolved identifier causes a | 8501 // In a static method, evaluation of an unresolved identifier causes a |
8490 // NoSuchMethodError to be thrown. | 8502 // NoSuchMethodError to be thrown. |
8491 // In an instance method, we convert this into a getter call | 8503 // In an instance method, we convert this into a getter call |
8492 // for a field (which may be defined in a subclass.) | 8504 // for a field (which may be defined in a subclass.) |
8493 // In metadata, an unresolved identifier cannot be a compile-time constant. | |
8494 String& name = String::CheckedZoneHandle(primary->primary().raw()); | 8505 String& name = String::CheckedZoneHandle(primary->primary().raw()); |
8495 if (parsing_metadata_) { | |
8496 ErrorMsg(primary->token_pos(), | |
8497 "unresolved identifier '%s' is not a compile-time constant", | |
8498 name.ToCString()); | |
8499 } | |
8500 if (current_function().is_static() || | 8506 if (current_function().is_static() || |
8501 current_function().IsInFactoryScope()) { | 8507 current_function().IsInFactoryScope()) { |
8502 StaticGetterNode* getter = | 8508 StaticGetterNode* getter = |
8503 new(isolate()) StaticGetterNode( | 8509 new(isolate()) StaticGetterNode( |
8504 primary->token_pos(), | 8510 primary->token_pos(), |
8505 NULL, // No receiver. | 8511 NULL, // No receiver. |
8506 false, // Not a super getter. | 8512 false, // Not a super getter. |
8507 Class::ZoneHandle(I, current_class().raw()), | 8513 Class::ZoneHandle(I, current_class().raw()), |
8508 name); | 8514 name); |
8509 getter->set_is_deferred(primary->is_deferred_reference()); | 8515 getter->set_is_deferred(primary->is_deferred_reference()); |
(...skipping 13 matching lines...) Expand all Loading... |
8523 Function::CheckedZoneHandle(primary->primary().raw()); | 8529 Function::CheckedZoneHandle(primary->primary().raw()); |
8524 const String& funcname = String::ZoneHandle(I, func.name()); | 8530 const String& funcname = String::ZoneHandle(I, func.name()); |
8525 if (func.is_static()) { | 8531 if (func.is_static()) { |
8526 // Static function access. | 8532 // Static function access. |
8527 ClosureNode* closure = | 8533 ClosureNode* closure = |
8528 CreateImplicitClosureNode(func, primary->token_pos(), NULL); | 8534 CreateImplicitClosureNode(func, primary->token_pos(), NULL); |
8529 closure->set_is_deferred(primary->is_deferred_reference()); | 8535 closure->set_is_deferred(primary->is_deferred_reference()); |
8530 return closure; | 8536 return closure; |
8531 } else { | 8537 } else { |
8532 // Instance function access. | 8538 // Instance function access. |
8533 if (parsing_metadata_) { | |
8534 ErrorMsg(primary->token_pos(), | |
8535 "cannot access instance method '%s' from metadata", | |
8536 funcname.ToCString()); | |
8537 } | |
8538 if (current_function().is_static() || | 8539 if (current_function().is_static() || |
8539 current_function().IsInFactoryScope()) { | 8540 current_function().IsInFactoryScope()) { |
8540 ErrorMsg(primary->token_pos(), | 8541 ErrorMsg(primary->token_pos(), |
8541 "cannot access instance method '%s' from static method", | 8542 "cannot access instance method '%s' from static method", |
8542 funcname.ToCString()); | 8543 funcname.ToCString()); |
8543 } | 8544 } |
8544 AstNode* receiver = LoadReceiver(primary->token_pos()); | 8545 AstNode* receiver = LoadReceiver(primary->token_pos()); |
8545 return CallGetter(primary->token_pos(), receiver, funcname); | 8546 return CallGetter(primary->token_pos(), receiver, funcname); |
8546 } | 8547 } |
8547 UNREACHABLE(); | 8548 UNREACHABLE(); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8730 current_class(), type, ClassFinalizer::kCanonicalize); | 8731 current_class(), type, ClassFinalizer::kCanonicalize); |
8731 // Type may be malbounded, but not malformed. | 8732 // Type may be malbounded, but not malformed. |
8732 ASSERT(!type.IsMalformed()); | 8733 ASSERT(!type.IsMalformed()); |
8733 selector = new(isolate()) TypeNode(primary_pos, type); | 8734 selector = new(isolate()) TypeNode(primary_pos, type); |
8734 } else { | 8735 } else { |
8735 UNREACHABLE(); // Internal parser error. | 8736 UNREACHABLE(); // Internal parser error. |
8736 } | 8737 } |
8737 } else { | 8738 } else { |
8738 // Left is not a primary node; this must be a closure call. | 8739 // Left is not a primary node; this must be a closure call. |
8739 AstNode* closure = left; | 8740 AstNode* closure = left; |
8740 if (parsing_metadata_) { | |
8741 // Compiling closure calls involves saving the current context based | |
8742 // on the current function, and metadata has no current function. | |
8743 // Fail early rather than limping along only to discover later that | |
8744 // we parsed something that isn't a compile-time constant. | |
8745 ErrorMsg(closure->token_pos(), | |
8746 "expression is not a valid compile-time constant"); | |
8747 } | |
8748 selector = ParseClosureCall(closure); | 8741 selector = ParseClosureCall(closure); |
8749 } | 8742 } |
8750 } else { | 8743 } else { |
8751 // No (more) selectors to parse. | 8744 // No (more) selectors to parse. |
8752 left = LoadFieldIfUnresolved(left); | 8745 left = LoadFieldIfUnresolved(left); |
8753 if (left->IsPrimaryNode()) { | 8746 if (left->IsPrimaryNode()) { |
8754 PrimaryNode* primary_node = left->AsPrimaryNode(); | 8747 PrimaryNode* primary_node = left->AsPrimaryNode(); |
8755 const intptr_t primary_pos = primary->token_pos(); | 8748 const intptr_t primary_pos = primary->token_pos(); |
8756 if (primary_node->primary().IsFunction()) { | 8749 if (primary_node->primary().IsFunction()) { |
8757 // Treat as implicit closure. | 8750 // Treat as implicit closure. |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8947 // A found name is treated as accessed and possibly marked as captured. | 8940 // A found name is treated as accessed and possibly marked as captured. |
8948 const bool kTestOnly = false; | 8941 const bool kTestOnly = false; |
8949 return current_block_->scope->LookupVariable(ident, kTestOnly); | 8942 return current_block_->scope->LookupVariable(ident, kTestOnly); |
8950 } | 8943 } |
8951 | 8944 |
8952 | 8945 |
8953 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, | 8946 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, |
8954 const String& field_name) { | 8947 const String& field_name) { |
8955 // Fields are not accessible from a static function, except from a | 8948 // Fields are not accessible from a static function, except from a |
8956 // constructor, which is considered as non-static by the compiler. | 8949 // constructor, which is considered as non-static by the compiler. |
8957 if (parsing_metadata_) { | |
8958 ErrorMsg(field_pos, | |
8959 "cannot access instance field '%s' from metadata", | |
8960 field_name.ToCString()); | |
8961 } | |
8962 if (current_function().is_static()) { | 8950 if (current_function().is_static()) { |
8963 ErrorMsg(field_pos, | 8951 ErrorMsg(field_pos, |
8964 "cannot access instance field '%s' from a static function", | 8952 "cannot access instance field '%s' from a static function", |
8965 field_name.ToCString()); | 8953 field_name.ToCString()); |
8966 } | 8954 } |
8967 } | 8955 } |
8968 | 8956 |
8969 | 8957 |
8970 bool Parser::ParsingStaticMember() const { | 8958 bool Parser::ParsingStaticMember() const { |
8971 if (is_top_level_) { | 8959 if (is_top_level_) { |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9139 isolate(), ArgumentsDescriptor::New(num_arguments, arguments->names())); | 9127 isolate(), ArgumentsDescriptor::New(num_arguments, arguments->names())); |
9140 Object& result = Object::Handle(isolate()); | 9128 Object& result = Object::Handle(isolate()); |
9141 { | 9129 { |
9142 PAUSETIMERSCOPE(isolate(), time_compilation); | 9130 PAUSETIMERSCOPE(isolate(), time_compilation); |
9143 result = DartEntry::InvokeFunction( | 9131 result = DartEntry::InvokeFunction( |
9144 constructor, arg_values, args_descriptor); | 9132 constructor, arg_values, args_descriptor); |
9145 } | 9133 } |
9146 if (result.IsError()) { | 9134 if (result.IsError()) { |
9147 // An exception may not occur in every parse attempt, i.e., the | 9135 // An exception may not occur in every parse attempt, i.e., the |
9148 // generated AST is not deterministic. Therefore mark the function as | 9136 // generated AST is not deterministic. Therefore mark the function as |
9149 // not optimizable. Unless we are evaluating metadata, in which case there | 9137 // not optimizable. |
9150 // is no current function. | 9138 current_function().SetIsOptimizable(false); |
9151 if (!parsing_metadata_) { | |
9152 current_function().SetIsOptimizable(false); | |
9153 } | |
9154 if (result.IsUnhandledException()) { | 9139 if (result.IsUnhandledException()) { |
9155 return result.raw(); | 9140 return result.raw(); |
9156 } else { | 9141 } else { |
9157 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); | 9142 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); |
9158 UNREACHABLE(); | 9143 UNREACHABLE(); |
9159 return Object::null(); | 9144 return Object::null(); |
9160 } | 9145 } |
9161 } else { | 9146 } else { |
9162 if (constructor.IsFactory()) { | 9147 if (constructor.IsFactory()) { |
9163 // The factory method returns the allocated object. | 9148 // The factory method returns the allocated object. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9240 return true; | 9225 return true; |
9241 } else if (func.IsStaticFunction()) { | 9226 } else if (func.IsStaticFunction()) { |
9242 if (node != NULL) { | 9227 if (node != NULL) { |
9243 ASSERT(AbstractType::Handle(isolate(), | 9228 ASSERT(AbstractType::Handle(isolate(), |
9244 func.result_type()).IsResolved()); | 9229 func.result_type()).IsResolved()); |
9245 // The static getter may later be changed into a dynamically | 9230 // The static getter may later be changed into a dynamically |
9246 // resolved instance setter if no static setter can | 9231 // resolved instance setter if no static setter can |
9247 // be found. | 9232 // be found. |
9248 AstNode* receiver = NULL; | 9233 AstNode* receiver = NULL; |
9249 const bool kTestOnly = true; | 9234 const bool kTestOnly = true; |
9250 if (parsing_metadata_) { | |
9251 ErrorMsg(ident_pos, | |
9252 "'%s' is not a compile-time constant", | |
9253 ident.ToCString()); | |
9254 } | |
9255 if (!current_function().is_static() && | 9235 if (!current_function().is_static() && |
9256 (LookupReceiver(current_block_->scope, kTestOnly) != NULL)) { | 9236 (LookupReceiver(current_block_->scope, kTestOnly) != NULL)) { |
9257 receiver = LoadReceiver(ident_pos); | 9237 receiver = LoadReceiver(ident_pos); |
9258 } | 9238 } |
9259 *node = new(isolate()) StaticGetterNode(ident_pos, | 9239 *node = new(isolate()) StaticGetterNode(ident_pos, |
9260 receiver, | 9240 receiver, |
9261 false, | 9241 false, |
9262 Class::ZoneHandle(I, cls.raw()), | 9242 Class::ZoneHandle(I, cls.raw()), |
9263 ident); | 9243 ident); |
9264 } | 9244 } |
(...skipping 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10633 primary = ParseNewOperator(Token::kCONST); | 10613 primary = ParseNewOperator(Token::kCONST); |
10634 } | 10614 } |
10635 } else if (token == Token::kLT || | 10615 } else if (token == Token::kLT || |
10636 token == Token::kLBRACK || | 10616 token == Token::kLBRACK || |
10637 token == Token::kINDEX || | 10617 token == Token::kINDEX || |
10638 token == Token::kLBRACE) { | 10618 token == Token::kLBRACE) { |
10639 primary = ParseCompoundLiteral(); | 10619 primary = ParseCompoundLiteral(); |
10640 } else if (token == Token::kHASH) { | 10620 } else if (token == Token::kHASH) { |
10641 primary = ParseSymbolLiteral(); | 10621 primary = ParseSymbolLiteral(); |
10642 } else if (token == Token::kSUPER) { | 10622 } else if (token == Token::kSUPER) { |
10643 if (parsing_metadata_) { | |
10644 ErrorMsg("cannot access superclass from metadata"); | |
10645 } | |
10646 if (current_function().is_static()) { | 10623 if (current_function().is_static()) { |
10647 ErrorMsg("cannot access superclass from static method"); | 10624 ErrorMsg("cannot access superclass from static method"); |
10648 } | 10625 } |
10649 if (current_class().SuperClass() == Class::null()) { | 10626 if (current_class().SuperClass() == Class::null()) { |
10650 ErrorMsg("class '%s' does not have a superclass", | 10627 ErrorMsg("class '%s' does not have a superclass", |
10651 String::Handle(isolate(), current_class().Name()).ToCString()); | 10628 String::Handle(isolate(), current_class().Name()).ToCString()); |
10652 } | 10629 } |
10653 if (current_class().IsMixinApplication()) { | 10630 if (current_class().IsMixinApplication()) { |
10654 const Type& mixin_type = Type::Handle(isolate(), current_class().mixin()); | 10631 const Type& mixin_type = Type::Handle(isolate(), current_class().mixin()); |
10655 if (mixin_type.type_class() == current_function().origin()) { | 10632 if (mixin_type.type_class() == current_function().origin()) { |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11050 void Parser::SkipQualIdent() { | 11027 void Parser::SkipQualIdent() { |
11051 ASSERT(IsIdentifier()); | 11028 ASSERT(IsIdentifier()); |
11052 ConsumeToken(); | 11029 ConsumeToken(); |
11053 if (CurrentToken() == Token::kPERIOD) { | 11030 if (CurrentToken() == Token::kPERIOD) { |
11054 ConsumeToken(); // Consume the kPERIOD token. | 11031 ConsumeToken(); // Consume the kPERIOD token. |
11055 ExpectIdentifier("identifier expected after '.'"); | 11032 ExpectIdentifier("identifier expected after '.'"); |
11056 } | 11033 } |
11057 } | 11034 } |
11058 | 11035 |
11059 } // namespace dart | 11036 } // namespace dart |
OLD | NEW |