⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 natmethod.cc

📁 gcc的组建
💻 CC
📖 第 1 页 / 共 2 页
字号:
// natMethod.cc - Native code for Method class./* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004, 2005 Free Software Foundation   This file is part of libgcj.This software is copyrighted work licensed under the terms of theLibgcj License.  Please consult the file "LIBGCJ_LICENSE" fordetails.  */#include <config.h>#include <gcj/cni.h>#include <jvm.h>#include <jni.h>#include <java-stack.h>#include <java/lang/reflect/Method.h>#include <java/lang/reflect/Constructor.h>#include <java/lang/reflect/InvocationTargetException.h>#include <java/lang/reflect/Modifier.h>#include <java/lang/Void.h>#include <java/lang/Byte.h>#include <java/lang/Boolean.h>#include <java/lang/Character.h>#include <java/lang/Short.h>#include <java/lang/Integer.h>#include <java/lang/Long.h>#include <java/lang/Float.h>#include <java/lang/Double.h>#include <java/lang/IllegalAccessException.h>#include <java/lang/IllegalArgumentException.h>#include <java/lang/IncompatibleClassChangeError.h>#include <java/lang/NullPointerException.h>#include <java/lang/ArrayIndexOutOfBoundsException.h>#include <java/lang/VirtualMachineError.h>#include <java/lang/Class.h>#include <gcj/method.h>#include <gnu/gcj/RawData.h>#include <java/lang/NoClassDefFoundError.h>#include <stdlib.h>#if USE_LIBFFI#include <ffi.h>#else#include <java/lang/UnsupportedOperationException.h>#endifstruct cpair{  jclass prim;  jclass wrap;};// This is used to determine when a primitive widening conversion is// allowed.static cpair primitives[] ={#define BOOLEAN 0  { JvPrimClass (boolean), &java::lang::Boolean::class$ },  { JvPrimClass (byte), &java::lang::Byte::class$ },#define SHORT 2  { JvPrimClass (short), &java::lang::Short::class$ },#define CHAR 3  { JvPrimClass (char), &java::lang::Character::class$ },  { JvPrimClass (int), &java::lang::Integer::class$ },  { JvPrimClass (long), &java::lang::Long::class$ },  { JvPrimClass (float), &java::lang::Float::class$ },  { JvPrimClass (double), &java::lang::Double::class$ },  { NULL, NULL }};static inline jbooleancan_widen (jclass from, jclass to){  int fromx = -1, tox = -1;  for (int i = 0; primitives[i].prim; ++i)    {      if (primitives[i].wrap == from)	fromx = i;      if (primitives[i].prim == to)	tox = i;    }  // Can't handle a miss.  if (fromx == -1 || tox == -1)    return false;  // Boolean arguments may not be widened.  if (fromx == BOOLEAN && tox != BOOLEAN)    return false;  // Nothing promotes to char.  if (tox == CHAR && fromx != CHAR)    return false;  return fromx <= tox;}#ifdef USE_LIBFFIstatic inline ffi_type *get_ffi_type (jclass klass){  // A special case.  if (klass == NULL)    return &ffi_type_pointer;  ffi_type *r;  if (klass == JvPrimClass (byte))    r = &ffi_type_sint8;  else if (klass == JvPrimClass (short))    r = &ffi_type_sint16;  else if (klass == JvPrimClass (int))    r = &ffi_type_sint32;  else if (klass == JvPrimClass (long))    r = &ffi_type_sint64;  else if (klass == JvPrimClass (float))    r = &ffi_type_float;  else if (klass == JvPrimClass (double))    r = &ffi_type_double;  else if (klass == JvPrimClass (boolean))    {      // On some platforms a bool is a byte, on others an int.      if (sizeof (jboolean) == sizeof (jbyte))	r = &ffi_type_sint8;      else	{	  JvAssert (sizeof (jboolean) == sizeof (jint));	  r = &ffi_type_sint32;	}    }  else if (klass == JvPrimClass (char))    r = &ffi_type_uint16;  else    {      JvAssert (! klass->isPrimitive());      r = &ffi_type_pointer;    }  return r;}#endif // USE_LIBFFIjobjectjava::lang::reflect::Method::invoke (jobject obj, jobjectArray args){  using namespace java::lang::reflect;  jclass iface = NULL;    if (parameter_types == NULL)    getType ();      jmethodID meth = _Jv_FromReflectedMethod (this);  if (Modifier::isStatic(meth->accflags))    {      // We have to initialize a static class.  It is safe to do this      // here and not in _Jv_CallAnyMethodA because JNI initializes a      // class whenever a method lookup is done.      _Jv_InitClass (declaringClass);    }  else    {      jclass objClass = JV_CLASS (obj);      if (! _Jv_IsAssignableFrom (objClass, declaringClass))        throw new java::lang::IllegalArgumentException;    }  // Check accessibility, if required.  if (! (Modifier::isPublic (meth->accflags) || this->isAccessible()))    {      Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);      if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))	throw new IllegalAccessException;    }  if (declaringClass->isInterface())    iface = declaringClass;    return _Jv_CallAnyMethodA (obj, return_type, meth, false,			     parameter_types, args, iface);}jintjava::lang::reflect::Method::getModifiers (){  // Ignore all unknown flags.  return _Jv_FromReflectedMethod (this)->accflags & Modifier::ALL_FLAGS;}jstringjava::lang::reflect::Method::getName (){  if (name == NULL)    name = _Jv_NewStringUtf8Const (_Jv_FromReflectedMethod (this)->name);  return name;}/* Internal method to set return_type and parameter_types fields. */voidjava::lang::reflect::Method::getType (){  _Jv_Method *method = _Jv_FromReflectedMethod (this);  _Jv_GetTypesFromSignature (method,			     declaringClass,			     &parameter_types,			     &return_type);  int count = 0;  if (method->throws != NULL)    {      while (method->throws[count] != NULL)	++count;    }  exception_types    = (JArray<jclass> *) JvNewObjectArray (count, &java::lang::Class::class$,					   NULL);  jclass *elts = elements (exception_types);  for (int i = 0; i < count; ++i)    elts[i] = _Jv_FindClass (method->throws[i],			     declaringClass->getClassLoaderInternal ());}void_Jv_GetTypesFromSignature (jmethodID method,			   jclass declaringClass,			   JArray<jclass> **arg_types_out,			   jclass *return_type_out){  _Jv_Utf8Const* sig = method->signature;  java::lang::ClassLoader *loader = declaringClass->getClassLoaderInternal();  char *ptr = sig->chars();  int numArgs = 0;  /* First just count the number of parameters. */  // FIXME: should do some validation here, e.g., that there is only  // one return type.  for (; ; ptr++)    {      switch (*ptr)	{	case 0:	case ')':	case 'V':	  break;	case '[':	case '(':	  continue;	case 'B':	case 'C':	case 'D':	case 'F':	case 'S':	case 'I':	case 'J':	case 'Z':	  numArgs++;	  continue;	case 'L':	  numArgs++;	  do 	    ptr++;	  while (*ptr != ';' && ptr[1] != '\0');	  continue;	}      break;    }  JArray<jclass> *args = (JArray<jclass> *)    JvNewObjectArray (numArgs, &java::lang::Class::class$, NULL);  jclass* argPtr = elements (args);  for (ptr = sig->chars(); *ptr != '\0'; ptr++)    {      if (*ptr == '(')	continue;      if (*ptr == ')')	{	  argPtr = return_type_out;	  continue;	}      char *end_ptr;      jclass type = _Jv_FindClassFromSignature (ptr, loader, &end_ptr);      if (type == NULL)	// FIXME: This isn't ideal.	throw new java::lang::NoClassDefFoundError (sig->toString());      // ARGPTR can be NULL if we are processing the return value of a      // call from Constructor.      if (argPtr)	*argPtr++ = type;      ptr = end_ptr;    }  *arg_types_out = args;}// This is a very rough analog of the JNI CallNonvirtual<type>MethodA// functions.  It handles both Methods and Constructors, and it can// handle any return type.  In the Constructor case, the `obj'// argument is unused and should be NULL; also, the `return_type' is// the class that the constructor will construct.  RESULT is a pointer// to a `jvalue' (see jni.h); for a void method this should be NULL.// This function returns an exception (if one was thrown), or NULL if// the call went ok.void_Jv_CallAnyMethodA (jobject obj,		    jclass return_type,		    jmethodID meth,		    jboolean is_constructor,		    jboolean is_virtual_call,		    JArray<jclass> *parameter_types,		    jvalue *args,		    jvalue *result,		    jboolean is_jni_call,		    jclass iface){  using namespace java::lang::reflect;  #ifdef USE_LIBFFI  JvAssert (! is_constructor || ! obj);  JvAssert (! is_constructor || return_type);  // See whether call needs an object as the first argument.  A  // constructor does need a `this' argument, but it is one we create.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -