MethodHandles: Implement MethodHandle.asType.
Tracks libcore change 16fa583fb5ee489.
Test: make test-art-host
Bug: 30550796
Change-Id: I2457b563f67a183c4eebf94ddbe74cc55f772ee0
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 1a99100..e607d4d 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -833,9 +833,23 @@
const MethodHandleKind handle_kind = method_handle->GetHandleKind();
Handle<mirror::MethodType> handle_type(hs.NewHandle(method_handle->GetMethodType()));
CHECK(handle_type.Get() != nullptr);
- if (UNLIKELY(is_invoke_exact && !callsite_type->IsExactMatch(handle_type.Get()))) {
- ThrowWrongMethodTypeException(handle_type.Get(), callsite_type.Get());
- return false;
+ if (is_invoke_exact) {
+ // 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());
+ ObjPtr<mirror::MethodType> check_type(nullptr);
+ if (LIKELY(nominal_type.Ptr() == nullptr)) {
+ check_type.Assign(handle_type.Get());
+ } else {
+ check_type.Assign(nominal_type.Ptr());
+ }
+
+ if (UNLIKELY(!callsite_type->IsExactMatch(check_type.Ptr()))) {
+ ThrowWrongMethodTypeException(check_type.Ptr(), callsite_type.Get());
+ return false;
+ }
}
uint32_t arg[Instruction::kMaxVarArgRegs] = {};