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

Unified Diff: runtime/vm/object_reload.cc

Issue 2147293002: Rebinding super calls. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Implement rebinding super calls after hot reload. Created 4 years, 5 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/object_reload.cc
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index 2f8d5b3fb4fb27807178c7916968f82369564bb0..9b2e3e83e3328e2da5a1729c6e97b4ffb7bdf01f 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -556,19 +556,59 @@ void ICData::Reset() const {
FATAL("old_target is NULL.\n");
}
static_call_target = &old_target;
+
+ const String& selector = String::Handle(old_target.name());
+ Function& new_target = Function::Handle();
if (!old_target.is_static()) {
- // TODO(johnmccutchan): Improve this.
- TIR_Print("Cannot rebind super-call to %s from %s\n",
- old_target.ToCString(),
- Object::Handle(Owner()).ToCString());
- return;
+ if (old_target.kind() == RawFunction::kConstructor) {
+ return; // Super constructor call.
+ }
+ Function& caller = Function::Handle();
+ caller ^= Owner();
+ ASSERT(!caller.is_static());
+ Class& cls = Class::Handle(caller.Owner());
+ if (cls.raw() == old_target.Owner()) {
+ // Dispatcher.
+ if (caller.IsImplicitClosureFunction()) {
+ return; // Tear-off.
+ }
+ if (caller.kind() == RawFunction::kNoSuchMethodDispatcher) {
+ // TODO(rmacnak): noSuchMethod might have been redefined.
+ return;
+ }
+ const Function& caller_parent =
+ Function::Handle(caller.parent_function());
+ if (!caller_parent.IsNull()) {
+ if (caller_parent.kind() == RawFunction::kInvokeFieldDispatcher) {
+ return; // Call-through-getter.
+ }
+ }
+ FATAL2("Unexpected dispatcher-like call site: %s from %s\n",
+ selector.ToCString(), caller.ToQualifiedCString());
+ }
+ // Super call.
+ cls = cls.SuperClass();
+ while (!cls.IsNull()) {
+ // TODO(rmacnak): Should use Resolver::ResolveDynamicAnyArgs to handle
+ // method-extractors and call-through-getters, but we're in a no
+ // safepoint scope here.
+ new_target = cls.LookupDynamicFunction(selector);
+ if (!new_target.IsNull()) {
+ break;
+ }
+ cls = cls.SuperClass();
+ }
+ } else {
+ // This can be incorrect if the call site was an unqualified invocation.
+ const Class& cls = Class::Handle(old_target.Owner());
+ new_target = cls.LookupStaticFunction(selector);
}
- const String& selector = String::Handle(old_target.name());
- const Class& cls = Class::Handle(old_target.Owner());
- const Function& new_target =
- Function::Handle(cls.LookupStaticFunction(selector));
- if (new_target.IsNull()) {
- // TODO(johnmccutchan): Improve this.
+
+ const Array& args_desc_array = Array::Handle(arguments_descriptor());
+ ArgumentsDescriptor args_desc(args_desc_array);
+ if (new_target.IsNull() ||
+ !new_target.AreValidArguments(args_desc, NULL)) {
+ // TODO(rmacnak): Patch to a NSME stub.
TIR_Print("Cannot rebind static call to %s from %s\n",
old_target.ToCString(),
Object::Handle(Owner()).ToCString());
« 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