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

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

Issue 302383002: VM: Use a fake parsed function when parsing metadata. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 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') | no next file » | 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 "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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698