* src/threads/thread.cpp: Break a reference cycle.
[cacao.git] / src / vm / javaobjects.cpp
index b8a0d601326b5b830b68e14a474d44ca009341df..cb862ee2c5d3dc91dc477d86a84820b8b6127911 100644 (file)
@@ -1,6 +1,8 @@
 /* src/vm/javaobjects.cpp - functions to create and access Java objects
 
-   Copyright (C) 2008 Theobroma Systems Ltd.
+   Copyright (C) 1996-2011
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2008, 2009 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
 #include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
 
+#include <map>
 
 #if defined(ENABLE_JAVASE)
 
+/**
+ * Invokes the static Java method getSystemClassLoader().
+ *
+ * @return Return value of the invocation or NULL in
+ * case of an exception.
+ */
+java_handle_t* java_lang_ClassLoader::invoke_getSystemClassLoader()
+{
+       methodinfo    *m;
+       java_handle_t *clo;
+       classloader_t *cl;
+
+       assert(class_java_lang_Object);
+       assert(class_java_lang_ClassLoader);
+       assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
+
+       m = class_resolveclassmethod(class_java_lang_ClassLoader,
+                                                                utf_getSystemClassLoader,
+                                                                utf_void__java_lang_ClassLoader,
+                                                                class_java_lang_Object,
+                                                                false);
+
+       if (m == NULL)
+               return NULL;
+
+       clo = vm_call_method(m, NULL);
+
+       if (clo == NULL)
+               return NULL;
+
+       cl = loader_hashtable_classloader_add(clo);
+
+       return cl;
+}
+
+
+/**
+ * Constructs a new instance of the class by calling the
+ * appropriate Java initializer.
+ */
+java_lang_management_MemoryUsage::java_lang_management_MemoryUsage(int64_t init, int64_t used, int64_t commited, int64_t maximum)
+{
+       // Load the class.
+       // XXX Maybe this should be made global at some points.
+       classinfo* class_java_lang_management_MemoryUsage;
+       if (!(class_java_lang_management_MemoryUsage = load_class_bootstrap(utf_new_char("java/lang/management/MemoryUsage"))))
+               return;
+
+       // Find the appropriate initializer.
+       // XXX Maybe this should be made global at some points.
+       methodinfo* m = class_findmethod(class_java_lang_management_MemoryUsage,
+                                                                        utf_init,
+                                                                        utf_new_char("(JJJJ)V"));
+
+       if (m == NULL)
+               return;
+
+       // Instantiate a new object.
+       _handle = builtin_new(class_java_lang_management_MemoryUsage);
+
+       if (is_null())
+               return;
+
+       // Call initializer.
+       (void) vm_call_method(m, _handle, init, used, commited, maximum);
+}
+
+
 /**
  * Constructs a Java object with the given
  * java.lang.reflect.Constructor.
@@ -67,7 +138,7 @@ java_handle_t* java_lang_reflect_Constructor::new_instance(java_handle_objectarr
 
        if (h == NULL)
                return NULL;
-        
+
        // Call initializer.
        (void) Reflection::invoke(m, h, args);
 
@@ -120,6 +191,87 @@ java_handle_t* java_lang_reflect_Method::invoke(java_handle_t* o, java_handle_ob
        return result;
 }
 
+struct DynOffsetEntry {
+       void (*setter)(int32_t);
+       const char *name;
+};
+
+typedef std::map<classinfo *, DynOffsetEntry *> RegisteredDynMap;
+static RegisteredDynMap dynEntryMap;
+
+static void register_dyn_entry_table(classinfo *c, DynOffsetEntry *entries)
+{
+       dynEntryMap.insert(std::make_pair(c, entries));
+}
+
+static bool runAllSetters(classinfo *c, DynOffsetEntry entries[])
+{
+       do {
+               fieldinfo *fi = class_findfield_by_name(c, utf_new_char(entries->name));
+               if (!fi)
+                       return false;
+               entries->setter(fi->offset);
+       } while ((++entries)->setter);
+       return true;
+}
+
+bool jobjects_run_dynoffsets_hook(classinfo *c)
+{
+       RegisteredDynMap::const_iterator it = dynEntryMap.find(c);
+       if (it == dynEntryMap.end())
+               return true;
+
+       if (!runAllSetters(c, it->second))
+               return false;
+
+       return true;
+}
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+off_t java_lang_Thread::offset_vmThread;
+off_t java_lang_Thread::offset_group;
+off_t java_lang_Thread::offset_name;
+off_t java_lang_Thread::offset_daemon;
+off_t java_lang_Thread::offset_priority;
+off_t java_lang_Thread::offset_exceptionHandler;
+
+static DynOffsetEntry dyn_entries_java_lang_Thread[] = {
+       { &java_lang_Thread::set_vmThread_offset,         "vmThread" },
+       { &java_lang_Thread::set_group_offset,            "group" },
+       { &java_lang_Thread::set_name_offset,             "name" },
+       { &java_lang_Thread::set_daemon_offset,           "daemon" },
+       { &java_lang_Thread::set_priority_offset,         "priority" },
+       { &java_lang_Thread::set_exceptionHandler_offset, "exceptionHandler" },
+       { 0, 0 }
+};
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+off_t java_lang_Thread::offset_priority;
+off_t java_lang_Thread::offset_daemon;
+off_t java_lang_Thread::offset_group;
+off_t java_lang_Thread::offset_uncaughtExceptionHandler;
+off_t java_lang_Thread::offset_threadStatus;
+off_t java_lang_Thread::offset_me;
+
+static DynOffsetEntry dyn_entries_java_lang_Thread[] = {
+       { &java_lang_Thread::set_priority_offset,                 "priority" },
+       { &java_lang_Thread::set_daemon_offset,                   "daemon" },
+       { &java_lang_Thread::set_group_offset,                    "group" },
+       { &java_lang_Thread::set_uncaughtExceptionHandler_offset, "uncaughtExceptionHandler" },
+       { &java_lang_Thread::set_threadStatus_offset,             "threadStatus" },
+       { &java_lang_Thread::set_me_offset,                       "me" },
+       { 0, 0 }
+};
+
+#endif
+
+void jobjects_register_dyn_offsets()
+{
+       register_dyn_entry_table(class_java_lang_Thread, dyn_entries_java_lang_Thread);
+}
+
 #endif // ENABLE_JAVASE
 
 
@@ -134,4 +286,5 @@ java_handle_t* java_lang_reflect_Method::invoke(java_handle_t* o, java_handle_ob
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */