CACAO
javaobjects.cpp
Go to the documentation of this file.
1 /* src/vm/javaobjects.cpp - functions to create and access Java objects
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5  Copyright (C) 2008, 2009 Theobroma Systems Ltd.
6 
7  This file is part of CACAO.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2, or (at
12  your option) any later version.
13 
14  This program is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  02110-1301, USA.
23 
24 */
25 
26 
27 #include "config.h"
28 
29 #include <stdint.h>
30 
31 #include "native/vm/reflection.hpp"
32 
33 #include "vm/access.hpp"
34 #include "vm/jit/builtin.hpp"
35 #include "vm/global.hpp"
36 #include "vm/globals.hpp"
37 #include "vm/initialize.hpp"
38 #include "vm/javaobjects.hpp"
39 #include "vm/vm.hpp"
40 
41 #include <map>
42 
43 #if defined(ENABLE_JAVASE)
44 
45 /**
46  * Invokes the static Java method getSystemClassLoader().
47  *
48  * @return Return value of the invocation or NULL in
49  * case of an exception.
50  */
52 {
53  methodinfo *m;
54  java_handle_t *clo;
55  classloader_t *cl;
56 
57  assert(class_java_lang_Object);
60 
62  utf8::getSystemClassLoader,
63  utf8::void__java_lang_ClassLoader,
65  false);
66 
67  if (m == NULL)
68  return NULL;
69 
70  clo = vm_call_method(m, NULL);
71 
72  if (clo == NULL)
73  return NULL;
74 
76 
77  return cl;
78 }
79 
80 
81 /**
82  * Constructs a new instance of the class by calling the
83  * appropriate Java initializer.
84  */
85 java_lang_management_MemoryUsage::java_lang_management_MemoryUsage(int64_t init, int64_t used, int64_t commited, int64_t maximum)
86 {
87  // Load the class.
88  // XXX Maybe this should be made global at some points.
89  classinfo* class_java_lang_management_MemoryUsage;
90  if (!(class_java_lang_management_MemoryUsage = load_class_bootstrap(Utf8String::from_utf8("java/lang/management/MemoryUsage"))))
91  return;
92 
93  // Find the appropriate initializer.
94  // XXX Maybe this should be made global at some points.
95  methodinfo* m = class_findmethod(class_java_lang_management_MemoryUsage,
96  utf8::init,
97  Utf8String::from_utf8("(JJJJ)V"));
98 
99  if (m == NULL)
100  return;
101 
102  // Instantiate a new object.
103  _handle = builtin_new(class_java_lang_management_MemoryUsage);
104 
105  if (is_null())
106  return;
107 
108  // Call initializer.
109  (void) vm_call_method(m, _handle, init, used, commited, maximum);
110 }
111 
112 
113 /**
114  * Constructs a Java object with the given
115  * java.lang.reflect.Constructor.
116  *
117  * @param args Constructor arguments.
118  *
119  * @return Handle to Java object.
120  */
122 {
123  methodinfo* m = get_method();
124 
125  // Should we bypass security the checks (AccessibleObject)?
126  if (get_override() == false) {
127  /* This method is always called like this:
128  [0] java.lang.reflect.Constructor.constructNative (Native Method)
129  [1] java.lang.reflect.Constructor.newInstance
130  [2] <caller>
131  */
132 
133  if (!access_check_method(m, 2))
134  return NULL;
135  }
136 
137  // Create a Java object.
139 
140  if (h == NULL)
141  return NULL;
142 
143  // Call initializer.
144  (void) Reflection::invoke(m, h, args);
145 
146  return h;
147 }
148 
149 
150 /**
151  * Invokes the given method.
152  *
153  * @param args Method arguments.
154  *
155  * @return return value of the method
156  */
158 {
159  methodinfo* m = get_method();
160 
161  // Should we bypass security the checks (AccessibleObject)?
162  if (get_override() == false) {
163 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
164  /* This method is always called like this:
165  [0] java.lang.reflect.Method.invokeNative (Native Method)
166  [1] java.lang.reflect.Method.invoke (Method.java:329)
167  [2] <caller>
168  */
169 
170  if (!access_check_method(m, 2))
171  return NULL;
172 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
173  /* We only pass 0 here as stacktrace_get_caller_class, which
174  is called from access_check_method, skips
175  java.lang.reflect.Method.invoke(). */
176 
177  if (!access_check_method(m, 0))
178  return NULL;
179 #else
180 # error unknown classpath configuration
181 #endif
182  }
183 
184  // Check if method class is initialized.
185  if (!(m->clazz->state & CLASS_INITIALIZED))
186  if (!initialize_class(m->clazz))
187  return NULL;
188 
189  // Call the Java method.
190  java_handle_t* result = Reflection::invoke(m, o, args);
191 
192  return result;
193 }
194 
196  void (*setter)(int32_t);
197  const char *name;
199 };
200 
201 typedef std::map<classinfo *, DynOffsetEntry *> RegisteredDynMap;
203 
205 {
206  dynEntryMap.insert(std::make_pair(c, entries));
207 }
208 
209 static bool runAllSetters(classinfo *c, DynOffsetEntry entries[])
210 {
211  do {
212  fieldinfo *fi = class_findfield_by_name(c, Utf8String::from_utf8(entries->name), false);
213  if (fi)
214  entries->setter(fi->offset);
215  else
216  if (entries->throwexception)
217  return false;
218  } while ((++entries)->setter);
219  return true;
220 }
221 
223 {
224  RegisteredDynMap::const_iterator it = dynEntryMap.find(c);
225  if (it == dynEntryMap.end())
226  return true;
227 
228  if (!runAllSetters(c, it->second))
229  return false;
230 
231  return true;
232 }
233 
234 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
235 
242 
244  { &java_lang_Thread::set_vmThread_offset, "vmThread", true },
245  { &java_lang_Thread::set_group_offset, "group", true },
246  { &java_lang_Thread::set_name_offset, "name", true },
247  { &java_lang_Thread::set_daemon_offset, "daemon", true },
248  { &java_lang_Thread::set_priority_offset, "priority", true },
249  { &java_lang_Thread::set_exceptionHandler_offset, "exceptionHandler", true },
250  { 0, 0 }
251 };
252 
253 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
254 
258 off_t java_lang_Thread::offset_uncaughtExceptionHandler;
259 off_t java_lang_Thread::offset_threadStatus;
260 #ifndef WITH_JAVA_RUNTIME_LIBRARY_OPENJDK_7
261 off_t java_lang_Thread::offset_me;
262 #endif
263 
264 static DynOffsetEntry dyn_entries_java_lang_Thread[] = {
265  { &java_lang_Thread::set_priority_offset, "priority", true },
266  { &java_lang_Thread::set_daemon_offset, "daemon", true },
267  { &java_lang_Thread::set_group_offset, "group", true },
268  { &java_lang_Thread::set_uncaughtExceptionHandler_offset, "uncaughtExceptionHandler", true },
269  { &java_lang_Thread::set_threadStatus_offset, "threadStatus", true },
270 #ifndef WITH_JAVA_RUNTIME_LIBRARY_OPENJDK_7
271  { &java_lang_Thread::set_me_offset, "me", true },
272 #endif
273  { 0, 0 }
274 };
275 
276 off_t java_lang_Class::offset_classLoader;
277 
278 static DynOffsetEntry dyn_entries_java_lang_Class[] = {
279  { &java_lang_Class::set_classLoader_offset, "classLoader", false },
280  { 0, 0 }
281 };
282 
283 #endif
284 
286 {
287  register_dyn_entry_table(class_java_lang_Thread, dyn_entries_java_lang_Thread);
288 #ifdef WITH_JAVA_RUNTIME_LIBRARY_OPENJDK_7
289  register_dyn_entry_table(class_java_lang_Class, dyn_entries_java_lang_Class);
290 #endif
291 }
292 
293 #endif // ENABLE_JAVASE
294 
295 
296 /*
297  * These are local overrides for various environment variables in Emacs.
298  * Please do not remove this and leave it at the end of the file, where
299  * Emacs will automagically detect them.
300  * ---------------------------------------------------------------------
301  * Local variables:
302  * mode: c++
303  * indent-tabs-mode: t
304  * c-basic-offset: 4
305  * tab-width: 4
306  * End:
307  * vim:noexpandtab:sw=4:ts=4:
308  */
static void set_group_offset(int32_t off)
const char * name
static off_t offset_exceptionHandler
static void register_dyn_entry_table(classinfo *c, DynOffsetEntry *entries)
methodinfo * class_resolveclassmethod(classinfo *c, Utf8String name, Utf8String desc, classinfo *referer, bool throwexception)
Definition: class.cpp:1211
java_lang_management_MemoryUsage(java_handle_t *h)
bool is_null() const
bool access_check_method(methodinfo *m, int callerdepth)
Definition: access.cpp:271
s4 state
Definition: class.hpp:115
static off_t offset_priority
void jobjects_register_dyn_offsets()
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
void(* setter)(int32_t)
static void set_priority_offset(int32_t off)
static java_handle_t * invoke(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *params)
Invoke a method on the given object with the given arguments.
Definition: reflection.cpp:59
classinfo * load_class_bootstrap(Utf8String name)
Definition: loader.cpp:1276
static off_t offset_vmThread
static void set_daemon_offset(int32_t off)
java_handle_t * vm_call_method(methodinfo *m, java_handle_t *o,...)
static bool runAllSetters(classinfo *c, DynOffsetEntry entries[])
static DynOffsetEntry dyn_entries_java_lang_Thread[]
classinfo * class_java_lang_Object
Definition: globals.cpp:28
static RegisteredDynMap dynEntryMap
static void set_vmThread_offset(int32_t off)
std::map< classinfo *, DynOffsetEntry * > RegisteredDynMap
methodinfo * class_findmethod(classinfo *c, Utf8String name, Utf8String desc)
Definition: class.cpp:1124
classloader_t * loader_hashtable_classloader_add(java_handle_t *cl)
Definition: loader.cpp:305
java_handle_t * builtin_new(classinfo *c)
Definition: builtin.cpp:816
java_handle_t * invoke(java_handle_t *o, java_handle_objectarray_t *args)
Invokes the given method.
fieldinfo * class_findfield_by_name(classinfo *c, Utf8String name, bool throwexception)
Definition: class.cpp:1319
static void set_name_offset(int32_t off)
int32_t offset
Definition: field.hpp:66
classinfo * clazz
Definition: method.hpp:80
bool jobjects_run_dynoffsets_hook(classinfo *c)
static off_t offset_daemon
int32_t get_override() const
classinfo * class_java_lang_Class
Definition: globals.cpp:35
static Utf8String from_utf8(const char *, size_t)
Definition: utf8.cpp:335
bool initialize_class(classinfo *c)
Definition: initialize.cpp:110
static java_handle_t * invoke_getSystemClassLoader()
Invokes the static Java method getSystemClassLoader().
Definition: javaobjects.cpp:51
java_handle_t * new_instance(java_handle_objectarray_t *args)
Constructs a Java object with the given java.lang.reflect.Constructor.
methodinfo * get_method() const
static off_t offset_group
methodinfo * get_method() const
java_handle_t * _handle
classinfo * class_java_lang_Thread
Definition: globals.cpp:41
static off_t offset_name
classinfo * class_java_lang_ClassLoader
Definition: globals.cpp:36
static void set_exceptionHandler_offset(int32_t off)