summaryrefslogtreecommitdiff
path: root/runtime/reflection.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/reflection.cc')
-rw-r--r--runtime/reflection.cc21
1 files changed, 14 insertions, 7 deletions
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index a2ce0cbf12..329ceb561d 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -564,14 +564,21 @@ jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaM
mirror::Object* receiver = nullptr;
if (!m->IsStatic()) {
- // Check that the receiver is non-null and an instance of the field's declaring class.
- receiver = soa.Decode<mirror::Object*>(javaReceiver);
- if (!VerifyObjectIsClass(receiver, declaring_class)) {
- return nullptr;
- }
+ // Replace calls to String.<init> with equivalent StringFactory call.
+ if (declaring_class->IsStringClass() && m->IsConstructor()) {
+ jmethodID mid = soa.EncodeMethod(m);
+ m = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
+ CHECK(javaReceiver == nullptr);
+ } else {
+ // Check that the receiver is non-null and an instance of the field's declaring class.
+ receiver = soa.Decode<mirror::Object*>(javaReceiver);
+ if (!VerifyObjectIsClass(receiver, declaring_class)) {
+ return nullptr;
+ }
- // Find the actual implementation of the virtual method.
- m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(m);
+ // Find the actual implementation of the virtual method.
+ m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(m);
+ }
}
// Get our arrays of arguments and their types, and check they're the same size.