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 "jvalue.h" 25 #include "mirror/class.h" 26 27 namespace art { 28 29 class ShadowFrame; 30 31 namespace mirror { 32 class EmulatedStackFrame; 33 class MethodHandle; 34 class MethodType; 35 } // namespace mirror 36 37 // Returns true if there is a possible conversion from |from| to |to| 38 // for a MethodHandle parameter. 39 bool IsParameterTypeConvertible(ObjPtr<mirror::Class> from, 40 ObjPtr<mirror::Class> to); 41 42 // Returns true if there is a possible conversion from |from| to |to| 43 // for the return type of a MethodHandle. 44 bool IsReturnTypeConvertible(ObjPtr<mirror::Class> from, 45 ObjPtr<mirror::Class> to); 46 47 // Performs a conversion from type |from| to a distinct type |to| as 48 // part of conversion of |caller_type| to |callee_type|. The value to 49 // be converted is in |value|. Returns true on success and updates 50 // |value| with the converted value, false otherwise. 51 bool ConvertJValueCommon(Handle<mirror::MethodType> callsite_type, 52 Handle<mirror::MethodType> callee_type, 53 ObjPtr<mirror::Class> from, 54 ObjPtr<mirror::Class> to, 55 JValue* value) 56 REQUIRES_SHARED(Locks::mutator_lock_); 57 58 // Converts the value of the argument at position |index| from type 59 // expected by |callee_type| to type used by |callsite_type|. |value| 60 // represents the value to be converted. Returns true on success and 61 // updates |value|, false otherwise. 62 ALWAYS_INLINE bool ConvertArgumentValue(Handle<mirror::MethodType> callsite_type, 63 Handle<mirror::MethodType> callee_type, 64 int index, 65 JValue* value) 66 REQUIRES_SHARED(Locks::mutator_lock_); 67 68 // Converts the return value from return type yielded by 69 // |callee_type| to the return type yielded by 70 // |callsite_type|. |value| represents the value to be 71 // converted. Returns true on success and updates |value|, false 72 // otherwise. 73 ALWAYS_INLINE bool ConvertReturnValue(Handle<mirror::MethodType> callsite_type, 74 Handle<mirror::MethodType> callee_type, 75 JValue* value) 76 REQUIRES_SHARED(Locks::mutator_lock_); 77 78 // Perform argument conversions between |callsite_type| (the type of the 79 // incoming arguments) and |callee_type| (the type of the method being 80 // invoked). These include widening and narrowing conversions as well as 81 // boxing and unboxing. Returns true on success, on false on failure. A 82 // pending exception will always be set on failure. 83 // 84 // The values to be converted are read from an input source (of type G) 85 // that provides three methods : 86 // 87 // class G { 88 // // Used to read the next boolean/short/int or float value from the 89 // // source. 90 // uint32_t Get(); 91 // 92 // // Used to the read the next reference value from the source. 93 // ObjPtr<mirror::Object> GetReference(); 94 // 95 // // Used to read the next double or long value from the source. 96 // int64_t GetLong(); 97 // } 98 // 99 // After conversion, the values are written to an output sink (of type S) 100 // that provides three methods : 101 // 102 // class S { 103 // void Set(uint32_t); 104 // void SetReference(ObjPtr<mirror::Object>) 105 // void SetLong(int64_t); 106 // } 107 // 108 // The semantics and usage of the Set methods are analagous to the getter 109 // class. 110 // 111 // This method is instantiated in three different scenarions : 112 // - <S = ShadowFrameSetter, G = ShadowFrameGetter> : copying from shadow 113 // frame to shadow frame, used in a regular polymorphic non-exact invoke. 114 // - <S = EmulatedShadowFrameAccessor, G = ShadowFrameGetter> : entering into 115 // a transformer method from a polymorphic invoke. 116 // - <S = ShadowFrameStter, G = EmulatedStackFrameAccessor> : entering into 117 // a regular poly morphic invoke from a transformer method. 118 // 119 // TODO(narayan): If we find that the instantiations of this function take 120 // up too much space, we can make G / S abstract base classes that are 121 // overridden by concrete classes. 122 template <typename G, typename S> 123 bool PerformConversions(Thread* self, 124 Handle<mirror::MethodType> callsite_type, 125 Handle<mirror::MethodType> callee_type, 126 G* getter, 127 S* setter, 128 int32_t start_index, 129 int32_t end_index) REQUIRES_SHARED(Locks::mutator_lock_); 130 131 template <typename G, typename S> 132 bool CopyArguments(Thread* self, 133 Handle<mirror::MethodType> method_type, 134 Handle<mirror::MethodType> callee_type, 135 G* getter, 136 S* setter) REQUIRES_SHARED(Locks::mutator_lock_); 137 138 bool MethodHandleInvoke(Thread* self, 139 ShadowFrame& shadow_frame, 140 Handle<mirror::MethodHandle> method_handle, 141 Handle<mirror::MethodType> callsite_type, 142 const InstructionOperands* const args, 143 JValue* result) 144 REQUIRES_SHARED(Locks::mutator_lock_); 145 146 bool MethodHandleInvokeExact(Thread* self, 147 ShadowFrame& shadow_frame, 148 Handle<mirror::MethodHandle> method_handle, 149 Handle<mirror::MethodType> callsite_type, 150 const InstructionOperands* const args, 151 JValue* result) 152 REQUIRES_SHARED(Locks::mutator_lock_); 153 154 void MethodHandleInvokeExactWithFrame(Thread* self, 155 Handle<mirror::MethodHandle> method_handle, 156 Handle<mirror::EmulatedStackFrame> stack_frame) 157 REQUIRES_SHARED(Locks::mutator_lock_); 158 159 } // namespace art 160 161 #endif // ART_RUNTIME_METHOD_HANDLES_H_ 162