* src/threads/thread.cpp (threads_thread_is_alive): Recognize parked states.
[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.hpp"
35 #include "native/llni.h"
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.h"
45 #include "vm/jit/builtin.hpp"
46 #include "vm/class.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/global.h"
49 #include "vm/globals.hpp"
50 #include "vm/initialize.hpp"
51 #include "vm/javaobjects.hpp"
52 #include "vm/method.h"
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 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 = rvmm.get_Class();
197
198                 m_parseAnnotationDefault = class_resolveclassmethod(
199                         class_sun_reflect_annotation_AnnotationParser,
200                         utf_parseAnnotationDefault,
201                         utf_desc,
202                         referer,
203                         true);
204
205                 if (m_parseAnnotationDefault == NULL) {
206                         /* method not found */
207                         return NULL;
208                 }
209         }
210
211         java_lang_reflect_Method rm(rvmm.get_m());
212         java_handle_bytearray_t* annotationDefault = rvmm.get_annotationDefault();
213
214         java_handle_t* result = vm_call_method(m_parseAnnotationDefault, NULL, rm.get_handle(), annotationDefault, cp.get_handle());
215
216         return (jobject) result;
217 }
218
219
220 /*
221  * Class:     java/lang/reflect/VMMethod
222  * Method:    declaredAnnotations
223  * Signature: ()Ljava/util/Map;
224  */
225 JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_declaredAnnotations(JNIEnv *env, jobject _this)
226 {
227         java_lang_reflect_VMMethod rvmm(_this);
228         java_handle_t* declaredAnnotations = rvmm.get_declaredAnnotations();
229
230         // Are the annotations parsed yet?
231         if (declaredAnnotations == NULL) {
232                 java_handle_bytearray_t* annotations    = rvmm.get_annotations();
233                 classinfo*               declaringClass = rvmm.get_clazz();
234                 classinfo*               referer        = rvmm.get_Class();
235
236                 declaredAnnotations = Reflection::get_declaredannotations(annotations, declaringClass, referer);
237
238                 rvmm.set_declaredAnnotations(declaredAnnotations);
239         }
240
241         return (jobject) declaredAnnotations;
242 }
243
244
245 /*
246  * Class:     java/lang/reflect/VMMethod
247  * Method:    getParameterAnnotations
248  * Signature: ()[[Ljava/lang/annotation/Annotation;
249  */
250 JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMMethod_getParameterAnnotations(JNIEnv *env, jobject _this)
251 {
252         java_lang_reflect_VMMethod rvmm(_this);
253         java_handle_bytearray_t* parameterAnnotations = rvmm.get_parameterAnnotations();
254         methodinfo* m = rvmm.get_method();
255         classinfo* referer = rvmm.get_Class();
256
257         java_handle_objectarray_t* oa = Reflection::get_parameterannotations(parameterAnnotations, m, referer);
258         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 void _Jv_java_lang_reflect_VMMethod_init(void)
289 {
290         utf* u = utf_new_char("java/lang/reflect/VMMethod");
291
292         NativeMethods& nm = VM::get_current()->get_nativemethods();
293         nm.register_methods(u, methods, NATIVE_METHODS_COUNT);
294 }
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  */