cafb69942680ad1dbb7bb9818f91ecb1a43f3273
[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 #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.h"
45 #include "vm/builtin.h"
46 #include "vm/class.h"
47 #include "vm/exceptions.hpp"
48 #include "vm/global.h"
49 #include "vm/globals.hpp"
50 #include "vm/initialize.h"
51 #include "vm/javaobjects.hpp"
52 #include "vm/method.h"
53 #include "vm/resolve.h"
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 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 jlrvmm(_this);
124         java_lang_reflect_Method jlrm(jlrvmm.get_m());
125
126         java_handle_t* result = jlrm.invoke((java_handle_t*) o, (java_handle_objectarray_t*) args);
127
128         return (jobject) result;
129 }
130
131
132 /*
133  * Class:     java/lang/reflect/VMMethod
134  * Method:    getSignature
135  * Signature: ()Ljava/lang/String;
136  */
137 JNIEXPORT jstring JNICALL Java_java_lang_reflect_VMMethod_getSignature(JNIEnv *env, jobject _this)
138 {
139         java_lang_reflect_VMMethod rvmm(_this);
140         methodinfo* m = rvmm.get_method();
141
142         if (m->signature == NULL)
143                 return NULL;
144
145         java_handle_t* s = javastring_new(m->signature);
146
147         /* in error case o is NULL */
148
149         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 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         utf                      *utf_parseAnnotationDefault = NULL; /* parser method name                                */
165         utf                      *utf_desc        = NULL;            /* parser method descriptor (signature)              */
166
167         if (_this == NULL) {
168                 exceptions_throw_nullpointerexception();
169                 return NULL;
170         }
171
172         // TODO Use a constructor.
173         java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
174
175         if (h == NULL)
176                 return NULL;
177
178         sun_reflect_ConstantPool cp(h);
179         
180         java_lang_reflect_VMMethod rvmm(_this);
181         classinfo* declaringClass = rvmm.get_clazz();
182         cp.set_constantPoolOop(declaringClass);
183
184         /* only resolve the parser method the first time */
185         if (m_parseAnnotationDefault == NULL) {
186                 utf_parseAnnotationDefault = utf_new_char("parseAnnotationDefault");
187                 utf_desc = utf_new_char(
188                         "(Ljava/lang/reflect/Method;[BLsun/reflect/ConstantPool;)"
189                         "Ljava/lang/Object;");
190
191                 if (utf_parseAnnotationDefault == NULL || utf_desc == NULL) {
192                         /* out of memory */
193                         return NULL;
194                 }
195
196                 classinfo *referer;
197                 LLNI_class_get((java_lang_reflect_VMMethod *) _this, referer);
198
199                 m_parseAnnotationDefault = class_resolveclassmethod(
200                         class_sun_reflect_annotation_AnnotationParser,
201                         utf_parseAnnotationDefault,
202                         utf_desc,
203                         referer,
204                         true);
205
206                 if (m_parseAnnotationDefault == NULL) {
207                         /* method not found */
208                         return NULL;
209                 }
210         }
211
212         java_lang_reflect_Method rm(rvmm.get_m());
213         java_handle_bytearray_t* annotationDefault = rvmm.get_annotationDefault();
214
215         java_handle_t* result = vm_call_method(m_parseAnnotationDefault, NULL, rm.get_handle(), annotationDefault, cp.get_handle());
216
217         return (jobject) result;
218 }
219
220
221 /*
222  * Class:     java/lang/reflect/VMMethod
223  * Method:    declaredAnnotations
224  * Signature: ()Ljava/util/Map;
225  */
226 JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_declaredAnnotations(JNIEnv *env, jobject _this)
227 {
228         java_lang_reflect_VMMethod rvmm(_this);
229         java_handle_t* declaredAnnotations = rvmm.get_declaredAnnotations();
230
231         // Are the annotations parsed yet?
232         if (declaredAnnotations == NULL) {
233                 java_handle_bytearray_t* annotations    = rvmm.get_annotations();
234                 classinfo*               declaringClass = rvmm.get_clazz();
235
236                 classinfo *referer;
237                 LLNI_class_get((java_lang_reflect_VMMethod *) _this, referer);
238
239                 declaredAnnotations = Reflection::get_declaredannotations(annotations, declaringClass, referer);
240
241                 rvmm.set_declaredAnnotations(declaredAnnotations);
242         }
243
244         return (jobject) declaredAnnotations;
245 }
246
247
248 /*
249  * Class:     java/lang/reflect/VMMethod
250  * Method:    getParameterAnnotations
251  * Signature: ()[[Ljava/lang/annotation/Annotation;
252  */
253 JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMMethod_getParameterAnnotations(JNIEnv *env, jobject _this)
254 {
255         java_lang_reflect_VMMethod rvmm(_this);
256         java_handle_bytearray_t* parameterAnnotations = rvmm.get_parameterAnnotations();
257         methodinfo* m = rvmm.get_method();
258
259         classinfo* referer;
260         LLNI_class_get((java_lang_reflect_VMMethod *) _this, referer);
261
262         java_handle_objectarray_t* oa = Reflection::get_parameterannotations(parameterAnnotations, m, referer);
263         return (jobjectArray) oa;
264 }
265 #endif
266
267 } // extern "C"
268
269
270 /* native methods implemented by this file ************************************/
271
272 static JNINativeMethod methods[] = {
273         { (char*) "getModifiersInternal",    (char*) "()I",                                                       (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getModifiersInternal    },
274         { (char*) "getReturnType",           (char*) "()Ljava/lang/Class;",                                       (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getReturnType           },
275         { (char*) "getParameterTypes",       (char*) "()[Ljava/lang/Class;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getParameterTypes       },
276         { (char*) "getExceptionTypes",       (char*) "()[Ljava/lang/Class;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getExceptionTypes       },
277         { (char*) "invoke",                  (char*) "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_invoke                  },
278         { (char*) "getSignature",            (char*) "()Ljava/lang/String;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getSignature            },
279 #if defined(ENABLE_ANNOTATIONS)
280         { (char*) "getDefaultValue",         (char*) "()Ljava/lang/Object;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getDefaultValue         },
281         { (char*) "declaredAnnotations",     (char*) "()Ljava/util/Map;",                                         (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_declaredAnnotations     },
282         { (char*) "getParameterAnnotations", (char*) "()[[Ljava/lang/annotation/Annotation;",                     (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getParameterAnnotations },
283 #endif
284 };
285
286
287 /* _Jv_java_lang_reflect_VMMethod_init *****************************************
288
289    Register native functions.
290
291 *******************************************************************************/
292
293 // FIXME
294 extern "C" {
295 void _Jv_java_lang_reflect_VMMethod_init(void)
296 {
297         utf *u;
298
299         u = utf_new_char("java/lang/reflect/VMMethod");
300
301         native_method_register(u, methods, NATIVE_METHODS_COUNT);
302 }
303 }
304
305
306 /*
307  * These are local overrides for various environment variables in Emacs.
308  * Please do not remove this and leave it at the end of the file, where
309  * Emacs will automagically detect them.
310  * ---------------------------------------------------------------------
311  * Local variables:
312  * mode: c++
313  * indent-tabs-mode: t
314  * c-basic-offset: 4
315  * tab-width: 4
316  * End:
317  */