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

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

Issue 2618823002: VM: Fix bug in deferred loading. (Closed)
Patch Set: Created 3 years, 11 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
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 #include "vm/flags.h" 6 #include "vm/flags.h"
7 7
8 #ifndef DART_PRECOMPILED_RUNTIME 8 #ifndef DART_PRECOMPILED_RUNTIME
9 9
10 #include "lib/invocation_mirror.h" 10 #include "lib/invocation_mirror.h"
(...skipping 10463 matching lines...) Expand 10 before | Expand all | Expand 10 after
10474 const Class& cls, 10474 const Class& cls,
10475 const String& function_name, 10475 const String& function_name,
10476 ArgumentListNode* function_arguments, 10476 ArgumentListNode* function_arguments,
10477 InvocationMirror::Call im_call, 10477 InvocationMirror::Call im_call,
10478 InvocationMirror::Type im_type, 10478 InvocationMirror::Type im_type,
10479 const Function* func, 10479 const Function* func,
10480 const LibraryPrefix* prefix) { 10480 const LibraryPrefix* prefix) {
10481 ArgumentListNode* arguments = new (Z) ArgumentListNode(call_pos); 10481 ArgumentListNode* arguments = new (Z) ArgumentListNode(call_pos);
10482 10482
10483 String& method_name = String::Handle(Z); 10483 String& method_name = String::Handle(Z);
10484 if (prefix == NULL) { 10484 if (prefix == NULL || !prefix->is_deferred_load()) {
10485 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); 10485 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw();
10486 } else { 10486 } else {
10487 arguments->Add(new (Z) LiteralNode(call_pos, *prefix)); 10487 arguments->Add(new (Z) LiteralNode(call_pos, *prefix));
10488 method_name = 10488 method_name =
10489 Library::PrivateCoreLibName(Symbols::ThrowNewIfNotLoaded()).raw(); 10489 Library::PrivateCoreLibName(Symbols::ThrowNewIfNotLoaded()).raw();
10490 } 10490 }
10491 // Object receiver. 10491 // Object receiver.
10492 // If the function is external and dynamic, pass the actual receiver, 10492 // If the function is external and dynamic, pass the actual receiver,
10493 // otherwise, pass a class literal of the unresolved method's owner. 10493 // otherwise, pass a class literal of the unresolved method's owner.
10494 if ((func != NULL) && !func->IsNull() && func->is_external() && 10494 if ((func != NULL) && !func->IsNull() && func->is_external() &&
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after
11212 SetAllowFunctionLiterals(saved_mode); 11212 SetAllowFunctionLiterals(saved_mode);
11213 if (named_argument_seen) { 11213 if (named_argument_seen) {
11214 arguments->set_names(Array::Handle(Z, Array::MakeArray(names))); 11214 arguments->set_names(Array::Handle(Z, Array::MakeArray(names)));
11215 } 11215 }
11216 return arguments; 11216 return arguments;
11217 } 11217 }
11218 11218
11219 11219
11220 AstNode* Parser::ParseStaticCall(const Class& cls, 11220 AstNode* Parser::ParseStaticCall(const Class& cls,
11221 const String& func_name, 11221 const String& func_name,
11222 TokenPosition ident_pos) { 11222 TokenPosition ident_pos,
11223 const LibraryPrefix* prefix) {
11223 TRACE_PARSER("ParseStaticCall"); 11224 TRACE_PARSER("ParseStaticCall");
11224 const TokenPosition call_pos = TokenPos(); 11225 const TokenPosition call_pos = TokenPos();
11225 ASSERT(CurrentToken() == Token::kLPAREN); 11226 ASSERT(CurrentToken() == Token::kLPAREN);
11226 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); 11227 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst);
11227 const int num_arguments = arguments->length(); 11228 const int num_arguments = arguments->length();
11228 const Function& func = Function::ZoneHandle( 11229 const Function& func = Function::ZoneHandle(
11229 Z, Resolver::ResolveStatic(cls, func_name, num_arguments, 11230 Z, Resolver::ResolveStatic(cls, func_name, num_arguments,
11230 arguments->names())); 11231 arguments->names()));
11231 if (func.IsNull()) { 11232 if (func.IsNull()) {
11232 // Check if there is a static field of the same name, it could be a closure 11233 // Check if there is a static field of the same name, it could be a closure
(...skipping 15 matching lines...) Expand all
11248 return BuildClosureCall(call_pos, closure, arguments); 11249 return BuildClosureCall(call_pos, closure, arguments);
11249 } 11250 }
11250 } else { 11251 } else {
11251 closure = GenerateStaticFieldLookup(field, call_pos); 11252 closure = GenerateStaticFieldLookup(field, call_pos);
11252 return BuildClosureCall(call_pos, closure, arguments); 11253 return BuildClosureCall(call_pos, closure, arguments);
11253 } 11254 }
11254 // Could not resolve static method: throw a NoSuchMethodError. 11255 // Could not resolve static method: throw a NoSuchMethodError.
11255 return ThrowNoSuchMethodError(ident_pos, cls, func_name, arguments, 11256 return ThrowNoSuchMethodError(ident_pos, cls, func_name, arguments,
11256 InvocationMirror::kStatic, 11257 InvocationMirror::kStatic,
11257 InvocationMirror::kMethod, 11258 InvocationMirror::kMethod,
11258 NULL); // No existing function. 11259 NULL, // No existing function.
11260 prefix);
rmacnak 2017/01/05 22:50:11 Please add an assert in ThrowNoSuchMethodError tha
Florian Schneider 2017/01/06 02:12:12 Done.
11259 } else if (cls.IsTopLevel() && (cls.library() == Library::CoreLibrary()) && 11261 } else if (cls.IsTopLevel() && (cls.library() == Library::CoreLibrary()) &&
11260 (func.name() == Symbols::Identical().raw())) { 11262 (func.name() == Symbols::Identical().raw())) {
11261 // This is the predefined toplevel function identical(a,b). 11263 // This is the predefined toplevel function identical(a,b).
11262 // Create a comparison node instead of a static call to the function. 11264 // Create a comparison node instead of a static call to the function.
11263 ASSERT(num_arguments == 2); 11265 ASSERT(num_arguments == 2);
11264 11266
11265 // If both arguments are constant expressions of type string, 11267 // If both arguments are constant expressions of type string,
11266 // evaluate and canonicalize them. 11268 // evaluate and canonicalize them.
11267 // This guarantees that identical("ab", "a"+"b") is true. 11269 // This guarantees that identical("ab", "a"+"b") is true.
11268 // An alternative way to guarantee this would be to introduce 11270 // An alternative way to guarantee this would be to introduce
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
11385 if (primary->primary().IsString()) { 11387 if (primary->primary().IsString()) {
11386 if (primary->IsSuper()) { 11388 if (primary->IsSuper()) {
11387 return primary; 11389 return primary;
11388 } 11390 }
11389 // In a static method, evaluation of an unresolved identifier causes a 11391 // In a static method, evaluation of an unresolved identifier causes a
11390 // NoSuchMethodError to be thrown. 11392 // NoSuchMethodError to be thrown.
11391 // In an instance method, we convert this into a getter call 11393 // In an instance method, we convert this into a getter call
11392 // for a field (which may be defined in a subclass.) 11394 // for a field (which may be defined in a subclass.)
11393 const String& name = 11395 const String& name =
11394 String::Cast(Object::ZoneHandle(primary->primary().raw())); 11396 String::Cast(Object::ZoneHandle(primary->primary().raw()));
11395 if (current_function().is_static() || 11397 if (primary->is_deferred_reference()) {
11396 current_function().IsInFactoryScope()) { 11398 StaticGetterNode* getter = new (Z) StaticGetterNode(
11399 primary->token_pos(),
11400 NULL, // No receiver.
11401 Class::ZoneHandle(Z, library_.toplevel_class()), name);
11402 getter->set_is_deferred(primary->is_deferred_reference());
11403 return getter;
11404 } else if (current_function().is_static() ||
11405 current_function().IsInFactoryScope()) {
11397 StaticGetterNode* getter = new (Z) 11406 StaticGetterNode* getter = new (Z)
11398 StaticGetterNode(primary->token_pos(), 11407 StaticGetterNode(primary->token_pos(),
11399 NULL, // No receiver. 11408 NULL, // No receiver.
11400 Class::ZoneHandle(Z, current_class().raw()), name); 11409 Class::ZoneHandle(Z, current_class().raw()), name);
11401 getter->set_is_deferred(primary->is_deferred_reference()); 11410 getter->set_is_deferred(primary->is_deferred_reference());
11402 return getter; 11411 return getter;
11403 } else { 11412 } else {
11404 AstNode* receiver = LoadReceiver(primary->token_pos()); 11413 AstNode* receiver = LoadReceiver(primary->token_pos());
11405 return CallGetter(node->token_pos(), receiver, name); 11414 return CallGetter(node->token_pos(), receiver, name);
11406 } 11415 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
11499 // method call. 11508 // method call.
11500 if (CurrentToken() == Token::kLT) { 11509 if (CurrentToken() == Token::kLT) {
11501 // Type arguments. 11510 // Type arguments.
11502 if (!FLAG_generic_method_syntax) { 11511 if (!FLAG_generic_method_syntax) {
11503 ReportError("generic type arguments not supported."); 11512 ReportError("generic type arguments not supported.");
11504 } 11513 }
11505 // TODO(regis): Pass type arguments in generic call. 11514 // TODO(regis): Pass type arguments in generic call.
11506 // For now, resolve type arguments and ignore. 11515 // For now, resolve type arguments and ignore.
11507 ParseTypeArguments(ClassFinalizer::kCanonicalize); 11516 ParseTypeArguments(ClassFinalizer::kCanonicalize);
11508 } 11517 }
11509 if (left->IsPrimaryNode() && 11518 PrimaryNode* primary_node = left->AsPrimaryNode();
11510 left->AsPrimaryNode()->primary().IsClass()) { 11519 if ((primary_node != NULL) && primary_node->primary().IsClass()) {
11511 // Static method call prefixed with class name. 11520 // Static method call prefixed with class name.
11512 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); 11521 const Class& cls = Class::Cast(primary_node->primary());
11513 selector = ParseStaticCall(cls, *ident, ident_pos); 11522 selector =
11523 ParseStaticCall(cls, *ident, ident_pos, primary_node->prefix());
11514 } else { 11524 } else {
11515 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional); 11525 if ((primary_node != NULL) && primary_node->is_deferred_reference()) {
11526 const Class& cls = Class::Handle(library_.toplevel_class());
11527 selector =
11528 ParseStaticCall(cls, *ident, ident_pos, primary_node->prefix());
11529 } else {
11530 selector =
11531 ParseInstanceCall(left, *ident, ident_pos, is_conditional);
11532 }
11516 } 11533 }
11517 } else { 11534 } else {
11518 // Field access. 11535 // Field access.
11519 Class& cls = Class::Handle(Z); 11536 Class& cls = Class::Handle(Z);
11520 bool is_deferred = false; 11537 bool is_deferred = false;
11521 if (left->IsPrimaryNode()) { 11538 if (left->IsPrimaryNode()) {
11522 PrimaryNode* primary_node = left->AsPrimaryNode(); 11539 PrimaryNode* primary_node = left->AsPrimaryNode();
11540 is_deferred = primary_node->is_deferred_reference();
11523 if (primary_node->primary().IsClass()) { 11541 if (primary_node->primary().IsClass()) {
11524 // If the primary node referred to a class we are loading a 11542 // If the primary node referred to a class we are loading a
11525 // qualified static field. 11543 // qualified static field.
11526 cls ^= primary_node->primary().raw(); 11544 cls ^= primary_node->primary().raw();
11527 is_deferred = primary_node->is_deferred_reference(); 11545 } else if (is_deferred) {
11546 cls = library_.toplevel_class();
11528 } 11547 }
11529 } 11548 }
11530 if (cls.IsNull()) { 11549 if (cls.IsNull()) {
11531 // Instance field access. 11550 // Instance field access.
11532 selector = new (Z) 11551 selector = new (Z)
11533 InstanceGetterNode(ident_pos, left, *ident, is_conditional); 11552 InstanceGetterNode(ident_pos, left, *ident, is_conditional);
11534 } else { 11553 } else {
11535 // Static field access. 11554 // Static field access.
11536 selector = GenerateStaticFieldAccess(cls, *ident, ident_pos); 11555 selector = GenerateStaticFieldAccess(cls, *ident, ident_pos);
11537 ASSERT(selector != NULL); 11556 ASSERT(selector != NULL);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
11609 ParseInstanceCall(LoadReceiver(primary_pos), func_name, 11628 ParseInstanceCall(LoadReceiver(primary_pos), func_name,
11610 primary_pos, false /* is_conditional */); 11629 primary_pos, false /* is_conditional */);
11611 } 11630 }
11612 } else if (primary_node->primary().IsString()) { 11631 } else if (primary_node->primary().IsString()) {
11613 // Primary is an unresolved name. 11632 // Primary is an unresolved name.
11614 if (primary_node->IsSuper()) { 11633 if (primary_node->IsSuper()) {
11615 ReportError(primary_pos, "illegal use of super"); 11634 ReportError(primary_pos, "illegal use of super");
11616 } 11635 }
11617 const String& name = 11636 const String& name =
11618 String::Cast(Object::ZoneHandle(primary_node->primary().raw())); 11637 String::Cast(Object::ZoneHandle(primary_node->primary().raw()));
11619 if (current_function().is_static()) { 11638 if (primary_node->is_deferred_reference()) {
11639 // The static call will be converted to throwing a NSM error.
11640 const Class& cls = Class::Handle(library_.toplevel_class());
11641 selector =
11642 ParseStaticCall(cls, name, primary_pos, primary_node->prefix());
11643 } else if (current_function().is_static()) {
11620 // The static call will be converted to throwing a NSM error. 11644 // The static call will be converted to throwing a NSM error.
11621 selector = ParseStaticCall(current_class(), name, primary_pos); 11645 selector = ParseStaticCall(current_class(), name, primary_pos);
11622 } else { 11646 } else {
11623 // Treat as call to unresolved (instance) method. 11647 // Treat as call to unresolved (instance) method.
11624 selector = 11648 selector =
11625 ParseInstanceCall(LoadReceiver(primary_pos), name, primary_pos, 11649 ParseInstanceCall(LoadReceiver(primary_pos), name, primary_pos,
11626 false /* is_conditional */); 11650 false /* is_conditional */);
11627 } 11651 }
11628 } else if (primary_node->primary().IsTypeParameter()) { 11652 } else if (primary_node->primary().IsTypeParameter()) {
11629 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); 11653 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z);
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
12496 } 12520 }
12497 } 12521 }
12498 const bool is_deferred = prefix.is_deferred_load(); 12522 const bool is_deferred = prefix.is_deferred_load();
12499 if (obj.IsNull()) { 12523 if (obj.IsNull()) {
12500 // Unresolved prefixed primary identifier. 12524 // Unresolved prefixed primary identifier.
12501 return NULL; 12525 return NULL;
12502 } else if (obj.IsClass()) { 12526 } else if (obj.IsClass()) {
12503 const Class& cls = Class::Cast(obj); 12527 const Class& cls = Class::Cast(obj);
12504 PrimaryNode* primary = 12528 PrimaryNode* primary =
12505 new (Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); 12529 new (Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw()));
12506 primary->set_is_deferred(is_deferred); 12530 if (is_deferred) {
12531 primary->set_prefix(&prefix);
12532 }
12507 return primary; 12533 return primary;
12508 } else if (obj.IsField()) { 12534 } else if (obj.IsField()) {
12509 const Field& field = Field::Cast(obj); 12535 const Field& field = Field::Cast(obj);
12510 ASSERT(field.is_static()); 12536 ASSERT(field.is_static());
12511 AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos); 12537 AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos);
12512 ASSERT(get_field != NULL); 12538 ASSERT(get_field != NULL);
12513 ASSERT(get_field->IsLoadStaticFieldNode() || 12539 ASSERT(get_field->IsLoadStaticFieldNode() ||
12514 get_field->IsStaticGetterNode()); 12540 get_field->IsStaticGetterNode());
12515 if (get_field->IsLoadStaticFieldNode()) { 12541 if (get_field->IsLoadStaticFieldNode()) {
12516 get_field->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); 12542 get_field->AsLoadStaticFieldNode()->set_is_deferred(is_deferred);
12517 } else if (get_field->IsStaticGetterNode()) { 12543 } else if (get_field->IsStaticGetterNode()) {
12518 get_field->AsStaticGetterNode()->set_is_deferred(is_deferred); 12544 get_field->AsStaticGetterNode()->set_is_deferred(is_deferred);
12519 get_field->AsStaticGetterNode()->set_owner(prefix); 12545 get_field->AsStaticGetterNode()->set_owner(prefix);
12520 } 12546 }
12521 return get_field; 12547 return get_field;
12522 } else if (obj.IsFunction()) { 12548 } else if (obj.IsFunction()) {
12523 const Function& func = Function::Cast(obj); 12549 const Function& func = Function::Cast(obj);
12524 ASSERT(func.is_static()); 12550 ASSERT(func.is_static());
12525 if (func.IsGetterFunction() || func.IsSetterFunction()) { 12551 if (func.IsGetterFunction() || func.IsSetterFunction()) {
12526 StaticGetterNode* getter = new (Z) StaticGetterNode( 12552 StaticGetterNode* getter = new (Z) StaticGetterNode(
12527 ident_pos, 12553 ident_pos,
12528 /* receiver */ NULL, Class::ZoneHandle(Z, func.Owner()), ident); 12554 /* receiver */ NULL, Class::ZoneHandle(Z, func.Owner()), ident);
12529 getter->set_is_deferred(is_deferred); 12555 getter->set_is_deferred(is_deferred);
12530 getter->set_owner(prefix); 12556 getter->set_owner(prefix);
12531 return getter; 12557 return getter;
12532 } else { 12558 } else {
12533 PrimaryNode* primary = 12559 PrimaryNode* primary =
12534 new (Z) PrimaryNode(ident_pos, Function::ZoneHandle(Z, func.raw())); 12560 new (Z) PrimaryNode(ident_pos, Function::ZoneHandle(Z, func.raw()));
12535 primary->set_is_deferred(is_deferred); 12561 if (is_deferred) {
12562 primary->set_prefix(&prefix);
12563 }
12536 return primary; 12564 return primary;
12537 } 12565 }
12538 } 12566 }
12539 // All possible object types are handled above. 12567 // All possible object types are handled above.
12540 UNREACHABLE(); 12568 UNREACHABLE();
12541 return NULL; 12569 return NULL;
12542 } 12570 }
12543 12571
12544 12572
12545 // Resolve identifier. Issue an error message if 12573 // Resolve identifier. Issue an error message if
(...skipping 1416 matching lines...) Expand 10 before | Expand all | Expand 10 after
13962 ConsumeToken(); // Prefix name. 13990 ConsumeToken(); // Prefix name.
13963 primary = new (Z) LiteralNode(qual_ident_pos, prefix); 13991 primary = new (Z) LiteralNode(qual_ident_pos, prefix);
13964 } else { 13992 } else {
13965 GrowableHandlePtrArray<const String> pieces(Z, 3); 13993 GrowableHandlePtrArray<const String> pieces(Z, 3);
13966 pieces.Add(String::Handle(Z, prefix.name())); 13994 pieces.Add(String::Handle(Z, prefix.name()));
13967 pieces.Add(Symbols::Dot()); 13995 pieces.Add(Symbols::Dot());
13968 pieces.Add(ident); 13996 pieces.Add(ident);
13969 const String& qualified_name = 13997 const String& qualified_name =
13970 String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces)); 13998 String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces));
13971 primary = new (Z) PrimaryNode(qual_ident_pos, qualified_name); 13999 primary = new (Z) PrimaryNode(qual_ident_pos, qualified_name);
14000 if (prefix.is_deferred_load()) {
14001 primary->AsPrimaryNode()->set_prefix(&prefix);
14002 }
13972 } 14003 }
13973 } else if (FLAG_load_deferred_eagerly && prefix.is_deferred_load()) { 14004 } else if (FLAG_load_deferred_eagerly && prefix.is_deferred_load()) {
13974 // primary != NULL. 14005 // primary != NULL.
13975 GrowableHandlePtrArray<const String> pieces(Z, 3); 14006 GrowableHandlePtrArray<const String> pieces(Z, 3);
13976 pieces.Add(String::Handle(Z, prefix.name())); 14007 pieces.Add(String::Handle(Z, prefix.name()));
13977 pieces.Add(Symbols::Dot()); 14008 pieces.Add(Symbols::Dot());
13978 pieces.Add(ident); 14009 pieces.Add(ident);
13979 const String& qualified_name = 14010 const String& qualified_name =
13980 String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces)); 14011 String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces));
13981 InvocationMirror::Type call_type = CurrentToken() == Token::kLPAREN 14012 InvocationMirror::Type call_type = CurrentToken() == Token::kLPAREN
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
14593 const ArgumentListNode& function_args, 14624 const ArgumentListNode& function_args,
14594 const LocalVariable* temp_for_last_arg, 14625 const LocalVariable* temp_for_last_arg,
14595 bool is_super_invocation) { 14626 bool is_super_invocation) {
14596 UNREACHABLE(); 14627 UNREACHABLE();
14597 return NULL; 14628 return NULL;
14598 } 14629 }
14599 14630
14600 } // namespace dart 14631 } // namespace dart
14601 14632
14602 #endif // DART_PRECOMPILED_RUNTIME 14633 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698