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