1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_METHOD_HANDLES_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_METHOD_HANDLES_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <ostream> 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 23*795d594fSAndroid Build Coastguard Worker #include "dex/dex_instruction.h" 24*795d594fSAndroid Build Coastguard Worker #include "handle.h" 25*795d594fSAndroid Build Coastguard Worker #include "jvalue.h" 26*795d594fSAndroid Build Coastguard Worker #include "mirror/class.h" 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker class ShadowFrame; 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker namespace mirror { 33*795d594fSAndroid Build Coastguard Worker class EmulatedStackFrame; 34*795d594fSAndroid Build Coastguard Worker class MethodHandle; 35*795d594fSAndroid Build Coastguard Worker class MethodType; 36*795d594fSAndroid Build Coastguard Worker } // namespace mirror 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker // Returns true if there is a possible conversion from |from| to |to| 39*795d594fSAndroid Build Coastguard Worker // for a MethodHandle parameter. 40*795d594fSAndroid Build Coastguard Worker bool IsParameterTypeConvertible(ObjPtr<mirror::Class> from, 41*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> to); 42*795d594fSAndroid Build Coastguard Worker 43*795d594fSAndroid Build Coastguard Worker // Returns true if there is a possible conversion from |from| to |to| 44*795d594fSAndroid Build Coastguard Worker // for the return type of a MethodHandle. 45*795d594fSAndroid Build Coastguard Worker bool IsReturnTypeConvertible(ObjPtr<mirror::Class> from, 46*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> to); 47*795d594fSAndroid Build Coastguard Worker 48*795d594fSAndroid Build Coastguard Worker // Interface for throwing `WrongMethodTypeException` by conversion functions. 49*795d594fSAndroid Build Coastguard Worker class ThrowWrongMethodTypeFunction { 50*795d594fSAndroid Build Coastguard Worker public: 51*795d594fSAndroid Build Coastguard Worker virtual void operator()() const REQUIRES_SHARED(Locks::mutator_lock_) = 0; 52*795d594fSAndroid Build Coastguard Worker 53*795d594fSAndroid Build Coastguard Worker protected: ~ThrowWrongMethodTypeFunction()54*795d594fSAndroid Build Coastguard Worker ~ThrowWrongMethodTypeFunction() {} 55*795d594fSAndroid Build Coastguard Worker }; 56*795d594fSAndroid Build Coastguard Worker 57*795d594fSAndroid Build Coastguard Worker // Performs a conversion from type `from` to a distinct type `to`. 58*795d594fSAndroid Build Coastguard Worker // The value to be converted is in `*value`. Returns true on success 59*795d594fSAndroid Build Coastguard Worker // and updates `*value` with the converted value, false otherwise. 60*795d594fSAndroid Build Coastguard Worker bool ConvertJValueCommon(const ThrowWrongMethodTypeFunction& throw_wmt, 61*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> from, 62*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> to, 63*795d594fSAndroid Build Coastguard Worker /*inout*/ JValue* value) 64*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 65*795d594fSAndroid Build Coastguard Worker 66*795d594fSAndroid Build Coastguard Worker // Converts the value of the argument from type `from` to type `to`. 67*795d594fSAndroid Build Coastguard Worker // `*value` represents the value to be converted. Returns true on success 68*795d594fSAndroid Build Coastguard Worker // and updates `*value`, false otherwise. 69*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE bool ConvertArgumentValue(const ThrowWrongMethodTypeFunction& throw_wmt, 70*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> from, 71*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> to, 72*795d594fSAndroid Build Coastguard Worker /*inout*/ JValue* value) 73*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 74*795d594fSAndroid Build Coastguard Worker 75*795d594fSAndroid Build Coastguard Worker // Converts the return value from return type `from` to the return type `to`. 76*795d594fSAndroid Build Coastguard Worker // `*value` represents the value to be converted. Returns true on success and 77*795d594fSAndroid Build Coastguard Worker // updates `*value`, false otherwise. 78*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE bool ConvertReturnValue(const ThrowWrongMethodTypeFunction& throw_wmt, 79*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> from, 80*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> to, 81*795d594fSAndroid Build Coastguard Worker /*inout*/ JValue* value) 82*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 83*795d594fSAndroid Build Coastguard Worker 84*795d594fSAndroid Build Coastguard Worker // Perform argument conversions between `from_types` (the types of the incoming 85*795d594fSAndroid Build Coastguard Worker // arguments) and `to_types` (the parameter types of the method being invoked). 86*795d594fSAndroid Build Coastguard Worker // These include widening and narrowing conversions as well as boxing and 87*795d594fSAndroid Build Coastguard Worker // unboxing. Returns true on success, false on failure. A pending exception 88*795d594fSAndroid Build Coastguard Worker // will always be set on failure. 89*795d594fSAndroid Build Coastguard Worker // 90*795d594fSAndroid Build Coastguard Worker // The values to be converted are read from an input source (of type G) 91*795d594fSAndroid Build Coastguard Worker // that provides three methods : 92*795d594fSAndroid Build Coastguard Worker // 93*795d594fSAndroid Build Coastguard Worker // class G { 94*795d594fSAndroid Build Coastguard Worker // // Used to read the next boolean/short/int or float value from the 95*795d594fSAndroid Build Coastguard Worker // // source. 96*795d594fSAndroid Build Coastguard Worker // uint32_t Get(); 97*795d594fSAndroid Build Coastguard Worker // 98*795d594fSAndroid Build Coastguard Worker // // Used to the read the next reference value from the source. 99*795d594fSAndroid Build Coastguard Worker // ObjPtr<mirror::Object> GetReference(); 100*795d594fSAndroid Build Coastguard Worker // 101*795d594fSAndroid Build Coastguard Worker // // Used to read the next double or long value from the source. 102*795d594fSAndroid Build Coastguard Worker // int64_t GetLong(); 103*795d594fSAndroid Build Coastguard Worker // } 104*795d594fSAndroid Build Coastguard Worker // 105*795d594fSAndroid Build Coastguard Worker // After conversion, the values are written to an output sink (of type S) 106*795d594fSAndroid Build Coastguard Worker // that provides three methods : 107*795d594fSAndroid Build Coastguard Worker // 108*795d594fSAndroid Build Coastguard Worker // class S { 109*795d594fSAndroid Build Coastguard Worker // void Set(uint32_t); 110*795d594fSAndroid Build Coastguard Worker // void SetReference(ObjPtr<mirror::Object>) 111*795d594fSAndroid Build Coastguard Worker // void SetLong(int64_t); 112*795d594fSAndroid Build Coastguard Worker // } 113*795d594fSAndroid Build Coastguard Worker // 114*795d594fSAndroid Build Coastguard Worker // The semantics and usage of the Set methods are analagous to the getter 115*795d594fSAndroid Build Coastguard Worker // class. 116*795d594fSAndroid Build Coastguard Worker // 117*795d594fSAndroid Build Coastguard Worker // This method is instantiated in three different scenarions : 118*795d594fSAndroid Build Coastguard Worker // - <S = ShadowFrameSetter, G = ShadowFrameGetter> : copying from shadow 119*795d594fSAndroid Build Coastguard Worker // frame to shadow frame, used in a regular polymorphic non-exact invoke. 120*795d594fSAndroid Build Coastguard Worker // - <S = EmulatedShadowFrameAccessor, G = ShadowFrameGetter> : entering into 121*795d594fSAndroid Build Coastguard Worker // a transformer method from a polymorphic invoke. 122*795d594fSAndroid Build Coastguard Worker // - <S = ShadowFrameStter, G = EmulatedStackFrameAccessor> : entering into 123*795d594fSAndroid Build Coastguard Worker // a regular poly morphic invoke from a transformer method. 124*795d594fSAndroid Build Coastguard Worker // 125*795d594fSAndroid Build Coastguard Worker // TODO(narayan): If we find that the instantiations of this function take 126*795d594fSAndroid Build Coastguard Worker // up too much space, we can make G / S abstract base classes that are 127*795d594fSAndroid Build Coastguard Worker // overridden by concrete classes. 128*795d594fSAndroid Build Coastguard Worker template <typename FromPTypes, typename ToPTypes, typename G, typename S> 129*795d594fSAndroid Build Coastguard Worker bool PerformConversions(const ThrowWrongMethodTypeFunction& throw_wmt, 130*795d594fSAndroid Build Coastguard Worker FromPTypes from_types, 131*795d594fSAndroid Build Coastguard Worker ToPTypes to_types, 132*795d594fSAndroid Build Coastguard Worker G* getter, 133*795d594fSAndroid Build Coastguard Worker S* setter) REQUIRES_SHARED(Locks::mutator_lock_); 134*795d594fSAndroid Build Coastguard Worker 135*795d594fSAndroid Build Coastguard Worker template <typename G, typename S> 136*795d594fSAndroid Build Coastguard Worker bool CopyArguments(Thread* self, 137*795d594fSAndroid Build Coastguard Worker Handle<mirror::MethodType> method_type, 138*795d594fSAndroid Build Coastguard Worker Handle<mirror::MethodType> callee_type, 139*795d594fSAndroid Build Coastguard Worker G* getter, 140*795d594fSAndroid Build Coastguard Worker S* setter) REQUIRES_SHARED(Locks::mutator_lock_); 141*795d594fSAndroid Build Coastguard Worker 142*795d594fSAndroid Build Coastguard Worker bool MethodHandleInvoke(Thread* self, 143*795d594fSAndroid Build Coastguard Worker ShadowFrame& shadow_frame, 144*795d594fSAndroid Build Coastguard Worker Handle<mirror::MethodHandle> method_handle, 145*795d594fSAndroid Build Coastguard Worker Handle<mirror::MethodType> callsite_type, 146*795d594fSAndroid Build Coastguard Worker const InstructionOperands* const args, 147*795d594fSAndroid Build Coastguard Worker JValue* result) 148*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker bool MethodHandleInvokeExact(Thread* self, 151*795d594fSAndroid Build Coastguard Worker ShadowFrame& shadow_frame, 152*795d594fSAndroid Build Coastguard Worker Handle<mirror::MethodHandle> method_handle, 153*795d594fSAndroid Build Coastguard Worker Handle<mirror::MethodType> callsite_type, 154*795d594fSAndroid Build Coastguard Worker const InstructionOperands* const args, 155*795d594fSAndroid Build Coastguard Worker JValue* result) 156*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 157*795d594fSAndroid Build Coastguard Worker 158*795d594fSAndroid Build Coastguard Worker void MethodHandleInvokeExactWithFrame(Thread* self, 159*795d594fSAndroid Build Coastguard Worker Handle<mirror::MethodHandle> method_handle, 160*795d594fSAndroid Build Coastguard Worker Handle<mirror::EmulatedStackFrame> stack_frame) 161*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 162*795d594fSAndroid Build Coastguard Worker 163*795d594fSAndroid Build Coastguard Worker } // namespace art 164*795d594fSAndroid Build Coastguard Worker 165*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_METHOD_HANDLES_H_ 166