This commit introduces C++ wrapper classes for Java heap objects.
[cacao.git] / src / vmcore / javaobjects.cpp
1 /* src/vmcore/javaobjects.cpp - functions to create and access Java objects
2
3    Copyright (C) 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 // REMOVEME
31 #include "native/vm/reflection.hpp"
32
33 #include "vm/access.h"
34 #include "vm/builtin.h"
35 #include "vm/global.h"
36
37 #include "vmcore/globals.hpp"
38 #include "vmcore/javaobjects.hpp"
39
40
41 /**
42  * Allocates a new java.lang.reflect.Constructor object and
43  * initializes the fields with the method passed.
44  */
45 java_handle_t* java_lang_reflect_Constructor::create(methodinfo *m)
46 {
47         java_handle_t* h;
48
49         /* Allocate a java.lang.reflect.Constructor object. */
50
51         h = builtin_new(class_java_lang_reflect_Constructor);
52
53         if (h == NULL)
54                 return NULL;
55
56         java_lang_reflect_Constructor rc(h);
57
58 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
59
60         /* Allocate a java.lang.reflect.VMConstructor object. */
61
62         h = builtin_new(class_java_lang_reflect_VMConstructor);
63
64         if (h == NULL)
65                 return NULL;
66
67         java_lang_reflect_VMConstructor rvmc(h, m);
68
69         // Link the two Java objects.
70
71         rc.set_cons(rvmc.get_handle());
72         rvmc.set_cons(rc.get_handle());
73
74 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
75
76         /* Calculate the slot. */
77
78         int slot = m - m->clazz->methods;
79
80         /* Set Java object instance fields. */
81
82         LLNI_field_set_cls(rc, clazz               , m->clazz);
83         LLNI_field_set_ref(rc, parameterTypes      , method_get_parametertypearray(m));
84         LLNI_field_set_ref(rc, exceptionTypes      , method_get_exceptionarray(m));
85         LLNI_field_set_val(rc, modifiers           , m->flags & ACC_CLASS_REFLECT_MASK);
86         LLNI_field_set_val(rc, slot                , slot);
87         LLNI_field_set_ref(rc, signature           , m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL);
88         LLNI_field_set_ref(rc, annotations         , method_get_annotations(m));
89         LLNI_field_set_ref(rc, parameterAnnotations, method_get_parameterannotations(m));
90
91 #else
92 # error unknown classpath configuration
93 #endif
94
95         return rc.get_handle();
96 }
97
98
99 /**
100  * Constructs a Java object with the given
101  * java.lang.reflect.Constructor.
102  *
103  * @param m        Method structure of the constructor.
104  * @param args     Constructor arguments.
105  * @param override Override security checks.
106  *
107  * @return Handle to Java object.
108  */
109 java_handle_t* java_lang_reflect_Constructor::new_instance(methodinfo* m, java_handle_objectarray_t* args, bool override)
110 {
111         java_handle_t* h;
112
113         // Should we bypass security the checks (AccessibleObject)?
114         if (override == false) {
115                 /* This method is always called like this:
116                        [0] java.lang.reflect.Constructor.constructNative (Native Method)
117                        [1] java.lang.reflect.Constructor.newInstance
118                        [2] <caller>
119                 */
120
121                 if (!access_check_method(m, 2))
122                         return NULL;
123         }
124
125         // Create a Java object.
126         h = builtin_new(m->clazz);
127
128         if (h == NULL)
129                 return NULL;
130         
131         // Call initializer.
132         (void) Reflection::invoke(m, h, args);
133
134         return h;
135 }
136
137
138 /**
139  * Creates a java.lang.reflect.Field object on the GC heap and
140  * intializes it with the given field.
141  *
142  * @param f Field structure.
143  *
144  * @return Handle to Java object.
145  */
146 java_handle_t* java_lang_reflect_Field::create(fieldinfo* f)
147 {
148         java_handle_t* h;
149
150         /* Allocate a java.lang.reflect.Field object. */
151
152         h = builtin_new(class_java_lang_reflect_Field);
153
154         if (h == NULL)
155                 return NULL;
156
157         java_lang_reflect_Field rf(h);
158
159 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
160
161         // Allocate a java.lang.reflect.VMField object.
162
163         h = builtin_new(class_java_lang_reflect_VMField);
164
165         if (h == NULL)
166                 return NULL;
167
168         java_lang_reflect_VMField rvmf(h, f);
169
170         // Link the two Java objects.
171
172         rf.set_f(rvmf.get_handle());
173         rvmf.set_f(rf.get_handle());
174
175 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
176
177         /* Calculate the slot. */
178
179         int slot = f - f->clazz->fields;
180
181         /* Set the Java object fields. */
182
183         LLNI_field_set_cls(rf, clazz,       f->clazz);
184
185         /* The name needs to be interned */
186         /* XXX implement me better! */
187
188         LLNI_field_set_ref(rf, name,        (java_lang_String *) javastring_intern(javastring_new(f->name)));
189         LLNI_field_set_cls(rf, type,        (java_lang_Class *) field_get_type(f));
190         LLNI_field_set_val(rf, modifiers,   f->flags);
191         LLNI_field_set_val(rf, slot,        slot);
192         LLNI_field_set_ref(rf, signature,   f->signature ? (java_lang_String *) javastring_new(f->signature) : NULL);
193         LLNI_field_set_ref(rf, annotations, field_get_annotations(f));
194
195 #else
196 # error unknown classpath configuration
197 #endif
198
199         return rf.get_handle();
200 }
201
202
203 /*
204  * Allocates a new java.lang.reflect.Method object and initializes the
205  * fields with the method passed.
206  *
207  * @param m Method structure.
208  *
209  * @return Handle to Java object.
210  */
211 java_handle_t* java_lang_reflect_Method::create(methodinfo *m)
212 {
213         java_handle_t* h;
214
215         /* Allocate a java.lang.reflect.Method object. */
216
217         h = builtin_new(class_java_lang_reflect_Method);
218
219         if (h == NULL)
220                 return NULL;
221
222         java_lang_reflect_Method rm(h);
223
224 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
225
226         /* Allocate a java.lang.reflect.VMMethod object. */
227
228         h = builtin_new(class_java_lang_reflect_VMMethod);
229
230         if (h == NULL)
231                 return NULL;
232
233         java_lang_reflect_VMMethod rvmm(h, m);
234
235         // Link the two Java objects.
236
237         rm.set_m(rvmm.get_handle());
238         rvmm.set_m(rm.get_handle());
239
240 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
241
242         /* Calculate the slot. */
243
244         int slot = m - m->clazz->methods;
245
246         LLNI_field_set_cls(rm, clazz,                m->clazz);
247
248         /* The name needs to be interned */
249         /* XXX implement me better! */
250
251         LLNI_field_set_ref(rm, name,                 (java_lang_String *) javastring_intern(javastring_new(m->name)));
252         LLNI_field_set_ref(rm, parameterTypes,       method_get_parametertypearray(m));
253         LLNI_field_set_cls(rm, returnType,           (java_lang_Class *) method_returntype_get(m));
254         LLNI_field_set_ref(rm, exceptionTypes,       method_get_exceptionarray(m));
255         LLNI_field_set_val(rm, modifiers,            m->flags & ACC_CLASS_REFLECT_MASK);
256         LLNI_field_set_val(rm, slot,                 slot);
257         LLNI_field_set_ref(rm, signature,            m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL);
258         LLNI_field_set_ref(rm, annotations,          method_get_annotations(m));
259         LLNI_field_set_ref(rm, parameterAnnotations, method_get_parameterannotations(m));
260         LLNI_field_set_ref(rm, annotationDefault,    method_get_annotationdefault(m));
261
262 #else
263 # error unknown classpath configuration
264 #endif
265
266         return rm.get_handle();
267 }
268
269
270 // Legacy C interface.
271
272 extern "C" {
273 java_handle_t* java_lang_reflect_Constructor_create(methodinfo* m) { return java_lang_reflect_Constructor::create(m); }
274 java_handle_t* java_lang_reflect_Field_create(fieldinfo* f) { return java_lang_reflect_Field::create(f); }
275 java_handle_t* java_lang_reflect_Method_create(methodinfo* m) { return java_lang_reflect_Method::create(m); }
276 }
277
278
279 /*
280  * These are local overrides for various environment variables in Emacs.
281  * Please do not remove this and leave it at the end of the file, where
282  * Emacs will automagically detect them.
283  * ---------------------------------------------------------------------
284  * Local variables:
285  * mode: c++
286  * indent-tabs-mode: t
287  * c-basic-offset: 4
288  * tab-width: 4
289  * End:
290  */