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

Unified Diff: runtime/vm/parser.cc

Issue 2204593011: Reload: Have dangling extracted properties raise NoSuchMethod. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: . Created 4 years, 4 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
« no previous file with comments | « runtime/vm/isolate_reload_test.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index d11536b775f48a4432b98e5783fd348e6293a117..f949c0001f02d6e34b83de575ab03936f39fe791 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -1548,32 +1548,14 @@ SequenceNode* Parser::ParseImplicitClosure(const Function& func) {
&Object::dynamic_type());
const Function& parent = Function::Handle(func.parent_function());
- const String& target_name = String::Handle(parent.name());
- const Class& owner = Class::Handle(parent.Owner());
- Function& target = Function::ZoneHandle(owner.LookupFunction(target_name));
- if (target.raw() != parent.raw()) {
- ASSERT(Isolate::Current()->HasAttemptedReload());
- if (target.IsNull() ||
- (target.is_static() != parent.is_static()) ||
- (target.kind() != parent.kind())) {
- // TODO(26977): call noSuchMethod/throw NSME instead.
- target = parent.raw();
- }
- }
-
- if (target.IsImplicitSetterFunction()) {
+ if (parent.IsImplicitSetterFunction()) {
const TokenPosition ident_pos = func.token_pos();
ASSERT(IsIdentifier());
- const String& field_name = *CurrentLiteral();
- const Class& field_class = Class::ZoneHandle(Z, target.Owner());
- const Field& field =
- Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name));
- const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type());
params.AddFinalParameter(ident_pos,
&Symbols::Value(),
Cutch 2016/08/04 00:38:05 why drop the field type here?
rmacnak 2016/08/04 16:19:31 The lookup can fail if the target no longer exists
- &field_type);
+ &Object::dynamic_type());
ASSERT(func.num_fixed_parameters() == 2); // closure, value.
- } else if (!target.IsGetterFunction() && !target.IsImplicitGetterFunction()) {
+ } else if (!parent.IsGetterFunction() && !parent.IsImplicitGetterFunction()) {
const bool allow_explicit_default_values = true;
SkipFunctionPreamble();
ParseFormalParameterList(allow_explicit_default_values, false, &params);
@@ -1604,7 +1586,71 @@ SequenceNode* Parser::ParseImplicitClosure(const Function& func) {
}
func_args->set_names(arg_names);
}
- StaticCallNode* call = new StaticCallNode(token_pos, target, func_args);
+
+ const String& func_name = String::ZoneHandle(parent.name());
+ const Class& owner = Class::Handle(parent.Owner());
+ Function& target = Function::ZoneHandle(owner.LookupFunction(func_name));
+ if (target.raw() != parent.raw()) {
+ ASSERT(Isolate::Current()->HasAttemptedReload());
+ if (target.IsNull() ||
+ (target.is_static() != parent.is_static()) ||
+ (target.kind() != parent.kind())) {
+ target = Function::null();
+ }
+ }
+
+ AstNode* call = NULL;
+ if (!target.IsNull()) {
+ call = new StaticCallNode(token_pos, target, func_args);
+ } else if (!parent.is_static()) {
+ ASSERT(Isolate::Current()->HasAttemptedReload());
+ // If a subsequent reload reintroduces the target in the middle of the
+ // Invocation object being constructed, we won't be able to successfully
+ // deopt because the generated AST will change.
+ current_function().SetIsOptimizable(false);
+
+ ArgumentListNode* arguments = BuildNoSuchMethodArguments(
+ token_pos, func_name, *func_args, NULL, false);
+ const intptr_t kNumArguments = 2; // Receiver, InvocationMirror.
+ ArgumentsDescriptor args_desc(
+ Array::Handle(Z, ArgumentsDescriptor::New(kNumArguments)));
+ Function& no_such_method = Function::ZoneHandle(Z,
+ Resolver::ResolveDynamicForReceiverClass(owner,
+ Symbols::NoSuchMethod(),
+ args_desc));
+ if (no_such_method.IsNull()) {
+ // If noSuchMethod(i) is not found, call Object:noSuchMethod.
+ no_such_method ^= Resolver::ResolveDynamicForReceiverClass(
+ Class::Handle(Z, I->object_store()->object_class()),
+ Symbols::NoSuchMethod(),
+ args_desc);
+ }
+ call = new StaticCallNode(token_pos, no_such_method, arguments);
+ } else {
+ ASSERT(Isolate::Current()->HasAttemptedReload());
+ // If a subsequent reload reintroduces the target in the middle of the
+ // arguments array being constructed, we won't be able to successfully
+ // deopt because the generated AST will change.
+ current_function().SetIsOptimizable(false);
+
+ InvocationMirror::Type im_type;
+ if (parent.IsImplicitGetterFunction()) {
+ im_type = InvocationMirror::kGetter;
+ } else if (parent.IsImplicitSetterFunction()) {
+ im_type = InvocationMirror::kSetter;
+ } else {
+ im_type = InvocationMirror::kMethod;
+ }
+ call = ThrowNoSuchMethodError(TokenPos(),
+ owner,
+ func_name,
+ func_args,
+ InvocationMirror::kStatic,
+ im_type,
+ NULL); // No existing function.
+ }
+
+ ASSERT(call != NULL);
ReturnNode* return_node = new ReturnNode(token_pos, call);
current_block_->statements->Add(return_node);
return CloseBlock();
« no previous file with comments | « runtime/vm/isolate_reload_test.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698