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