4eea085f26b1e314fdb0538a940bf00623a05fc0
[cacao.git] / src / native / vm / gnuclasspath / java_lang_reflect_VMMethod.cpp
1 /* src/native/vm/gnuclasspath/java_lang_reflect_VMMethod.cpp
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
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.h"
35 #include "native/llni.h"
36 #include "native/native.h"
37
38 // FIXME
39 //#include "native/include/java_lang_reflect_VMMethod.h"
40
41 #include "native/vm/reflection.hpp"
42
43 #include "vm/access.h"
44 #include "vm/global.h"
45 #include "vm/builtin.h"
46 #include "vm/exceptions.hpp"
47 #include "vm/initialize.h"
48 #include "vm/resolve.h"
49 #include "vm/string.hpp"
50
51 #include "vmcore/class.h"
52 #include "vmcore/globals.hpp"
53 #include "vmcore/javaobjects.hpp"
54 #include "vmcore/method.h"
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 JNIEXPORT jint JNICALL Java_java_lang_reflect_VMMethod_getModifiersInternal(JNIEnv *env, jobject _this)
66 {
67         java_lang_reflect_VMMethod rvmm(_this);
68         methodinfo* m = rvmm.get_method();
69         return m->flags;
70 }
71
72
73 /*
74  * Class:     java/lang/reflect/VMMethod
75  * Method:    getReturnType
76  * Signature: ()Ljava/lang/Class;
77  */
78 JNIEXPORT jclass JNICALL Java_java_lang_reflect_VMMethod_getReturnType(JNIEnv *env, jobject _this)
79 {
80         java_lang_reflect_VMMethod rvmm(_this);
81         methodinfo* m = rvmm.get_method();
82         classinfo*  c = method_returntype_get(m);
83
84         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 JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMMethod_getParameterTypes(JNIEnv *env, jobject _this)
94 {
95         java_lang_reflect_VMMethod rvmm(_this);
96         methodinfo* m = rvmm.get_method();
97         java_handle_objectarray_t* oa = method_get_parametertypearray(m);
98         return (jobjectArray) oa;
99 }
100
101
102 /*
103  * Class:     java/lang/reflect/VMMethod
104  * Method:    getExceptionTypes
105  * Signature: ()[Ljava/lang/Class;
106  */
107 JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMMethod_getExceptionTypes(JNIEnv *env, jobject _this)
108 {
109         java_lang_reflect_VMMethod rvmm(_this);
110         methodinfo* m = rvmm.get_method();
111         java_handle_objectarray_t* oa = method_get_exceptionarray(m);
112         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 JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_invoke(JNIEnv *env, jobject _this, jobject o, jobjectArray args)
122 {
123         java_lang_reflect_VMMethod rvmm(_this);
124         java_lang_reflect_Method rm(rvmm.get_m());
125
126         methodinfo* m = rvmm.get_method();
127         int32_t override = rm.get_flag();
128
129         java_handle_t* result = Reflection::method_invoke(m, (java_handle_t*) o, (java_handle_objectarray_t*) args, override);
130
131         return (jobject) result;
132 }
133
134
135 /*
136  * Class:     java/lang/reflect/VMMethod
137  * Method:    getSignature
138  * Signature: ()Ljava/lang/String;
139  */
140 JNIEXPORT jstring JNICALL Java_java_lang_reflect_VMMethod_getSignature(JNIEnv *env, jobject _this)
141 {
142         java_lang_reflect_VMMethod rvmm(_this);
143         methodinfo* m = rvmm.get_method();
144
145         if (m->signature == NULL)
146                 return NULL;
147
148         java_handle_t* s = javastring_new(m->signature);
149
150         /* in error case o is NULL */
151
152         return (jstring) s;
153 }
154
155
156 #if defined(ENABLE_ANNOTATIONS)
157 /*
158  * Class:     java/lang/reflect/VMMethod
159  * Method:    getDefaultValue
160  * Signature: ()Ljava/lang/Object;
161  *
162  * Parses the annotation default value and returnes it (boxed, if it's a primitive).
163  */
164 JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_getDefaultValue(JNIEnv *env, jobject _this)
165 {
166         static methodinfo        *m_parseAnnotationDefault   = NULL; /* parser method (will be chached, therefore static) */
167         utf                      *utf_parseAnnotationDefault = NULL; /* parser method name                                */
168         utf                      *utf_desc        = NULL;            /* parser method descriptor (signature)              */
169
170         if (_this == NULL) {
171                 exceptions_throw_nullpointerexception();
172                 return NULL;
173         }
174
175         // TODO Use a constructor.
176         java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
177
178         if (h == NULL)
179                 return NULL;
180
181         sun_reflect_ConstantPool cp(h);
182         
183         java_lang_reflect_VMMethod rvmm(_this);
184         classinfo* declaringClass = rvmm.get_clazz();
185         cp.set_constantPoolOop(declaringClass);
186
187         /* only resolve the parser method the first time */
188         if (m_parseAnnotationDefault == NULL) {
189                 utf_parseAnnotationDefault = utf_new_char("parseAnnotationDefault");
190                 utf_desc = utf_new_char(
191                         "(Ljava/lang/reflect/Method;[BLsun/reflect/ConstantPool;)"
192                         "Ljava/lang/Object;");
193
194                 if (utf_parseAnnotationDefault == NULL || utf_desc == NULL) {
195                         /* out of memory */
196                         return NULL;
197                 }
198
199                 classinfo *referer;
200                 LLNI_class_get((java_lang_reflect_VMMethod *) _this, referer);
201
202                 m_parseAnnotationDefault = class_resolveclassmethod(
203                         class_sun_reflect_annotation_AnnotationParser,
204                         utf_parseAnnotationDefault,
205                         utf_desc,
206                         referer,
207                         true);
208
209                 if (m_parseAnnotationDefault == NULL) {
210                         /* method not found */
211                         return NULL;
212                 }
213         }
214
215         java_lang_reflect_Method rm(rvmm.get_m());
216         java_handle_bytearray_t* annotationDefault = rvmm.get_annotationDefault();
217
218         java_handle_t* result = vm_call_method(m_parseAnnotationDefault, NULL, rm.get_handle(), annotationDefault, cp.get_handle());
219
220         return (jobject) result;
221 }
222
223
224 /*
225  * Class:     java/lang/reflect/VMMethod
226  * Method:    declaredAnnotations
227  * Signature: ()Ljava/util/Map;
228  */
229 JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_declaredAnnotations(JNIEnv *env, jobject _this)
230 {
231         java_lang_reflect_VMMethod rvmm(_this);
232         java_handle_t* declaredAnnotations = rvmm.get_declaredAnnotations();
233
234         // Are the annotations parsed yet?
235         if (declaredAnnotations == NULL) {
236                 java_handle_bytearray_t* annotations    = rvmm.get_annotations();
237                 classinfo*               declaringClass = rvmm.get_clazz();
238
239                 classinfo *referer;
240                 LLNI_class_get((java_lang_reflect_VMMethod *) _this, referer);
241
242                 declaredAnnotations = Reflection::get_declaredannotations(annotations, declaringClass, referer);
243
244                 rvmm.set_declaredAnnotations(declaredAnnotations);
245         }
246
247         return (jobject) declaredAnnotations;
248 }
249
250
251 /*
252  * Class:     java/lang/reflect/VMMethod
253  * Method:    getParameterAnnotations
254  * Signature: ()[[Ljava/lang/annotation/Annotation;
255  */
256 JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMMethod_getParameterAnnotations(JNIEnv *env, jobject _this)
257 {
258         java_lang_reflect_VMMethod rvmm(_this);
259         java_handle_bytearray_t* parameterAnnotations = rvmm.get_parameterAnnotations();
260         methodinfo* m = rvmm.get_method();
261
262         classinfo* referer;
263         LLNI_class_get((java_lang_reflect_VMMethod *) _this, referer);
264
265         java_handle_objectarray_t* oa = Reflection::get_parameterannotations(parameterAnnotations, m, referer);
266         return (jobjectArray) oa;
267 }
268 #endif
269
270 } // extern "C"
271
272
273 /* native methods implemented by this file ************************************/
274
275 static JNINativeMethod methods[] = {
276         { (char*) "getModifiersInternal",    (char*) "()I",                                                       (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getModifiersInternal    },
277         { (char*) "getReturnType",           (char*) "()Ljava/lang/Class;",                                       (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getReturnType           },
278         { (char*) "getParameterTypes",       (char*) "()[Ljava/lang/Class;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getParameterTypes       },
279         { (char*) "getExceptionTypes",       (char*) "()[Ljava/lang/Class;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getExceptionTypes       },
280         { (char*) "invoke",                  (char*) "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_invoke                  },
281         { (char*) "getSignature",            (char*) "()Ljava/lang/String;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getSignature            },
282 #if defined(ENABLE_ANNOTATIONS)
283         { (char*) "getDefaultValue",         (char*) "()Ljava/lang/Object;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getDefaultValue         },
284         { (char*) "declaredAnnotations",     (char*) "()Ljava/util/Map;",                                         (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_declaredAnnotations     },
285         { (char*) "getParameterAnnotations", (char*) "()[[Ljava/lang/annotation/Annotation;",                     (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getParameterAnnotations },
286 #endif
287 };
288
289
290 /* _Jv_java_lang_reflect_VMMethod_init *****************************************
291
292    Register native functions.
293
294 *******************************************************************************/
295
296 // FIXME
297 extern "C" {
298 void _Jv_java_lang_reflect_VMMethod_init(void)
299 {
300         utf *u;
301
302         u = utf_new_char("java/lang/reflect/VMMethod");
303
304         native_method_register(u, methods, NATIVE_METHODS_COUNT);
305 }
306 }
307
308
309 /*
310  * These are local overrides for various environment variables in Emacs.
311  * Please do not remove this and leave it at the end of the file, where
312  * Emacs will automagically detect them.
313  * ---------------------------------------------------------------------
314  * Local variables:
315  * mode: c++
316  * indent-tabs-mode: t
317  * c-basic-offset: 4
318  * tab-width: 4
319  * End:
320  */