Revert^2 "MethodHandle composability fix"

This reverts commit 6ed5c4f64809902169a8943aa1671085bf423c31.

Reason for revert: no longer calling abstract method.

Bug: 206407164
Test: art/tools/buildbot-build.sh --host
Test: art/tools/run-libcore-tests.sh --mode host --variant X32 --debug
Change-Id: I939ead996c4c03210e2bdfc2993a24fb01ee69c7
diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc
index 78e7561..bce5bf3 100644
--- a/runtime/method_handles.cc
+++ b/runtime/method_handles.cc
@@ -16,20 +16,24 @@
 
 #include "method_handles-inl.h"
 
+#include "android-base/macros.h"
 #include "android-base/stringprintf.h"
-
 #include "class_root-inl.h"
 #include "common_dex_operations.h"
 #include "common_throws.h"
 #include "interpreter/shadow_frame-inl.h"
+#include "interpreter/shadow_frame.h"
 #include "jvalue-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/emulated_stack_frame-inl.h"
+#include "mirror/emulated_stack_frame.h"
 #include "mirror/method_handle_impl-inl.h"
+#include "mirror/method_handle_impl.h"
 #include "mirror/method_type-inl.h"
 #include "mirror/var_handle.h"
 #include "reflection-inl.h"
 #include "reflection.h"
+#include "thread.h"
 #include "well_known_classes.h"
 
 namespace art {
@@ -402,7 +406,7 @@
 // Returns true iff. the callsite type for a polymorphic invoke is transformer
 // like, i.e that it has a single input argument whose type is
 // dalvik.system.EmulatedStackFrame.
-static inline bool IsCallerTransformer(Handle<mirror::MethodType> callsite_type)
+static inline bool InvokedFromTransform(Handle<mirror::MethodType> callsite_type)
     REQUIRES_SHARED(Locks::mutator_lock_) {
   ObjPtr<mirror::ObjectArray<mirror::Class>> param_types(callsite_type->GetPTypes());
   if (param_types->GetLength() == 1) {
@@ -474,7 +478,7 @@
       // a single argument of type dalvik.system.EmulatedStackFrame. In that
       // case, we'll have to unmarshal the EmulatedStackFrame into the
       // new_shadow_frame and perform argument conversions on it.
-      if (IsCallerTransformer(callsite_type)) {
+      if (InvokedFromTransform(callsite_type)) {
         is_caller_transformer = true;
         // The emulated stack frame is the first and only argument when we're coming
         // through from a transformer.
@@ -582,7 +586,7 @@
 
   StackHandleScope<1> hs(self);
   MutableHandle<mirror::EmulatedStackFrame> sf(hs.NewHandle<mirror::EmulatedStackFrame>(nullptr));
-  if (IsCallerTransformer(callsite_type)) {
+  if (InvokedFromTransform(callsite_type)) {
     // If we're entering this transformer from another transformer, we can pass
     // through the handle directly to the callee, instead of having to
     // instantiate a new stack frame based on the shadow frame.
@@ -657,7 +661,7 @@
     // For virtual and interface methods ensure target_method points to
     // the actual method to invoke.
     ObjPtr<mirror::Object> receiver(shadow_frame.GetVRegReference(receiver_reg));
-    if (IsCallerTransformer(callsite_type)) {
+    if (InvokedFromTransform(callsite_type)) {
       // The current receiver is an emulated stack frame, the method's
       // receiver needs to be fetched from there as the emulated frame
       // will be unpacked into a new frame.
@@ -1162,7 +1166,7 @@
 
   // Slow-path check.
   if (IsInvokeTransform(handle_kind) ||
-      IsCallerTransformer(callsite_type)) {
+      InvokedFromTransform(callsite_type)) {
     return DoInvokePolymorphicMethod(self,
                                      shadow_frame,
                                      method_handle,
@@ -1179,7 +1183,7 @@
                                         result);
   }
 
-  // On the fast-path. This is equivalent to DoCallPolymoprhic without the conversion paths.
+  // On the fast-path. This is equivalent to DoCallPolymorphic without the conversion paths.
   ArtMethod* target_method = method_handle->GetTargetMethod();
   uint32_t receiver_reg = (operands->GetNumberOfOperands() > 0) ? operands->GetOperand(0) : 0u;
   ArtMethod* called_method = RefineTargetMethod(self,
@@ -1227,7 +1231,7 @@
       called_method, called_method->GetEntryPointFromQuickCompiledCode());
   PerformCall(self,
               accessor,
-              shadow_frame.GetMethod(),
+              called_method,
               first_dest_reg,
               new_shadow_frame,
               result,
@@ -1238,31 +1242,86 @@
   return true;
 }
 
+template <typename T>
+bool InvokeInContext(Thread* self,
+                     ShadowFrame& shadow_frame,
+                     Handle<mirror::MethodHandle> method_handle,
+                     Handle<mirror::MethodType> callsite_type,
+                     const InstructionOperands* const operands,
+                     JValue* result,
+                     T invoker) REQUIRES_SHARED(Locks::mutator_lock_) {
+  if (!InvokedFromTransform(callsite_type) || IsInvokeTransform(method_handle->GetHandleKind())) {
+    return invoker(self, shadow_frame, method_handle, callsite_type, operands, result);
+  }
+
+  // The MethodHandle invocation has occurred within a Transformer that has created an emulated
+  // stack frame as context with which to invoke the MethodHandle. We need to unpack this, then
+  // invoke the MethodHandle in the provided context.
+  StackHandleScope<2> hs(self);
+  size_t first_argument_vreg = operands->GetOperand(0);
+  Handle<mirror::EmulatedStackFrame> emulated_stack_frame =
+      hs.NewHandle(ObjPtr<mirror::EmulatedStackFrame>::DownCast(
+          shadow_frame.GetVRegReference(first_argument_vreg)));
+  Handle<mirror::MethodType> effective_callsite_type =
+      hs.NewHandle(emulated_stack_frame->GetType());
+  uint16_t num_vregs = effective_callsite_type->NumberOfVRegs();
+
+  RangeInstructionOperands effective_operands(0, num_vregs);
+  ArtMethod* called_method = method_handle->GetTargetMethod();  // invoke / invokeExact.
+  // Create a shadow frame
+  ShadowFrameAllocaUniquePtr effective_frame =
+      CREATE_SHADOW_FRAME(num_vregs, &shadow_frame, called_method, shadow_frame.GetDexPC());
+  if (UNLIKELY(effective_operands.GetNumberOfOperands() != 0 &&
+               !emulated_stack_frame->WriteToShadowFrame(self,
+                                                         effective_callsite_type,
+                                                         effective_operands.GetOperand(0),
+                                                         effective_frame.get()))) {
+    DCHECK(self->IsExceptionPending());
+    result->SetL(nullptr);
+    return false;
+  }
+
+  ScopedStackedShadowFramePusher pusher(
+      self, effective_frame.get(), StackedShadowFrameType::kShadowFrameUnderConstruction);
+
+  // Invoke MethodHandle in newly created context
+  bool success = invoker(self,
+                         *effective_frame.get(),
+                         method_handle,
+                         effective_callsite_type,
+                         &effective_operands,
+                         result);
+  if (success) {
+    emulated_stack_frame->SetReturnValue(self, *result);
+  }
+  return success;
+}
+
 }  // namespace
 
 bool MethodHandleInvoke(Thread* self,
-                       ShadowFrame& shadow_frame,
-                       Handle<mirror::MethodHandle> method_handle,
-                       Handle<mirror::MethodType> callsite_type,
-                       const InstructionOperands* const operands,
-                       JValue* result)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  if (UNLIKELY(callsite_type->IsExactMatch(method_handle->GetMethodType()))) {
-    // A non-exact invoke that can be invoked exactly.
-    return MethodHandleInvokeExactInternal(self,
-                                           shadow_frame,
-                                           method_handle,
-                                           callsite_type,
-                                           operands,
-                                           result);
-  } else {
-    return MethodHandleInvokeInternal(self,
-                                      shadow_frame,
-                                      method_handle,
-                                      callsite_type,
-                                      operands,
-                                      result);
-  }
+                        ShadowFrame& shadow_frame,
+                        Handle<mirror::MethodHandle> method_handle,
+                        Handle<mirror::MethodType> callsite_type,
+                        const InstructionOperands* const operands,
+                        JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
+  auto invoke = [](Thread* self,
+                   ShadowFrame& shadow_frame,
+                   Handle<mirror::MethodHandle> method_handle,
+                   Handle<mirror::MethodType> callsite_type,
+                   const InstructionOperands* const operands,
+                   JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
+    if (UNLIKELY(callsite_type->IsExactMatch(method_handle->GetMethodType()))) {
+      // A non-exact invoke that can be invoked exactly.
+      return MethodHandleInvokeExactInternal(
+          self, shadow_frame, method_handle, callsite_type, operands, result);
+    } else {
+      return MethodHandleInvokeInternal(
+          self, shadow_frame, method_handle, callsite_type, operands, result);
+    }
+  };
+  return InvokeInContext(
+      self, shadow_frame, method_handle, callsite_type, operands, result, invoke);
 }
 
 bool MethodHandleInvokeExact(Thread* self,
@@ -1272,32 +1331,33 @@
                              const InstructionOperands* const operands,
                              JValue* result)
     REQUIRES_SHARED(Locks::mutator_lock_) {
-  // We need to check the nominal type of the handle in addition to the
-  // real type. The "nominal" type is present when MethodHandle.asType is
-  // called any handle, and results in the declared type of the handle
-  // changing.
-  ObjPtr<mirror::MethodType> nominal_type(method_handle->GetNominalType());
-  if (UNLIKELY(nominal_type != nullptr)) {
-    if (UNLIKELY(!callsite_type->IsExactMatch(nominal_type.Ptr()))) {
-      ThrowWrongMethodTypeException(nominal_type.Ptr(), callsite_type.Get());
-      return false;
+  auto invoke = [](Thread* self,
+                   ShadowFrame& shadow_frame,
+                   Handle<mirror::MethodHandle> method_handle,
+                   Handle<mirror::MethodType> callsite_type,
+                   const InstructionOperands* const operands,
+                   JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
+    // We need to check the nominal type of the handle in addition to the
+    // real type. The "nominal" type is present when MethodHandle.asType is
+    // called any handle, and results in the declared type of the handle
+    // changing.
+    ObjPtr<mirror::MethodType> nominal_type(method_handle->GetNominalType());
+    if (UNLIKELY(nominal_type != nullptr)) {
+      if (UNLIKELY(!callsite_type->IsExactMatch(nominal_type.Ptr()))) {
+        ThrowWrongMethodTypeException(nominal_type.Ptr(), callsite_type.Get());
+        return false;
+      }
+      if (LIKELY(!nominal_type->IsExactMatch(method_handle->GetMethodType()))) {
+        // Different nominal type means we have to treat as non-exact.
+        return MethodHandleInvokeInternal(
+            self, shadow_frame, method_handle, callsite_type, operands, result);
+      }
     }
-    if (LIKELY(!nominal_type->IsExactMatch(method_handle->GetMethodType()))) {
-      // Different nominal type means we have to treat as non-exact.
-      return MethodHandleInvokeInternal(self,
-                                        shadow_frame,
-                                        method_handle,
-                                        callsite_type,
-                                        operands,
-                                        result);
-    }
-  }
-  return MethodHandleInvokeExactInternal(self,
-                                         shadow_frame,
-                                         method_handle,
-                                         callsite_type,
-                                         operands,
-                                         result);
+    return MethodHandleInvokeExactInternal(
+        self, shadow_frame, method_handle, callsite_type, operands, result);
+  };
+  return InvokeInContext(
+      self, shadow_frame, method_handle, callsite_type, operands, result, invoke);
 }
 
 }  // namespace art