• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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