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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index c8d2aa1a51760d28959424faff94ec01121e017d..7c250ae19bfe476a5993b800a04577af032aa4cd 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -10481,7 +10481,7 @@ AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos,
ArgumentListNode* arguments = new (Z) ArgumentListNode(call_pos);
String& method_name = String::Handle(Z);
- if (prefix == NULL) {
+ if (prefix == NULL || !prefix->is_deferred_load()) {
method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw();
} else {
arguments->Add(new (Z) LiteralNode(call_pos, *prefix));
@@ -11219,7 +11219,8 @@ ArgumentListNode* Parser::ParseActualParameters(
AstNode* Parser::ParseStaticCall(const Class& cls,
const String& func_name,
- TokenPosition ident_pos) {
+ TokenPosition ident_pos,
+ const LibraryPrefix* prefix) {
TRACE_PARSER("ParseStaticCall");
const TokenPosition call_pos = TokenPos();
ASSERT(CurrentToken() == Token::kLPAREN);
@@ -11255,7 +11256,8 @@ AstNode* Parser::ParseStaticCall(const Class& cls,
return ThrowNoSuchMethodError(ident_pos, cls, func_name, arguments,
InvocationMirror::kStatic,
InvocationMirror::kMethod,
- NULL); // No existing function.
+ NULL, // No existing function.
+ prefix);
rmacnak 2017/01/05 22:50:11 Please add an assert in ThrowNoSuchMethodError tha
Florian Schneider 2017/01/06 02:12:12 Done.
} else if (cls.IsTopLevel() && (cls.library() == Library::CoreLibrary()) &&
(func.name() == Symbols::Identical().raw())) {
// This is the predefined toplevel function identical(a,b).
@@ -11392,8 +11394,15 @@ AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) {
// for a field (which may be defined in a subclass.)
const String& name =
String::Cast(Object::ZoneHandle(primary->primary().raw()));
- if (current_function().is_static() ||
- current_function().IsInFactoryScope()) {
+ if (primary->is_deferred_reference()) {
+ StaticGetterNode* getter = new (Z) StaticGetterNode(
+ primary->token_pos(),
+ NULL, // No receiver.
+ Class::ZoneHandle(Z, library_.toplevel_class()), name);
+ getter->set_is_deferred(primary->is_deferred_reference());
+ return getter;
+ } else if (current_function().is_static() ||
+ current_function().IsInFactoryScope()) {
StaticGetterNode* getter = new (Z)
StaticGetterNode(primary->token_pos(),
NULL, // No receiver.
@@ -11506,13 +11515,21 @@ AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) {
// For now, resolve type arguments and ignore.
ParseTypeArguments(ClassFinalizer::kCanonicalize);
}
- if (left->IsPrimaryNode() &&
- left->AsPrimaryNode()->primary().IsClass()) {
+ PrimaryNode* primary_node = left->AsPrimaryNode();
+ if ((primary_node != NULL) && primary_node->primary().IsClass()) {
// Static method call prefixed with class name.
- const Class& cls = Class::Cast(left->AsPrimaryNode()->primary());
- selector = ParseStaticCall(cls, *ident, ident_pos);
+ const Class& cls = Class::Cast(primary_node->primary());
+ selector =
+ ParseStaticCall(cls, *ident, ident_pos, primary_node->prefix());
} else {
- selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional);
+ if ((primary_node != NULL) && primary_node->is_deferred_reference()) {
+ const Class& cls = Class::Handle(library_.toplevel_class());
+ selector =
+ ParseStaticCall(cls, *ident, ident_pos, primary_node->prefix());
+ } else {
+ selector =
+ ParseInstanceCall(left, *ident, ident_pos, is_conditional);
+ }
}
} else {
// Field access.
@@ -11520,11 +11537,13 @@ AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) {
bool is_deferred = false;
if (left->IsPrimaryNode()) {
PrimaryNode* primary_node = left->AsPrimaryNode();
+ is_deferred = primary_node->is_deferred_reference();
if (primary_node->primary().IsClass()) {
// If the primary node referred to a class we are loading a
// qualified static field.
cls ^= primary_node->primary().raw();
- is_deferred = primary_node->is_deferred_reference();
+ } else if (is_deferred) {
+ cls = library_.toplevel_class();
}
}
if (cls.IsNull()) {
@@ -11616,7 +11635,12 @@ AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) {
}
const String& name =
String::Cast(Object::ZoneHandle(primary_node->primary().raw()));
- if (current_function().is_static()) {
+ if (primary_node->is_deferred_reference()) {
+ // The static call will be converted to throwing a NSM error.
+ const Class& cls = Class::Handle(library_.toplevel_class());
+ selector =
+ ParseStaticCall(cls, name, primary_pos, primary_node->prefix());
+ } else if (current_function().is_static()) {
// The static call will be converted to throwing a NSM error.
selector = ParseStaticCall(current_class(), name, primary_pos);
} else {
@@ -12503,7 +12527,9 @@ AstNode* Parser::ResolveIdentInPrefixScope(TokenPosition ident_pos,
const Class& cls = Class::Cast(obj);
PrimaryNode* primary =
new (Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw()));
- primary->set_is_deferred(is_deferred);
+ if (is_deferred) {
+ primary->set_prefix(&prefix);
+ }
return primary;
} else if (obj.IsField()) {
const Field& field = Field::Cast(obj);
@@ -12532,7 +12558,9 @@ AstNode* Parser::ResolveIdentInPrefixScope(TokenPosition ident_pos,
} else {
PrimaryNode* primary =
new (Z) PrimaryNode(ident_pos, Function::ZoneHandle(Z, func.raw()));
- primary->set_is_deferred(is_deferred);
+ if (is_deferred) {
+ primary->set_prefix(&prefix);
+ }
return primary;
}
}
@@ -13969,6 +13997,9 @@ AstNode* Parser::ParsePrimary() {
const String& qualified_name =
String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces));
primary = new (Z) PrimaryNode(qual_ident_pos, qualified_name);
+ if (prefix.is_deferred_load()) {
+ primary->AsPrimaryNode()->set_prefix(&prefix);
+ }
}
} else if (FLAG_load_deferred_eagerly && prefix.is_deferred_load()) {
// primary != NULL.

Powered by Google App Engine
This is Rietveld 408576698