LCOV - code coverage report
Current view: top level - vm - javaobjects.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 45 65 69.2 %
Date: 2017-07-14 10:03:36 Functions: 9 11 81.8 %

          Line data    Source code
       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             :  */
      51         141 : java_handle_t* java_lang_ClassLoader::invoke_getSystemClassLoader()
      52             : {
      53             :         methodinfo    *m;
      54             :         java_handle_t *clo;
      55             :         classloader_t *cl;
      56             : 
      57         141 :         assert(class_java_lang_Object);
      58         141 :         assert(class_java_lang_ClassLoader);
      59         141 :         assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
      60             : 
      61             :         m = class_resolveclassmethod(class_java_lang_ClassLoader,
      62             :                                                                  utf8::getSystemClassLoader,
      63             :                                                                  utf8::void__java_lang_ClassLoader,
      64             :                                                                  class_java_lang_Object,
      65         141 :                                                                  false);
      66             : 
      67         141 :         if (m == NULL)
      68           0 :                 return NULL;
      69             : 
      70         141 :         clo = vm_call_method(m, NULL);
      71             : 
      72         141 :         if (clo == NULL)
      73           0 :                 return NULL;
      74             : 
      75         141 :         cl = loader_hashtable_classloader_add(clo);
      76             : 
      77         141 :         return cl;
      78             : }
      79             : 
      80             : 
      81             : /**
      82             :  * Constructs a new instance of the class by calling the
      83             :  * appropriate Java initializer.
      84             :  */
      85           0 : 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           0 :         if (!(class_java_lang_management_MemoryUsage = load_class_bootstrap(Utf8String::from_utf8("java/lang/management/MemoryUsage"))))
      91           0 :                 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           0 :                                          Utf8String::from_utf8("(JJJJ)V"));
      98             : 
      99           0 :         if (m == NULL)
     100           0 :                 return;
     101             : 
     102             :         // Instantiate a new object.
     103           0 :         _handle = builtin_new(class_java_lang_management_MemoryUsage);
     104             : 
     105           0 :         if (is_null())
     106           0 :                 return;
     107             : 
     108             :         // Call initializer.
     109           0 :         (void) vm_call_method(m, _handle, init, used, commited, maximum);
     110           0 : }
     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             :  */
     121         468 : java_handle_t* java_lang_reflect_Constructor::new_instance(java_handle_objectarray_t* args)
     122             : {
     123         468 :         methodinfo* m = get_method();
     124             : 
     125             :         // Should we bypass security the checks (AccessibleObject)?
     126         468 :         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         468 :                 if (!access_check_method(m, 2))
     134           0 :                         return NULL;
     135             :         }
     136             : 
     137             :         // Create a Java object.
     138         468 :         java_handle_t* h = builtin_new(m->clazz);
     139             : 
     140         468 :         if (h == NULL)
     141           0 :                 return NULL;
     142             : 
     143             :         // Call initializer.
     144         468 :         (void) Reflection::invoke(m, h, args);
     145             : 
     146         468 :         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             :  */
     157         385 : java_handle_t* java_lang_reflect_Method::invoke(java_handle_t* o, java_handle_objectarray_t* args)
     158             : {
     159         385 :         methodinfo* m = get_method();
     160             : 
     161             :         // Should we bypass security the checks (AccessibleObject)?
     162         385 :         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         363 :                 if (!access_check_method(m, 2))
     171           0 :                         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         385 :         if (!(m->clazz->state & CLASS_INITIALIZED))
     186           9 :                 if (!initialize_class(m->clazz))
     187           0 :                         return NULL;
     188             : 
     189             :         // Call the Java method.
     190         385 :         java_handle_t* result = Reflection::invoke(m, o, args);
     191             : 
     192         385 :         return result;
     193             : }
     194             : 
     195             : struct DynOffsetEntry {
     196             :         void (*setter)(int32_t);
     197             :         const char *name;
     198             :         bool throwexception;
     199             : };
     200             : 
     201             : typedef std::map<classinfo *, DynOffsetEntry *> RegisteredDynMap;
     202         165 : static RegisteredDynMap dynEntryMap;
     203             : 
     204         163 : static void register_dyn_entry_table(classinfo *c, DynOffsetEntry *entries)
     205             : {
     206         163 :         dynEntryMap.insert(std::make_pair(c, entries));
     207         163 : }
     208             : 
     209         978 : static bool runAllSetters(classinfo *c, DynOffsetEntry entries[])
     210             : {
     211         978 :         do {
     212         978 :                 fieldinfo *fi = class_findfield_by_name(c, Utf8String::from_utf8(entries->name), false);
     213         978 :                 if (fi)
     214         978 :                         entries->setter(fi->offset);
     215             :                 else
     216           0 :                         if (entries->throwexception)
     217           0 :                                 return false;
     218             :         } while ((++entries)->setter);
     219         163 :         return true;
     220             : }
     221             : 
     222       42202 : bool jobjects_run_dynoffsets_hook(classinfo *c)
     223             : {
     224       42202 :         RegisteredDynMap::const_iterator it = dynEntryMap.find(c);
     225       42202 :         if (it == dynEntryMap.end())
     226       42039 :                 return true;
     227             : 
     228         163 :         if (!runAllSetters(c, it->second))
     229           0 :                 return false;
     230             : 
     231         163 :         return true;
     232             : }
     233             : 
     234             : #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
     235             : 
     236             : off_t java_lang_Thread::offset_vmThread;
     237             : off_t java_lang_Thread::offset_group;
     238             : off_t java_lang_Thread::offset_name;
     239             : off_t java_lang_Thread::offset_daemon;
     240             : off_t java_lang_Thread::offset_priority;
     241             : off_t java_lang_Thread::offset_exceptionHandler;
     242             : 
     243             : static DynOffsetEntry dyn_entries_java_lang_Thread[] = {
     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             : 
     255             : off_t java_lang_Thread::offset_priority;
     256             : off_t java_lang_Thread::offset_daemon;
     257             : off_t java_lang_Thread::offset_group;
     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             : 
     285         163 : void jobjects_register_dyn_offsets()
     286             : {
     287         163 :         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         658 : }
     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             :  */

Generated by: LCOV version 1.11