diff options
Diffstat (limited to 'runtime/method_handles.cc')
| -rw-r--r-- | runtime/method_handles.cc | 59 |
1 files changed, 33 insertions, 26 deletions
diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc index 1327a24905..c8c6ef9a73 100644 --- a/runtime/method_handles.cc +++ b/runtime/method_handles.cc @@ -81,7 +81,7 @@ bool GetUnboxedPrimitiveType(ObjPtr<mirror::Class> klass, Primitive::Type* type) ObjPtr<mirror::Class> GetBoxedPrimitiveClass(Primitive::Type type) REQUIRES_SHARED(Locks::mutator_lock_) { ScopedAssertNoThreadSuspension ants(__FUNCTION__); - jmethodID m = nullptr; + ArtMethod* m = nullptr; switch (type) { #define CASE_PRIMITIVE(primitive, _, java_name, __) \ case primitive: \ @@ -93,7 +93,7 @@ ObjPtr<mirror::Class> GetBoxedPrimitiveClass(Primitive::Type type) case Primitive::Type::kPrimVoid: return nullptr; } - return jni::DecodeArtMethod(m)->GetDeclaringClass(); + return m->GetDeclaringClass(); } bool GetUnboxedTypeAndValue(ObjPtr<mirror::Object> o, Primitive::Type* type, JValue* value) @@ -290,6 +290,13 @@ bool ConvertJValueCommon( return false; } + ObjPtr<mirror::Class> from_obj_type = from_obj->GetClass(); + Primitive::Type from_primitive_type; + if (!GetUnboxedPrimitiveType(from_obj_type, &from_primitive_type)) { + ThrowClassCastException(from, to); + return false; + } + Primitive::Type unboxed_type; JValue unboxed_value; if (UNLIKELY(!GetUnboxedTypeAndValue(from_obj, &unboxed_type, &unboxed_value))) { @@ -393,7 +400,7 @@ static inline bool MethodHandleInvokeTransform(Thread* self, const char* old_cause = self->StartAssertNoThreadSuspension("MethodHandleInvokeTransform"); ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr = - CREATE_SHADOW_FRAME(kNumRegsForTransform, &shadow_frame, called_method, /* dex pc */ 0); + CREATE_SHADOW_FRAME(kNumRegsForTransform, called_method, /* dex pc */ 0); ShadowFrame* new_shadow_frame = shadow_frame_unique_ptr.get(); new_shadow_frame->SetVRegReference(0, method_handle.Get()); new_shadow_frame->SetVRegReference(1, sf.Get()); @@ -459,7 +466,7 @@ ArtMethod* RefineTargetMethod(Thread* self, } else if (handle_kind == mirror::MethodHandle::Kind::kInvokeDirect) { // String constructors are a special case, they are replaced with // StringFactory methods. - if (target_method->IsConstructor() && target_method->GetDeclaringClass()->IsStringClass()) { + if (target_method->IsStringConstructor()) { DCHECK(handle_type->GetRType()->IsStringClass()); return WellKnownClasses::StringInitToStringFactory(target_method); } @@ -544,31 +551,30 @@ inline bool MethodHandleFieldPut(Thread* self, JValue& value) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(!Runtime::Current()->IsActiveTransaction()); static const bool kTransaction = false; // Not in a transaction. - static const bool kAssignabilityCheck = false; // No access check. switch (field_type) { case Primitive::kPrimBoolean: return - DoFieldPutCommon<Primitive::kPrimBoolean, kAssignabilityCheck, kTransaction>( + DoFieldPutCommon<Primitive::kPrimBoolean, kTransaction>( self, shadow_frame, obj, field, value); case Primitive::kPrimByte: - return DoFieldPutCommon<Primitive::kPrimByte, kAssignabilityCheck, kTransaction>( + return DoFieldPutCommon<Primitive::kPrimByte, kTransaction>( self, shadow_frame, obj, field, value); case Primitive::kPrimChar: - return DoFieldPutCommon<Primitive::kPrimChar, kAssignabilityCheck, kTransaction>( + return DoFieldPutCommon<Primitive::kPrimChar, kTransaction>( self, shadow_frame, obj, field, value); case Primitive::kPrimShort: - return DoFieldPutCommon<Primitive::kPrimShort, kAssignabilityCheck, kTransaction>( + return DoFieldPutCommon<Primitive::kPrimShort, kTransaction>( self, shadow_frame, obj, field, value); case Primitive::kPrimInt: case Primitive::kPrimFloat: - return DoFieldPutCommon<Primitive::kPrimInt, kAssignabilityCheck, kTransaction>( + return DoFieldPutCommon<Primitive::kPrimInt, kTransaction>( self, shadow_frame, obj, field, value); case Primitive::kPrimLong: case Primitive::kPrimDouble: - return DoFieldPutCommon<Primitive::kPrimLong, kAssignabilityCheck, kTransaction>( + return DoFieldPutCommon<Primitive::kPrimLong, kTransaction>( self, shadow_frame, obj, field, value); case Primitive::kPrimNot: - return DoFieldPutCommon<Primitive::kPrimNot, kAssignabilityCheck, kTransaction>( + return DoFieldPutCommon<Primitive::kPrimNot, kTransaction>( self, shadow_frame, obj, field, value); case Primitive::kPrimVoid: LOG(FATAL) << "Unreachable: " << field_type; @@ -625,6 +631,10 @@ bool MethodHandleFieldAccess(Thread* self, case mirror::MethodHandle::kInstanceGet: { size_t obj_reg = operands->GetOperand(0); ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(obj_reg); + if (obj == nullptr) { + ThrowNullPointerException("Receiver is null"); + return false; + } MethodHandleFieldGet(self, shadow_frame, obj, field, field_type, result); return true; } @@ -648,6 +658,10 @@ bool MethodHandleFieldAccess(Thread* self, callsite_type->GetPTypes()->Get(kPTypeIndex)->GetPrimitiveType(), value_reg); ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(obj_reg); + if (obj == nullptr) { + ThrowNullPointerException("Receiver is null"); + return false; + } return MethodHandleFieldPut(self, shadow_frame, obj, field, field_type, value); } case mirror::MethodHandle::kStaticPut: { @@ -769,7 +783,7 @@ static bool DoMethodHandleInvokeMethod(Thread* self, const char* old_cause = self->StartAssertNoThreadSuspension("DoMethodHandleInvokeMethod"); ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr = - CREATE_SHADOW_FRAME(num_regs, &shadow_frame, called_method, /* dex pc */ 0); + CREATE_SHADOW_FRAME(num_regs, called_method, /* dex pc */ 0); ShadowFrame* new_shadow_frame = shadow_frame_unique_ptr.get(); CopyArgumentsFromCallerFrame(shadow_frame, new_shadow_frame, operands, first_dest_reg); self->EndAssertNoThreadSuspension(old_cause); @@ -856,19 +870,13 @@ static bool MethodHandleInvokeInternal(Thread* self, if (atc == nullptr || !callsite_type->IsExactMatch(atc->GetMethodType())) { // Cached asType adapter does not exist or is for another call site. Call // MethodHandle::asType() to get an appropriate adapter. - ArtMethod* as_type = - jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandle_asType); - uint32_t as_type_args[] = { - static_cast<uint32_t>(reinterpret_cast<uintptr_t>(method_handle.Get())), - static_cast<uint32_t>(reinterpret_cast<uintptr_t>(callsite_type.Get()))}; - JValue atc_result; - as_type->Invoke(self, as_type_args, sizeof(as_type_args), &atc_result, "LL"); - if (atc_result.GetL() == nullptr) { + ArtMethod* as_type = WellKnownClasses::java_lang_invoke_MethodHandle_asType; + ObjPtr<mirror::MethodHandle> atc_method_handle = ObjPtr<mirror::MethodHandle>::DownCast( + as_type->InvokeVirtual<'L', 'L'>(self, method_handle.Get(), callsite_type.Get())); + if (atc_method_handle == nullptr) { DCHECK(self->IsExceptionPending()); return false; } - ObjPtr<mirror::MethodHandle> atc_method_handle = - down_cast<mirror::MethodHandle*>(atc_result.GetL()); atc.Assign(atc_method_handle); DCHECK(!atc.IsNull()); } @@ -909,10 +917,9 @@ void MethodHandleInvokeExactWithFrame(Thread* self, const uint16_t num_vregs = callsite_type->NumberOfVRegs(); const char* old_cause = self->StartAssertNoThreadSuspension("EmulatedStackFrame to ShadowFrame"); - ArtMethod* invoke_exact = - jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandle_invokeExact); + ArtMethod* invoke_exact = WellKnownClasses::java_lang_invoke_MethodHandle_invokeExact; ShadowFrameAllocaUniquePtr shadow_frame = - CREATE_SHADOW_FRAME(num_vregs, /*link*/ nullptr, invoke_exact, /*dex_pc*/ 0); + CREATE_SHADOW_FRAME(num_vregs, invoke_exact, /*dex_pc*/ 0); emulated_frame->WriteToShadowFrame(self, callsite_type, 0, shadow_frame.get()); self->EndAssertNoThreadSuspension(old_cause); |