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 "dex/dex_instruction.h" 23 #include "handle.h" 24 #include "interpreter/shadow_frame.h" 25 #include "jvalue.h" 26 #include "mirror/class.h" 27 28 namespace art { 29 30 namespace mirror { 31 class MethodHandle; 32 class MethodType; 33 } // namespace mirror 34 35 // Returns true if there is a possible conversion from |from| to |to| 36 // for a MethodHandle parameter. 37 bool IsParameterTypeConvertible(ObjPtr<mirror::Class> from, 38 ObjPtr<mirror::Class> to); 39 40 // Returns true if there is a possible conversion from |from| to |to| 41 // for the return type of a MethodHandle. 42 bool IsReturnTypeConvertible(ObjPtr<mirror::Class> from, 43 ObjPtr<mirror::Class> to); 44 45 // Performs a conversion from type |from| to a distinct type |to| as 46 // part of conversion of |caller_type| to |callee_type|. The value to 47 // be converted is in |value|. Returns true on success and updates 48 // |value| with the converted value, false otherwise. 49 bool ConvertJValueCommon(Handle<mirror::MethodType> callsite_type, 50 Handle<mirror::MethodType> callee_type, 51 ObjPtr<mirror::Class> from, 52 ObjPtr<mirror::Class> to, 53 JValue* value) 54 REQUIRES_SHARED(Locks::mutator_lock_); 55 56 // Converts the value of the argument at position |index| from type 57 // expected by |callee_type| to type used by |callsite_type|. |value| 58 // represents the value to be converted. Returns true on success and 59 // updates |value|, false otherwise. 60 ALWAYS_INLINE bool ConvertArgumentValue(Handle<mirror::MethodType> callsite_type, 61 Handle<mirror::MethodType> callee_type, 62 int index, 63 JValue* value) 64 REQUIRES_SHARED(Locks::mutator_lock_); 65 66 // Converts the return value from return type yielded by 67 // |callee_type| to the return type yielded by 68 // |callsite_type|. |value| represents the value to be 69 // converted. Returns true on success and updates |value|, false 70 // otherwise. 71 ALWAYS_INLINE bool ConvertReturnValue(Handle<mirror::MethodType> callsite_type, 72 Handle<mirror::MethodType> callee_type, 73 JValue* value) 74 REQUIRES_SHARED(Locks::mutator_lock_); 75 76 // Perform argument conversions between |callsite_type| (the type of the 77 // incoming arguments) and |callee_type| (the type of the method being 78 // invoked). These include widening and narrowing conversions as well as 79 // boxing and unboxing. Returns true on success, on false on failure. A 80 // pending exception will always be set on failure. 81 // 82 // The values to be converted are read from an input source (of type G) 83 // that provides three methods : 84 // 85 // class G { 86 // // Used to read the next boolean/short/int or float value from the 87 // // source. 88 // uint32_t Get(); 89 // 90 // // Used to the read the next reference value from the source. 91 // ObjPtr<mirror::Object> GetReference(); 92 // 93 // // Used to read the next double or long value from the source. 94 // int64_t GetLong(); 95 // } 96 // 97 // After conversion, the values are written to an output sink (of type S) 98 // that provides three methods : 99 // 100 // class S { 101 // void Set(uint32_t); 102 // void SetReference(ObjPtr<mirror::Object>) 103 // void SetLong(int64_t); 104 // } 105 // 106 // The semantics and usage of the Set methods are analagous to the getter 107 // class. 108 // 109 // This method is instantiated in three different scenarions : 110 // - <S = ShadowFrameSetter, G = ShadowFrameGetter> : copying from shadow 111 // frame to shadow frame, used in a regular polymorphic non-exact invoke. 112 // - <S = EmulatedShadowFrameAccessor, G = ShadowFrameGetter> : entering into 113 // a transformer method from a polymorphic invoke. 114 // - <S = ShadowFrameStter, G = EmulatedStackFrameAccessor> : entering into 115 // a regular poly morphic invoke from a transformer method. 116 // 117 // TODO(narayan): If we find that the instantiations of this function take 118 // up too much space, we can make G / S abstract base classes that are 119 // overridden by concrete classes. 120 template <typename G, typename S> 121 bool PerformConversions(Thread* self, 122 Handle<mirror::MethodType> callsite_type, 123 Handle<mirror::MethodType> callee_type, 124 G* getter, 125 S* setter, 126 int32_t start_index, 127 int32_t end_index) REQUIRES_SHARED(Locks::mutator_lock_); 128 129 // A convenience class that allows for iteration through a list of 130 // input argument registers. This is used to iterate over input 131 // arguments while performing standard argument conversions. 132 class ShadowFrameGetter { 133 public: 134 ShadowFrameGetter(const ShadowFrame& shadow_frame, 135 const InstructionOperands* const operands, 136 size_t operand_index = 0u) shadow_frame_(shadow_frame)137 : shadow_frame_(shadow_frame), operands_(operands), operand_index_(operand_index) {} 138 Get()139 ALWAYS_INLINE uint32_t Get() REQUIRES_SHARED(Locks::mutator_lock_) { 140 return shadow_frame_.GetVReg(Next()); 141 } 142 GetLong()143 ALWAYS_INLINE int64_t GetLong() REQUIRES_SHARED(Locks::mutator_lock_) { 144 return shadow_frame_.GetVRegLong(NextLong()); 145 } 146 GetReference()147 ALWAYS_INLINE ObjPtr<mirror::Object> GetReference() REQUIRES_SHARED(Locks::mutator_lock_) { 148 return shadow_frame_.GetVRegReference(Next()); 149 } 150 151 private: Next()152 uint32_t Next() { 153 const uint32_t next = operands_->GetOperand(operand_index_); 154 operand_index_ += 1; 155 return next; 156 } 157 NextLong()158 uint32_t NextLong() { 159 const uint32_t next = operands_->GetOperand(operand_index_); 160 operand_index_ += 2; 161 return next; 162 } 163 164 const ShadowFrame& shadow_frame_; 165 const InstructionOperands* const operands_; // the set of register operands to read 166 size_t operand_index_; // the next register operand to read from frame 167 }; 168 169 // A convenience class that allows values to be written to a given shadow frame, 170 // starting at location |first_dst_reg|. 171 class ShadowFrameSetter { 172 public: ShadowFrameSetter(ShadowFrame * shadow_frame,size_t first_dst_reg)173 ShadowFrameSetter(ShadowFrame* shadow_frame, size_t first_dst_reg) 174 : shadow_frame_(shadow_frame), arg_index_(first_dst_reg) {} 175 Set(uint32_t value)176 ALWAYS_INLINE void Set(uint32_t value) REQUIRES_SHARED(Locks::mutator_lock_) { 177 shadow_frame_->SetVReg(arg_index_++, value); 178 } 179 SetReference(ObjPtr<mirror::Object> value)180 ALWAYS_INLINE void SetReference(ObjPtr<mirror::Object> value) 181 REQUIRES_SHARED(Locks::mutator_lock_) { 182 shadow_frame_->SetVRegReference(arg_index_++, value.Ptr()); 183 } 184 SetLong(int64_t value)185 ALWAYS_INLINE void SetLong(int64_t value) REQUIRES_SHARED(Locks::mutator_lock_) { 186 shadow_frame_->SetVRegLong(arg_index_, value); 187 arg_index_ += 2; 188 } 189 190 private: 191 ShadowFrame* shadow_frame_; 192 size_t arg_index_; 193 }; 194 195 bool MethodHandleInvoke(Thread* self, 196 ShadowFrame& shadow_frame, 197 Handle<mirror::MethodHandle> method_handle, 198 Handle<mirror::MethodType> callsite_type, 199 const InstructionOperands* const args, 200 JValue* result) 201 REQUIRES_SHARED(Locks::mutator_lock_); 202 203 bool MethodHandleInvokeExact(Thread* self, 204 ShadowFrame& shadow_frame, 205 Handle<mirror::MethodHandle> method_handle, 206 Handle<mirror::MethodType> callsite_type, 207 const InstructionOperands* const args, 208 JValue* result) 209 REQUIRES_SHARED(Locks::mutator_lock_); 210 211 } // namespace art 212 213 #endif // ART_RUNTIME_METHOD_HANDLES_H_ 214