LCOV - code coverage report
Current view: top level - native/vm - reflection.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 42 54 77.8 %
Date: 2015-06-10 18:10:59 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* src/native/vm/reflection.cpp - helper functions for java/lang/reflect
       2             : 
       3             :    Copyright (C) 1996-2013
       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 "native/llni.hpp"
      29             : #include "native/native.hpp"
      30             : 
      31             : #if defined(ENABLE_ANNOTATIONS) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
      32             : # include "vm/vm.hpp"
      33             : #endif
      34             : 
      35             : #include "native/vm/reflection.hpp"
      36             : 
      37             : #include "vm/access.hpp"
      38             : #include "vm/array.hpp"
      39             : #include "vm/descriptor.hpp"
      40             : #include "vm/exceptions.hpp"
      41             : #include "vm/global.hpp"
      42             : #include "vm/globals.hpp"
      43             : #include "vm/initialize.hpp"
      44             : #include "vm/javaobjects.hpp"
      45             : #include "vm/method.hpp"
      46             : #include "vm/vm.hpp"
      47             : 
      48             : #include "vm/jit/builtin.hpp"
      49             : 
      50             : 
      51             : /**
      52             :  * Invoke a method on the given object with the given arguments.
      53             :  *
      54             :  * For instance methods OBJ must be != NULL and the method is looked up
      55             :  * in the vftbl of the object.
      56             :  *
      57             :  * For static methods, OBJ is ignored.
      58             :  */
      59         853 : java_handle_t* Reflection::invoke(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *params)
      60             : {
      61             :         methodinfo    *resm;
      62             :         java_handle_t *ro;
      63             :         int            argcount;
      64             :         int            paramcount;
      65             : 
      66             :         /* Sanity check. */
      67             : 
      68         853 :         assert(m != NULL);
      69             : 
      70         853 :         argcount = m->parseddesc->paramcount;
      71         853 :         paramcount = argcount;
      72             : 
      73             :         /* If method is non-static, remove the `this' pointer. */
      74             : 
      75         853 :         if (!(m->flags & ACC_STATIC))
      76         818 :                 paramcount--;
      77             : 
      78             :         /* For instance methods the object has to be an instance of the
      79             :            class the method belongs to. For static methods the obj
      80             :            parameter is ignored. */
      81             : 
      82         853 :         if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->clazz))) {
      83           0 :                 exceptions_throw_illegalargumentexception();
      84           0 :                 return NULL;
      85             :         }
      86             : 
      87             :         /* check if we got the right number of arguments */
      88             : 
      89         853 :         ObjectArray oa(params);
      90             : 
      91         853 :         if (((params == NULL) && (paramcount != 0)) ||
      92             :                 (params && (oa.get_length() != paramcount))) 
      93             :         {
      94           0 :                 exceptions_throw_illegalargumentexception();
      95           0 :                 return NULL;
      96             :         }
      97             : 
      98             :         /* for instance methods we need an object */
      99             : 
     100         853 :         if (!(m->flags & ACC_STATIC) && (o == NULL)) {
     101             :                 /* XXX not sure if that is the correct exception */
     102           0 :                 exceptions_throw_nullpointerexception();
     103           0 :                 return NULL;
     104             :         }
     105             : 
     106             :         /* for static methods, zero object to make subsequent code simpler */
     107         853 :         if (m->flags & ACC_STATIC)
     108          35 :                 o = NULL;
     109             : 
     110         853 :         if (o != NULL) {
     111             :                 /* for instance methods we must do a vftbl lookup */
     112         818 :                 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
     113             :         }
     114             :         else {
     115             :                 /* for static methods, just for convenience */
     116          35 :                 resm = m;
     117             :         }
     118             : 
     119         853 :         ro = vm_call_method_objectarray(resm, o, params);
     120             : 
     121         853 :         return ro;
     122             : }
     123             : 
     124             : 
     125             : #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) && defined(ENABLE_ANNOTATIONS)
     126             : /* reflect_get_declaredannotations *********************************************
     127             : 
     128             :    Calls the annotation parser with the unparsed annotations and returnes
     129             :    the parsed annotations as a map.
     130             :    
     131             :    IN:
     132             :        annotations........the unparsed annotations
     133             :        declaringClass.....the class in which the annotated element is declared
     134             :        referer............the calling class (for the 'referer' parameter of
     135             :                           vm_call_method())
     136             : 
     137             :    RETURN VALUE:
     138             :        The parsed annotations as a
     139             :            java.util.Map<Class<? extends Annotation>, Annotation>.
     140             : 
     141             : *******************************************************************************/
     142             : 
     143         441 : java_handle_t* Reflection::get_declaredannotations(java_handle_bytearray_t *annotations, classinfo* declaringClass, classinfo *referer)
     144             : {
     145             :         static methodinfo* m_parseAnnotations = NULL;
     146             : 
     147         441 :         java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
     148             :                 
     149         441 :         if (h == NULL)
     150           0 :                 return NULL;
     151             : 
     152         441 :         sun_reflect_ConstantPool cp(h);
     153         441 :         cp.set_constantPoolOop(declaringClass);
     154             :                 
     155             :         /* only resolve the parser method the first time */
     156         441 :         if (m_parseAnnotations == NULL) {
     157             :                 // FIXME Use globals.
     158           3 :                 Utf8String utf_parseAnnotations = Utf8String::from_utf8("parseAnnotations");
     159           3 :                 Utf8String utf_desc             = Utf8String::from_utf8("([BLsun/reflect/ConstantPool;Ljava/lang/Class;)Ljava/util/Map;");
     160             : 
     161           3 :                 if (utf_parseAnnotations == NULL || utf_desc == NULL)
     162           0 :                         return NULL;
     163             :                 
     164             :                 m_parseAnnotations = class_resolveclassmethod(
     165             :                         class_sun_reflect_annotation_AnnotationParser,
     166             :                         utf_parseAnnotations,
     167             :                         utf_desc,
     168             :                         referer,
     169           3 :                         true);
     170             :         
     171           3 :                 if (m_parseAnnotations == NULL)
     172           0 :                         return NULL;
     173             :         }
     174             :         
     175         441 :         return (java_handle_t*) vm_call_method(m_parseAnnotations, NULL, annotations, cp.get_handle(), declaringClass);
     176             : }
     177             : 
     178             : 
     179             : /* reflect_get_parameterannotations *******************************************
     180             : 
     181             :    Calls the annotation parser with the unparsed parameter annotations of
     182             :    a method and returnes the parsed parameter annotations in a 2 dimensional
     183             :    array.
     184             :    
     185             :    IN:
     186             :        parameterAnnotations....the unparsed parameter annotations
     187             :            slot....................the slot of the method
     188             :        declaringClass..........the class in which the annotated element is
     189             :                                    declared
     190             :        referer.................the calling class (for the 'referer' parameter
     191             :                                of vm_call_method())
     192             : 
     193             :    RETURN VALUE:
     194             :        The parsed parameter annotations in a 2 dimensional array.
     195             : 
     196             : *******************************************************************************/
     197             : 
     198          12 : java_handle_objectarray_t* Reflection::get_parameterannotations(java_handle_bytearray_t* parameterAnnotations, methodinfo* m, classinfo* referer)
     199             : {
     200             :         /* This method in java would be basically the following.
     201             :          * We don't do it in java because we don't want to make a
     202             :          * public method with wich you can get a ConstantPool, because
     203             :          * with that you could read any kind of constants (even private
     204             :          * ones).
     205             :          *
     206             :          * ConstantPool constPool = new ConstantPool();
     207             :          * constPool.constantPoolOop = method.getDeclaringClass();
     208             :          * return sun.reflect.AnnotationParser.parseParameterAnnotations(
     209             :          *        parameterAnnotations,
     210             :          *        constPool,
     211             :          *        method.getDeclaringClass(),
     212             :          *        method.getParameterTypes().length);
     213             :          */
     214             : 
     215             :         static methodinfo* m_parseParameterAnnotations = NULL;
     216             : 
     217             :         /* get parameter count */
     218             : 
     219          12 :         int32_t numParameters = method_get_parametercount(m);
     220             : 
     221             :         /* get ConstantPool */
     222             : 
     223          12 :         java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
     224             :         
     225          12 :         if (h == NULL)
     226           0 :                 return NULL;
     227             : 
     228          12 :         sun_reflect_ConstantPool cp(h);
     229          12 :         cp.set_constantPoolOop(m->clazz);
     230             : 
     231             :         /* only resolve the parser method the first time */
     232          12 :         if (m_parseParameterAnnotations == NULL) {
     233           1 :                 Utf8String utf_parseParameterAnnotations = Utf8String::from_utf8("parseParameterAnnotations");
     234           1 :                 Utf8String utf_desc                      = Utf8String::from_utf8("([BLsun/reflect/ConstantPool;Ljava/lang/Class;I)[[Ljava/lang/annotation/Annotation;");
     235             : 
     236           1 :                 if (utf_parseParameterAnnotations == NULL || utf_desc == NULL)
     237           0 :                         return NULL;
     238             : 
     239             :                 /* get parser method */
     240             : 
     241             :                 m_parseParameterAnnotations = class_resolveclassmethod(
     242             :                         class_sun_reflect_annotation_AnnotationParser,
     243             :                         utf_parseParameterAnnotations,
     244             :                         utf_desc,
     245             :                         referer,
     246           1 :                         true);
     247             : 
     248           1 :                 if (m_parseParameterAnnotations == NULL)
     249           0 :                         return NULL;
     250             :         }
     251             : 
     252          12 :         return (java_handle_objectarray_t*) vm_call_method(m_parseParameterAnnotations, NULL, parameterAnnotations, cp.get_handle(), m->clazz, numParameters);
     253             : }
     254             : #endif
     255             : 
     256             : 
     257             : /*
     258             :  * These are local overrides for various environment variables in Emacs.
     259             :  * Please do not remove this and leave it at the end of the file, where
     260             :  * Emacs will automagically detect them.
     261             :  * ---------------------------------------------------------------------
     262             :  * Local variables:
     263             :  * mode: c++
     264             :  * indent-tabs-mode: t
     265             :  * c-basic-offset: 4
     266             :  * tab-width: 4
     267             :  * End:
     268             :  * vim:noexpandtab:sw=4:ts=4:
     269             :  */

Generated by: LCOV version 1.11