Line data Source code
1 : /* src/native/vm/gnuclasspath/java_lang_reflect_VMMethod.cpp
2 :
3 : Copyright (C) 1996-2013
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 :
26 : #include "config.h"
27 :
28 : #include <stdint.h>
29 :
30 : #if defined(ENABLE_ANNOTATIONS)
31 : #include "vm/vm.hpp"
32 : #endif
33 :
34 : #include "native/jni.hpp"
35 : #include "native/llni.hpp"
36 : #include "native/native.hpp"
37 :
38 : #if defined(ENABLE_JNI_HEADERS)
39 : # include "native/vm/include/java_lang_reflect_VMMethod.h"
40 : #endif
41 :
42 : #include "native/vm/reflection.hpp"
43 :
44 : #include "vm/access.hpp"
45 : #include "vm/jit/builtin.hpp"
46 : #include "vm/class.hpp"
47 : #include "vm/exceptions.hpp"
48 : #include "vm/global.hpp"
49 : #include "vm/globals.hpp"
50 : #include "vm/initialize.hpp"
51 : #include "vm/javaobjects.hpp"
52 : #include "vm/method.hpp"
53 : #include "vm/resolve.hpp"
54 : #include "vm/string.hpp"
55 :
56 :
57 : // Native functions are exported as C functions.
58 : extern "C" {
59 :
60 : /*
61 : * Class: java/lang/reflect/VMMethod
62 : * Method: getModifiersInternal
63 : * Signature: ()I
64 : */
65 62 : JNIEXPORT jint JNICALL Java_java_lang_reflect_VMMethod_getModifiersInternal(JNIEnv *env, jobject _this)
66 : {
67 62 : java_lang_reflect_VMMethod rvmm(_this);
68 62 : methodinfo* m = rvmm.get_method();
69 62 : return m->flags;
70 : }
71 :
72 :
73 : /*
74 : * Class: java/lang/reflect/VMMethod
75 : * Method: getReturnType
76 : * Signature: ()Ljava/lang/Class;
77 : */
78 987 : JNIEXPORT jclass JNICALL Java_java_lang_reflect_VMMethod_getReturnType(JNIEnv *env, jobject _this)
79 : {
80 987 : java_lang_reflect_VMMethod rvmm(_this);
81 987 : methodinfo* m = rvmm.get_method();
82 987 : classinfo* c = method_returntype_get(m);
83 :
84 987 : return (jclass) LLNI_classinfo_wrap(c);
85 : }
86 :
87 :
88 : /*
89 : * Class: java/lang/reflect/VMMethod
90 : * Method: getParameterTypes
91 : * Signature: ()[Ljava/lang/Class;
92 : */
93 1259 : JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMMethod_getParameterTypes(JNIEnv *env, jobject _this)
94 : {
95 1259 : java_lang_reflect_VMMethod rvmm(_this);
96 1259 : methodinfo* m = rvmm.get_method();
97 1259 : java_handle_objectarray_t* oa = method_get_parametertypearray(m);
98 1259 : return (jobjectArray) oa;
99 : }
100 :
101 :
102 : /*
103 : * Class: java/lang/reflect/VMMethod
104 : * Method: getExceptionTypes
105 : * Signature: ()[Ljava/lang/Class;
106 : */
107 74 : JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMMethod_getExceptionTypes(JNIEnv *env, jobject _this)
108 : {
109 74 : java_lang_reflect_VMMethod rvmm(_this);
110 74 : methodinfo* m = rvmm.get_method();
111 74 : java_handle_objectarray_t* oa = method_get_exceptionarray(m);
112 74 : return (jobjectArray) oa;
113 : }
114 :
115 :
116 : /*
117 : * Class: java/lang/reflect/VMMethod
118 : * Method: invoke
119 : * Signature: (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
120 : */
121 385 : JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_invoke(JNIEnv *env, jobject _this, jobject o, jobjectArray args)
122 : {
123 385 : java_lang_reflect_VMMethod jlrvmm(_this);
124 385 : java_lang_reflect_Method jlrm(jlrvmm.get_m());
125 :
126 385 : java_handle_t* result = jlrm.invoke((java_handle_t*) o, (java_handle_objectarray_t*) args);
127 :
128 385 : return (jobject) result;
129 : }
130 :
131 :
132 : /*
133 : * Class: java/lang/reflect/VMMethod
134 : * Method: getSignature
135 : * Signature: ()Ljava/lang/String;
136 : */
137 0 : JNIEXPORT jstring JNICALL Java_java_lang_reflect_VMMethod_getSignature(JNIEnv *env, jobject _this)
138 : {
139 0 : java_lang_reflect_VMMethod rvmm(_this);
140 0 : methodinfo* m = rvmm.get_method();
141 :
142 0 : if (m->signature == NULL)
143 0 : return NULL;
144 :
145 0 : java_handle_t* s = JavaString::from_utf8(m->signature);
146 :
147 : /* in error case o is NULL */
148 :
149 0 : return (jstring) s;
150 : }
151 :
152 :
153 : #if defined(ENABLE_ANNOTATIONS)
154 : /*
155 : * Class: java/lang/reflect/VMMethod
156 : * Method: getDefaultValue
157 : * Signature: ()Ljava/lang/Object;
158 : *
159 : * Parses the annotation default value and returnes it (boxed, if it's a primitive).
160 : */
161 53 : JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_getDefaultValue(JNIEnv *env, jobject _this)
162 : {
163 : static methodinfo *m_parseAnnotationDefault = NULL; /* parser method (will be chached, therefore static) */
164 53 : Utf8String utf_parseAnnotationDefault = NULL; /* parser method name */
165 53 : Utf8String utf_desc = NULL; /* parser method descriptor (signature) */
166 :
167 53 : if (_this == NULL) {
168 0 : exceptions_throw_nullpointerexception();
169 0 : return NULL;
170 : }
171 :
172 : // TODO Use a constructor.
173 53 : java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
174 :
175 53 : if (h == NULL)
176 0 : return NULL;
177 :
178 53 : sun_reflect_ConstantPool cp(h);
179 :
180 53 : java_lang_reflect_VMMethod rvmm(_this);
181 53 : classinfo* declaringClass = rvmm.get_clazz();
182 53 : cp.set_constantPoolOop(declaringClass);
183 :
184 : /* only resolve the parser method the first time */
185 53 : if (m_parseAnnotationDefault == NULL) {
186 3 : utf_parseAnnotationDefault = Utf8String::from_utf8("parseAnnotationDefault");
187 : utf_desc = Utf8String::from_utf8(
188 : "(Ljava/lang/reflect/Method;[BLsun/reflect/ConstantPool;)"
189 3 : "Ljava/lang/Object;");
190 :
191 3 : if (utf_parseAnnotationDefault == NULL || utf_desc == NULL) {
192 : /* out of memory */
193 0 : return NULL;
194 : }
195 :
196 3 : classinfo *referer = rvmm.get_Class();
197 :
198 : m_parseAnnotationDefault = class_resolveclassmethod(
199 : class_sun_reflect_annotation_AnnotationParser,
200 : utf_parseAnnotationDefault,
201 : utf_desc,
202 : referer,
203 3 : true);
204 :
205 3 : if (m_parseAnnotationDefault == NULL) {
206 : /* method not found */
207 0 : return NULL;
208 : }
209 : }
210 :
211 53 : java_lang_reflect_Method rm(rvmm.get_m());
212 53 : java_handle_bytearray_t* annotationDefault = rvmm.get_annotationDefault();
213 :
214 53 : java_handle_t* result = vm_call_method(m_parseAnnotationDefault, NULL, rm.get_handle(), annotationDefault, cp.get_handle());
215 :
216 53 : return (jobject) result;
217 : }
218 :
219 :
220 : /*
221 : * Class: java/lang/reflect/VMMethod
222 : * Method: declaredAnnotations
223 : * Signature: ()Ljava/util/Map;
224 : */
225 1092 : JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_declaredAnnotations(JNIEnv *env, jobject _this)
226 : {
227 1092 : java_lang_reflect_VMMethod rvmm(_this);
228 1092 : java_handle_t* declaredAnnotations = rvmm.get_declaredAnnotations();
229 :
230 : // Are the annotations parsed yet?
231 1092 : if (declaredAnnotations == NULL) {
232 408 : java_handle_bytearray_t* annotations = rvmm.get_annotations();
233 408 : classinfo* declaringClass = rvmm.get_clazz();
234 408 : classinfo* referer = rvmm.get_Class();
235 :
236 408 : declaredAnnotations = Reflection::get_declaredannotations(annotations, declaringClass, referer);
237 :
238 408 : rvmm.set_declaredAnnotations(declaredAnnotations);
239 : }
240 :
241 1092 : return (jobject) declaredAnnotations;
242 : }
243 :
244 :
245 : /*
246 : * Class: java/lang/reflect/VMMethod
247 : * Method: getParameterAnnotations
248 : * Signature: ()[[Ljava/lang/annotation/Annotation;
249 : */
250 10 : JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMMethod_getParameterAnnotations(JNIEnv *env, jobject _this)
251 : {
252 10 : java_lang_reflect_VMMethod rvmm(_this);
253 10 : java_handle_bytearray_t* parameterAnnotations = rvmm.get_parameterAnnotations();
254 10 : methodinfo* m = rvmm.get_method();
255 10 : classinfo* referer = rvmm.get_Class();
256 :
257 10 : java_handle_objectarray_t* oa = Reflection::get_parameterannotations(parameterAnnotations, m, referer);
258 10 : return (jobjectArray) oa;
259 : }
260 : #endif
261 :
262 : } // extern "C"
263 :
264 :
265 : /* native methods implemented by this file ************************************/
266 :
267 : static JNINativeMethod methods[] = {
268 : { (char*) "getModifiersInternal", (char*) "()I", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getModifiersInternal },
269 : { (char*) "getReturnType", (char*) "()Ljava/lang/Class;", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getReturnType },
270 : { (char*) "getParameterTypes", (char*) "()[Ljava/lang/Class;", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getParameterTypes },
271 : { (char*) "getExceptionTypes", (char*) "()[Ljava/lang/Class;", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getExceptionTypes },
272 : { (char*) "invoke", (char*) "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_invoke },
273 : { (char*) "getSignature", (char*) "()Ljava/lang/String;", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getSignature },
274 : #if defined(ENABLE_ANNOTATIONS)
275 : { (char*) "getDefaultValue", (char*) "()Ljava/lang/Object;", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getDefaultValue },
276 : { (char*) "declaredAnnotations", (char*) "()Ljava/util/Map;", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_declaredAnnotations },
277 : { (char*) "getParameterAnnotations", (char*) "()[[Ljava/lang/annotation/Annotation;", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getParameterAnnotations },
278 : #endif
279 : };
280 :
281 :
282 : /* _Jv_java_lang_reflect_VMMethod_init *****************************************
283 :
284 : Register native functions.
285 :
286 : *******************************************************************************/
287 :
288 163 : void _Jv_java_lang_reflect_VMMethod_init(void)
289 : {
290 163 : Utf8String u = Utf8String::from_utf8("java/lang/reflect/VMMethod");
291 :
292 163 : NativeMethods& nm = VM::get_current()->get_nativemethods();
293 163 : nm.register_methods(u, methods, NATIVE_METHODS_COUNT);
294 163 : }
295 :
296 :
297 : /*
298 : * These are local overrides for various environment variables in Emacs.
299 : * Please do not remove this and leave it at the end of the file, where
300 : * Emacs will automagically detect them.
301 : * ---------------------------------------------------------------------
302 : * Local variables:
303 : * mode: c++
304 : * indent-tabs-mode: t
305 : * c-basic-offset: 4
306 : * tab-width: 4
307 : * End:
308 : */
|