mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-30 15:24:07 +08:00
[multiple changes]
2000-01-04 Tom Tromey <tromey@cygnus.com> * java/lang/reflect/natConstructor.cc (newInstance): Pass declaring class as return_type argument to _Jv_CallNonvirtualMethodA. * java/lang/reflect/natMethod.cc (_Jv_CallNonvirtualMethodA): In constructor case, create object and use it as `this' argument. * java/lang/Class.h (_getConstructors): Declare. (_getFields): Declare. * java/lang/Class.java (getConstructors): Wrote. (_getConstructors): New native method. (getDeclaredConstructors): Wrote. (_getFields): Declare new native method. * java/lang/natClass.cc (_Jv_LookupInterfaceMethod): Removed incorrect comment. (getMethod): Work correctly when class is primitive. (getDeclaredMethods): Likewise. Compute offset using `method', not `mptr'. (getDeclaredMethod): Likewise. (getConstructor): Wrote. (ConstructorClass): New define. (getDeclaredConstructor): Wrote. (_getConstructors): New method. (_getFields): New method. (getFields): Wrote. * Makefile.in: Rebuilt. * Makefile.am (AM_CXXFLAGS): Added -D_GNU_SOURCE. * prims.cc: Remove `#pragma implementation'. * gcj/array.h: Remove `#pragma interface'. * prims.cc (_Jv_equaln): New function. * java/lang/Class.java (getSignature): Declare. * resolve.cc (_Jv_LookupDeclaredMethod): Moved to natClass.cc. * java/lang/natClass.cc (_Jv_LookupDeclaredMethod): Moved from resolve.cc. (getSignature): New method. (getDeclaredMethod): Wrote. (getMethod): Wrote. Include StringBuffer.h. * java/lang/Class.h (Class): Added _Jv_FromReflectedConstructor as a friend. Unconditionally declare _Jv_LookupDeclaredMethod as a friend. (getSignature): Declare. * include/jvm.h (_Jv_GetTypesFromSignature): Declare. (_Jv_equaln): Declare. (_Jv_CallNonvirtualMethodA): Declare. * Makefile.in: Rebuilt. * Makefile.am (nat_source_files): Added natConstructor.cc. (java/lang/reflect/Constructor.h): New target. * java/lang/reflect/natConstructor.cc: New file. * java/lang/reflect/Constructor.java (newInstance): Now native. (declaringClass): Renamed from decl_class. (offset): Renamed from index. (getType): New native method. (getModifiers): Now native. (getParameterTypes): Call getType if required. (hashCode): Include hash code from declaring class. (modifiers): Removed. (toString): Call getType if required. * gcj/method.h (_Jv_FromReflectedConstructor): New function. * java/lang/reflect/natMethod.cc (hack_call): New method. Removed `#if 0' around FFI code. Include <gnu/gcj/RawData.h>. (invoke): Use _Jv_CallNonvirtualMethodA. Throw IllegalArgumentException when argument object and class disagree. (_Jv_GetTypesFromSignature): New function. (getType): Use it. (ObjectClass): New define. (_Jv_CallNonvirtualMethodA): New function. * java/lang/reflect/Method.java (hack_trampoline): New method. (hack_call): New native method. 1999-12-21 Per Bothner <per@bothner.com> * java/lang/natClass.cc (getDeclaredMethods): Correctly compute offset in new Method. From-SVN: r31199
This commit is contained in:
parent
00da7781ff
commit
0f918fea8b
@ -1,3 +1,82 @@
|
||||
2000-01-04 Tom Tromey <tromey@cygnus.com>
|
||||
|
||||
* java/lang/reflect/natConstructor.cc (newInstance): Pass
|
||||
declaring class as return_type argument to
|
||||
_Jv_CallNonvirtualMethodA.
|
||||
* java/lang/reflect/natMethod.cc (_Jv_CallNonvirtualMethodA): In
|
||||
constructor case, create object and use it as `this' argument.
|
||||
* java/lang/Class.h (_getConstructors): Declare.
|
||||
(_getFields): Declare.
|
||||
* java/lang/Class.java (getConstructors): Wrote.
|
||||
(_getConstructors): New native method.
|
||||
(getDeclaredConstructors): Wrote.
|
||||
(_getFields): Declare new native method.
|
||||
* java/lang/natClass.cc (_Jv_LookupInterfaceMethod): Removed
|
||||
incorrect comment.
|
||||
(getMethod): Work correctly when class is primitive.
|
||||
(getDeclaredMethods): Likewise. Compute offset using `method',
|
||||
not `mptr'.
|
||||
(getDeclaredMethod): Likewise.
|
||||
(getConstructor): Wrote.
|
||||
(ConstructorClass): New define.
|
||||
(getDeclaredConstructor): Wrote.
|
||||
(_getConstructors): New method.
|
||||
(_getFields): New method.
|
||||
(getFields): Wrote.
|
||||
|
||||
* Makefile.in: Rebuilt.
|
||||
* Makefile.am (AM_CXXFLAGS): Added -D_GNU_SOURCE.
|
||||
|
||||
* prims.cc: Remove `#pragma implementation'.
|
||||
* gcj/array.h: Remove `#pragma interface'.
|
||||
|
||||
* prims.cc (_Jv_equaln): New function.
|
||||
* java/lang/Class.java (getSignature): Declare.
|
||||
* resolve.cc (_Jv_LookupDeclaredMethod): Moved to natClass.cc.
|
||||
* java/lang/natClass.cc (_Jv_LookupDeclaredMethod): Moved from
|
||||
resolve.cc.
|
||||
(getSignature): New method.
|
||||
(getDeclaredMethod): Wrote.
|
||||
(getMethod): Wrote.
|
||||
Include StringBuffer.h.
|
||||
* java/lang/Class.h (Class): Added _Jv_FromReflectedConstructor
|
||||
as a friend. Unconditionally declare _Jv_LookupDeclaredMethod as
|
||||
a friend.
|
||||
(getSignature): Declare.
|
||||
* include/jvm.h (_Jv_GetTypesFromSignature): Declare.
|
||||
(_Jv_equaln): Declare.
|
||||
(_Jv_CallNonvirtualMethodA): Declare.
|
||||
* Makefile.in: Rebuilt.
|
||||
* Makefile.am (nat_source_files): Added natConstructor.cc.
|
||||
(java/lang/reflect/Constructor.h): New target.
|
||||
* java/lang/reflect/natConstructor.cc: New file.
|
||||
* java/lang/reflect/Constructor.java (newInstance): Now native.
|
||||
(declaringClass): Renamed from decl_class.
|
||||
(offset): Renamed from index.
|
||||
(getType): New native method.
|
||||
(getModifiers): Now native.
|
||||
(getParameterTypes): Call getType if required.
|
||||
(hashCode): Include hash code from declaring class.
|
||||
(modifiers): Removed.
|
||||
(toString): Call getType if required.
|
||||
* gcj/method.h (_Jv_FromReflectedConstructor): New function.
|
||||
* java/lang/reflect/natMethod.cc (hack_call): New method.
|
||||
Removed `#if 0' around FFI code.
|
||||
Include <gnu/gcj/RawData.h>.
|
||||
(invoke): Use _Jv_CallNonvirtualMethodA. Throw
|
||||
IllegalArgumentException when argument object and class disagree.
|
||||
(_Jv_GetTypesFromSignature): New function.
|
||||
(getType): Use it.
|
||||
(ObjectClass): New define.
|
||||
(_Jv_CallNonvirtualMethodA): New function.
|
||||
* java/lang/reflect/Method.java (hack_trampoline): New method.
|
||||
(hack_call): New native method.
|
||||
|
||||
1999-12-21 Per Bothner <per@bothner.com>
|
||||
|
||||
* java/lang/natClass.cc (getDeclaredMethods): Correctly compute
|
||||
offset in new Method.
|
||||
|
||||
1999-12-22 Bryce McKinlay <bryce@albatross.co.nz>
|
||||
|
||||
* java/lang/natObject.cc (notify): Throw message with
|
||||
|
@ -74,8 +74,10 @@ JAVAC = $(GCJ) -C
|
||||
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
||||
|
||||
WARNINGS = -W -Wall
|
||||
## We need _GNU_SOURCE defined for some Linux builds. It doesn't hurt
|
||||
## to always define it.
|
||||
AM_CXXFLAGS = -fno-rtti -fvtable-thunks @LIBGCJ_CXXFLAGS@ @EXCEPTIONSPEC@ \
|
||||
$(WARNINGS)
|
||||
$(WARNINGS) -D_GNU_SOURCE
|
||||
if USING_GCC
|
||||
AM_CFLAGS = @LIBGCJ_CFLAGS@ $(WARNINGS)
|
||||
else
|
||||
@ -229,6 +231,12 @@ java/lang/String.h: java/lang/String.class libgcj.zip
|
||||
-friend 'jstring _Jv_AllocString (jsize);' \
|
||||
$(basename $<)
|
||||
|
||||
java/lang/reflect/Constructor.h: java/lang/reflect/Constructor.class libgcj.zip
|
||||
$(GCJH) -classpath $(top_builddir) \
|
||||
-friend 'jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);' \
|
||||
-friend 'java::lang::Class;' \
|
||||
$(basename $<)
|
||||
|
||||
java/lang/reflect/Field.h: java/lang/reflect/Field.class libgcj.zip
|
||||
$(GCJH) -classpath $(top_builddir) \
|
||||
-friend 'jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);' \
|
||||
@ -797,6 +805,7 @@ java/lang/natString.cc \
|
||||
java/lang/natSystem.cc \
|
||||
java/lang/natThread.cc \
|
||||
java/lang/reflect/natArray.cc \
|
||||
java/lang/reflect/natConstructor.cc \
|
||||
java/lang/reflect/natField.cc \
|
||||
java/lang/reflect/natMethod.cc \
|
||||
java/net/natInetAddress.cc \
|
||||
|
@ -158,7 +158,7 @@ EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
||||
|
||||
WARNINGS = -W -Wall
|
||||
AM_CXXFLAGS = -fno-rtti -fvtable-thunks @LIBGCJ_CXXFLAGS@ @EXCEPTIONSPEC@ \
|
||||
$(WARNINGS)
|
||||
$(WARNINGS) -D_GNU_SOURCE
|
||||
|
||||
@USING_GCC_TRUE@AM_CFLAGS = \
|
||||
@USING_GCC_TRUE@@LIBGCJ_CFLAGS@ $(WARNINGS)
|
||||
@ -619,6 +619,7 @@ java/lang/natString.cc \
|
||||
java/lang/natSystem.cc \
|
||||
java/lang/natThread.cc \
|
||||
java/lang/reflect/natArray.cc \
|
||||
java/lang/reflect/natConstructor.cc \
|
||||
java/lang/reflect/natField.cc \
|
||||
java/lang/reflect/natMethod.cc \
|
||||
java/net/natInetAddress.cc \
|
||||
@ -726,7 +727,7 @@ THANKS acinclude.m4 aclocal.m4 configure configure.in libgcj.spec.in
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = gtar
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
DIST_SUBDIRS = testsuite gcj include gcj include
|
||||
DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||
@ -1267,7 +1268,7 @@ distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
if test -d $$d/$$file; then \
|
||||
cp -pr $$d/$$file $(distdir)/$$file; \
|
||||
cp -pr $$/$$file $(distdir)/$$file; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
@ -1513,6 +1514,12 @@ java/lang/String.h: java/lang/String.class libgcj.zip
|
||||
-friend 'jstring _Jv_AllocString (jsize);' \
|
||||
$(basename $<)
|
||||
|
||||
java/lang/reflect/Constructor.h: java/lang/reflect/Constructor.class libgcj.zip
|
||||
$(GCJH) -classpath $(top_builddir) \
|
||||
-friend 'jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);' \
|
||||
-friend 'java::lang::Class;' \
|
||||
$(basename $<)
|
||||
|
||||
java/lang/reflect/Field.h: java/lang/reflect/Field.class libgcj.zip
|
||||
$(GCJH) -classpath $(top_builddir) \
|
||||
-friend 'jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);' \
|
||||
|
@ -76,12 +76,14 @@ DLLTOOL = @DLLTOOL@
|
||||
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
||||
EXCEPTIONSPEC = @EXCEPTIONSPEC@
|
||||
EXEEXT = @EXEEXT@
|
||||
FORCELIBGCCSPEC = @FORCELIBGCCSPEC@
|
||||
GCDEPS = @GCDEPS@
|
||||
GCINCS = @GCINCS@
|
||||
GCLIBS = @GCLIBS@
|
||||
GCOBJS = @GCOBJS@
|
||||
GCSPEC = @GCSPEC@
|
||||
LD = @LD@
|
||||
LIBDATASTARTSPEC = @LIBDATASTARTSPEC@
|
||||
LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@
|
||||
LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@
|
||||
LIBGCJ_JAVAFLAGS = @LIBGCJ_JAVAFLAGS@
|
||||
@ -90,7 +92,6 @@ LN_S = @LN_S@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NM = @NM@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
PACKAGE = @PACKAGE@
|
||||
PERL = @PERL@
|
||||
RANLIB = @RANLIB@
|
||||
@ -100,6 +101,7 @@ THREADINCS = @THREADINCS@
|
||||
THREADLIBS = @THREADLIBS@
|
||||
THREADOBJS = @THREADOBJS@
|
||||
THREADSPEC = @THREADSPEC@
|
||||
USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
|
||||
VERSION = @VERSION@
|
||||
ZDEPS = @ZDEPS@
|
||||
ZINCS = @ZINCS@
|
||||
|
@ -11,8 +11,6 @@ details. */
|
||||
#ifndef __GCJ_ARRAY_H__
|
||||
#define __GCJ_ARRAY_H__
|
||||
|
||||
#pragma interface
|
||||
|
||||
#include <java/lang/Object.h>
|
||||
|
||||
extern "Java" {
|
||||
|
@ -18,4 +18,11 @@ _Jv_FromReflectedMethod(java::lang::reflect::Method *method)
|
||||
((char *) method->declaringClass->methods + method->offset);
|
||||
}
|
||||
|
||||
extern inline jmethodID
|
||||
_Jv_FromReflectedConstructor (java::lang::reflect::Constructor *constructor)
|
||||
{
|
||||
return (jmethodID)
|
||||
((char *) constructor->declaringClass->methods + constructor->offset);
|
||||
}
|
||||
|
||||
#endif /* __GCJ_METHOD_H__ */
|
||||
|
@ -76,12 +76,14 @@ DLLTOOL = @DLLTOOL@
|
||||
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
||||
EXCEPTIONSPEC = @EXCEPTIONSPEC@
|
||||
EXEEXT = @EXEEXT@
|
||||
FORCELIBGCCSPEC = @FORCELIBGCCSPEC@
|
||||
GCDEPS = @GCDEPS@
|
||||
GCINCS = @GCINCS@
|
||||
GCLIBS = @GCLIBS@
|
||||
GCOBJS = @GCOBJS@
|
||||
GCSPEC = @GCSPEC@
|
||||
LD = @LD@
|
||||
LIBDATASTARTSPEC = @LIBDATASTARTSPEC@
|
||||
LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@
|
||||
LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@
|
||||
LIBGCJ_JAVAFLAGS = @LIBGCJ_JAVAFLAGS@
|
||||
@ -90,7 +92,6 @@ LN_S = @LN_S@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NM = @NM@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
PACKAGE = @PACKAGE@
|
||||
PERL = @PERL@
|
||||
RANLIB = @RANLIB@
|
||||
@ -100,6 +101,7 @@ THREADINCS = @THREADINCS@
|
||||
THREADLIBS = @THREADLIBS@
|
||||
THREADOBJS = @THREADOBJS@
|
||||
THREADSPEC = @THREADSPEC@
|
||||
USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
|
||||
VERSION = @VERSION@
|
||||
ZDEPS = @ZDEPS@
|
||||
ZINCS = @ZINCS@
|
||||
|
@ -53,6 +53,7 @@ _Jv_Utf8Const *_Jv_makeUtf8Const (char *s, int len);
|
||||
_Jv_Utf8Const *_Jv_makeUtf8Const (jstring string);
|
||||
extern jboolean _Jv_equalUtf8Consts (_Jv_Utf8Const *, _Jv_Utf8Const *);
|
||||
extern jboolean _Jv_equal (_Jv_Utf8Const *, jstring, jint);
|
||||
extern jboolean _Jv_equaln (_Jv_Utf8Const *, jstring, jint);
|
||||
|
||||
#define StringClass _CL_Q34java4lang6String
|
||||
extern java::lang::Class StringClass;
|
||||
@ -161,6 +162,13 @@ extern jclass _Jv_FindClass (_Jv_Utf8Const *name,
|
||||
java::lang::ClassLoader *loader);
|
||||
extern jclass _Jv_FindClassFromSignature (char *,
|
||||
java::lang::ClassLoader *loader);
|
||||
extern void _Jv_GetTypesFromSignature (jmethodID method,
|
||||
jclass declaringClass,
|
||||
JArray<jclass> **arg_types_out,
|
||||
jclass *return_type_out);
|
||||
extern jobject _Jv_CallNonvirtualMethodA (jobject, jclass,
|
||||
jmethodID, jboolean,
|
||||
JArray<jclass> *, jobjectArray);
|
||||
|
||||
extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
|
||||
__attribute__((__malloc__));
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Class.h - Header file for java.lang.Class. -*- c++ -*-
|
||||
|
||||
/* Copyright (C) 1998, 1999 Cygnus Solutions
|
||||
/* Copyright (C) 1998, 1999, 2000 Cygnus Solutions
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
@ -94,12 +94,16 @@ public:
|
||||
|
||||
java::lang::reflect::Field *getField (jstring);
|
||||
private:
|
||||
jint _getFields (JArray<java::lang::reflect::Field *> *result, jint offset);
|
||||
JArray<java::lang::reflect::Constructor *> *_getConstructors (jboolean);
|
||||
java::lang::reflect::Field *getField (jstring, jint);
|
||||
public:
|
||||
JArray<java::lang::reflect::Field *> *getFields (void);
|
||||
|
||||
JArray<jclass> *getInterfaces (void);
|
||||
|
||||
void getSignature (java::lang::StringBuffer *buffer);
|
||||
static jstring getSignature (JArray<jclass> *);
|
||||
java::lang::reflect::Method *getMethod (jstring, JArray<jclass> *);
|
||||
JArray<java::lang::reflect::Method *> *getMethods (void);
|
||||
|
||||
@ -156,6 +160,8 @@ private:
|
||||
// Friend functions implemented in natClass.cc.
|
||||
friend _Jv_Method *_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
|
||||
_Jv_Utf8Const *signature);
|
||||
friend _Jv_Method* _Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
|
||||
_Jv_Utf8Const*);
|
||||
friend void _Jv_InitClass (jclass klass);
|
||||
|
||||
friend jfieldID JvGetFirstInstanceField (jclass);
|
||||
@ -166,6 +172,7 @@ private:
|
||||
friend jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv *, jclass, jfieldID);
|
||||
friend jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);
|
||||
friend jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
|
||||
friend jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);
|
||||
|
||||
friend class _Jv_PrimClass;
|
||||
|
||||
@ -190,8 +197,6 @@ private:
|
||||
#ifdef INTERPRETER
|
||||
friend jboolean _Jv_IsInterpretedClass (jclass);
|
||||
friend void _Jv_InitField (jobject, jclass, _Jv_Field*);
|
||||
friend _Jv_Method* _Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
|
||||
_Jv_Utf8Const*);
|
||||
friend int _Jv_DetermineVTableIndex (jclass, _Jv_Utf8Const *,
|
||||
_Jv_Utf8Const*);
|
||||
friend void _Jv_InitField (jobject, jclass, int);
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Class.java - Representation of a Java class.
|
||||
|
||||
/* Copyright (C) 1998, 1999 Cygnus Solutions
|
||||
/* Copyright (C) 1998, 1999, 2000 Cygnus Solutions
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
@ -36,14 +36,27 @@ public final class Class implements Serializable
|
||||
|
||||
public native Constructor getConstructor (Class[] parameterTypes)
|
||||
throws NoSuchMethodException, SecurityException;
|
||||
public native Constructor[] getConstructors () throws SecurityException;
|
||||
|
||||
public native Class[] getDeclaredClasses () throws SecurityException;
|
||||
// This is used to implement getConstructors and
|
||||
// getDeclaredConstructors.
|
||||
private native Constructor[] _getConstructors (boolean declared)
|
||||
throws SecurityException;
|
||||
|
||||
public Constructor[] getConstructors () throws SecurityException
|
||||
{
|
||||
return _getConstructors (false);
|
||||
}
|
||||
|
||||
public native Constructor getDeclaredConstructor (Class[] parameterTypes)
|
||||
throws NoSuchMethodException, SecurityException;
|
||||
public native Constructor[] getDeclaredConstructors ()
|
||||
throws SecurityException;
|
||||
|
||||
public native Class[] getDeclaredClasses () throws SecurityException;
|
||||
|
||||
public Constructor[] getDeclaredConstructors () throws SecurityException
|
||||
{
|
||||
return _getConstructors (true);
|
||||
}
|
||||
|
||||
public native Field getDeclaredField (String fieldName)
|
||||
throws NoSuchFieldException, SecurityException;
|
||||
public native Field[] getDeclaredFields () throws SecurityException;
|
||||
@ -69,10 +82,15 @@ public final class Class implements Serializable
|
||||
throw new NoSuchFieldException(fieldName);
|
||||
return fld;
|
||||
}
|
||||
|
||||
private native Field[] _getFields (Field[] result, int offset);
|
||||
public native Field[] getFields () throws SecurityException;
|
||||
|
||||
public native Class[] getInterfaces ();
|
||||
|
||||
private final native void getSignature (StringBuffer buffer);
|
||||
private static final native String getSignature (Class[] parameterTypes);
|
||||
|
||||
public native Method getMethod (String methodName, Class[] parameterTypes)
|
||||
throws NoSuchMethodException, SecurityException;
|
||||
public native Method[] getMethods () throws SecurityException;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// natClass.cc - Implementation of java.lang.Class native methods.
|
||||
|
||||
/* Copyright (C) 1998, 1999 Cygnus Solutions
|
||||
/* Copyright (C) 1998, 1999, 2000 Cygnus Solutions
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
@ -38,6 +38,7 @@ details. */
|
||||
#include <java/lang/NullPointerException.h>
|
||||
#include <java/lang/System.h>
|
||||
#include <java/lang/SecurityManager.h>
|
||||
#include <java/lang/StringBuffer.h>
|
||||
|
||||
#include <java-cpool.h>
|
||||
|
||||
@ -55,6 +56,8 @@ extern java::lang::Class ClassClass;
|
||||
extern java::lang::Class MethodClass;
|
||||
#define FieldClass _CL_Q44java4lang7reflect5Field
|
||||
extern java::lang::Class FieldClass;
|
||||
#define ConstructorClass _CL_Q44java4lang7reflect11Constructor
|
||||
extern java::lang::Class ConstructorClass;
|
||||
|
||||
// Some constants we use to look up the class initializer.
|
||||
static _Jv_Utf8Const *void_signature = _Jv_makeUtf8Const ("()V", 3);
|
||||
@ -96,27 +99,95 @@ java::lang::Class::forName (jstring className)
|
||||
}
|
||||
|
||||
java::lang::reflect::Constructor *
|
||||
java::lang::Class::getConstructor (JArray<jclass> *)
|
||||
java::lang::Class::getConstructor (JArray<jclass> *param_types)
|
||||
{
|
||||
JvFail ("java::lang::Class::getConstructor not implemented");
|
||||
jstring partial_sig = getSignature (param_types);
|
||||
jint hash = partial_sig->hashCode ();
|
||||
|
||||
int i = isPrimitive () ? 0 : method_count;
|
||||
while (--i >= 0)
|
||||
{
|
||||
// FIXME: access checks.
|
||||
if (_Jv_equalUtf8Consts (methods[i].name, init_name)
|
||||
&& _Jv_equal (methods[i].signature, partial_sig, hash))
|
||||
{
|
||||
// Found it. For getConstructor, the constructor must be
|
||||
// public.
|
||||
using namespace java::lang::reflect;
|
||||
if (Modifier::isPublic(methods[i].accflags))
|
||||
break;
|
||||
Constructor *cons = new Constructor ();
|
||||
cons->offset = (char *) (&methods[i]) - (char *) methods;
|
||||
cons->declaringClass = this;
|
||||
return cons;
|
||||
}
|
||||
}
|
||||
JvThrow (new java::lang::NoSuchMethodException);
|
||||
}
|
||||
|
||||
JArray<java::lang::reflect::Constructor *> *
|
||||
java::lang::Class::getConstructors (void)
|
||||
java::lang::Class::_getConstructors (jboolean declared)
|
||||
{
|
||||
JvFail ("java::lang::Class::getConstructors not implemented");
|
||||
// FIXME: this method needs access checks.
|
||||
|
||||
int numConstructors = 0;
|
||||
int max = isPrimitive () ? 0 : method_count;
|
||||
int i;
|
||||
for (i = max; --i >= 0; )
|
||||
{
|
||||
_Jv_Method *method = &methods[i];
|
||||
if (method->name == NULL
|
||||
&& ! _Jv_equalUtf8Consts (method->name, init_name))
|
||||
continue;
|
||||
if (declared
|
||||
&& ! java::lang::reflect::Modifier::isPublic(method->accflags))
|
||||
continue;
|
||||
numConstructors++;
|
||||
}
|
||||
JArray<java::lang::reflect::Constructor *> *result
|
||||
= (JArray<java::lang::reflect::Constructor *> *)
|
||||
JvNewObjectArray (numConstructors, &ConstructorClass, NULL);
|
||||
java::lang::reflect::Constructor** cptr = elements (result);
|
||||
for (i = 0; i < max; i++)
|
||||
{
|
||||
_Jv_Method *method = &methods[i];
|
||||
if (method->name == NULL
|
||||
&& ! _Jv_equalUtf8Consts (method->name, init_name))
|
||||
continue;
|
||||
if (declared
|
||||
&& ! java::lang::reflect::Modifier::isPublic(method->accflags))
|
||||
continue;
|
||||
java::lang::reflect::Constructor *cons
|
||||
= new java::lang::reflect::Constructor ();
|
||||
cons->offset = (char *) method - (char *) methods;
|
||||
cons->declaringClass = this;
|
||||
*cptr++ = cons;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
java::lang::reflect::Constructor *
|
||||
java::lang::Class::getDeclaredConstructor (JArray<jclass> *)
|
||||
java::lang::Class::getDeclaredConstructor (JArray<jclass> *param_types)
|
||||
{
|
||||
JvFail ("java::lang::Class::getDeclaredConstructor not implemented");
|
||||
}
|
||||
jstring partial_sig = getSignature (param_types);
|
||||
jint hash = partial_sig->hashCode ();
|
||||
|
||||
JArray<java::lang::reflect::Constructor *> *
|
||||
java::lang::Class::getDeclaredConstructors (void)
|
||||
{
|
||||
JvFail ("java::lang::Class::getDeclaredConstructors not implemented");
|
||||
int i = isPrimitive () ? 0 : method_count;
|
||||
while (--i >= 0)
|
||||
{
|
||||
// FIXME: access checks.
|
||||
if (_Jv_equalUtf8Consts (methods[i].name, init_name)
|
||||
&& _Jv_equal (methods[i].signature, partial_sig, hash))
|
||||
{
|
||||
// Found it.
|
||||
using namespace java::lang::reflect;
|
||||
Constructor *cons = new Constructor ();
|
||||
cons->offset = (char *) (&methods[i]) - (char *) methods;
|
||||
cons->declaringClass = this;
|
||||
return cons;
|
||||
}
|
||||
}
|
||||
JvThrow (new java::lang::NoSuchMethodException);
|
||||
}
|
||||
|
||||
java::lang::reflect::Field *
|
||||
@ -187,18 +258,67 @@ java::lang::Class::getDeclaredFields (void)
|
||||
return result;
|
||||
}
|
||||
|
||||
java::lang::reflect::Method *
|
||||
java::lang::Class::getDeclaredMethod (jstring, JArray<jclass> *)
|
||||
void
|
||||
java::lang::Class::getSignature (java::lang::StringBuffer *buffer)
|
||||
{
|
||||
JvFail ("java::lang::Class::getDeclaredMethod not implemented");
|
||||
if (isPrimitive())
|
||||
buffer->append((jchar) method_count);
|
||||
else
|
||||
{
|
||||
jstring name = getName();
|
||||
if (name->charAt(0) != '[')
|
||||
buffer->append((jchar) 'L');
|
||||
buffer->append(name);
|
||||
if (name->charAt(0) != '[')
|
||||
buffer->append((jchar) ';');
|
||||
}
|
||||
}
|
||||
|
||||
// This doesn't have to be native. It is an implementation detail
|
||||
// only called from the C++ code, though, so maybe this is clearer.
|
||||
jstring
|
||||
java::lang::Class::getSignature (JArray<jclass> *param_types)
|
||||
{
|
||||
java::lang::StringBuffer *buf = new java::lang::StringBuffer ();
|
||||
buf->append((jchar) '(');
|
||||
jclass *v = elements (param_types);
|
||||
for (int i = 0; i < param_types->length; ++i)
|
||||
v[i]->getSignature(buf);
|
||||
buf->append((jchar) ')');
|
||||
return buf->toString();
|
||||
}
|
||||
|
||||
java::lang::reflect::Method *
|
||||
java::lang::Class::getDeclaredMethod (jstring name,
|
||||
JArray<jclass> *param_types)
|
||||
{
|
||||
jstring partial_sig = getSignature (param_types);
|
||||
jint p_len = partial_sig->length();
|
||||
_Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
|
||||
int i = isPrimitive () ? 0 : method_count;
|
||||
while (--i >= 0)
|
||||
{
|
||||
// FIXME: access checks.
|
||||
if (_Jv_equalUtf8Consts (methods[i].name, utf_name)
|
||||
&& _Jv_equaln (methods[i].signature, partial_sig, p_len))
|
||||
{
|
||||
// Found it.
|
||||
using namespace java::lang::reflect;
|
||||
Method *rmethod = new Method ();
|
||||
rmethod->offset = (char*) (&methods[i]) - (char*) methods;
|
||||
rmethod->declaringClass = this;
|
||||
}
|
||||
}
|
||||
JvThrow (new java::lang::NoSuchMethodException);
|
||||
}
|
||||
|
||||
JArray<java::lang::reflect::Method *> *
|
||||
java::lang::Class::getDeclaredMethods (void)
|
||||
{
|
||||
int numMethods = 0;
|
||||
int max = isPrimitive () ? 0 : method_count;
|
||||
int i;
|
||||
for (i = method_count; --i >= 0; )
|
||||
for (i = max; --i >= 0; )
|
||||
{
|
||||
_Jv_Method *method = &methods[i];
|
||||
if (method->name == NULL
|
||||
@ -211,15 +331,16 @@ java::lang::Class::getDeclaredMethods (void)
|
||||
= (JArray<java::lang::reflect::Method *> *)
|
||||
JvNewObjectArray (numMethods, &MethodClass, NULL);
|
||||
java::lang::reflect::Method** mptr = elements (result);
|
||||
for (i = 0; i < method_count; i++)
|
||||
for (i = 0; i < max; i++)
|
||||
{
|
||||
_Jv_Method *method = &methods[i];
|
||||
if (method->name == NULL
|
||||
|| _Jv_equalUtf8Consts (method->name, clinit_name)
|
||||
|| _Jv_equalUtf8Consts (method->name, init_name))
|
||||
continue;
|
||||
java::lang::reflect::Method* rmethod = new java::lang::reflect::Method ();
|
||||
rmethod->offset = (char*) mptr - (char*) elements (result);
|
||||
java::lang::reflect::Method* rmethod
|
||||
= new java::lang::reflect::Method ();
|
||||
rmethod->offset = (char*) method - (char*) methods;
|
||||
rmethod->declaringClass = this;
|
||||
*mptr++ = rmethod;
|
||||
}
|
||||
@ -258,10 +379,58 @@ java::lang::Class::getDeclaringClass (void)
|
||||
return NULL; // Placate compiler.
|
||||
}
|
||||
|
||||
jint
|
||||
java::lang::Class::_getFields (JArray<java::lang::reflect::Field *> *result,
|
||||
jint offset)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < field_count; i++)
|
||||
{
|
||||
_Jv_Field *field = &fields[i];
|
||||
if (! (field->getModifiers() & java::lang::reflect::Modifier::PUBLIC))
|
||||
continue;
|
||||
++count;
|
||||
|
||||
if (result != NULL)
|
||||
{
|
||||
java::lang::reflect::Field *rfield
|
||||
= new java::lang::reflect::Field ();
|
||||
rfield->offset = (char *) field - (char *) fields;
|
||||
rfield->declaringClass = this;
|
||||
rfield->name = _Jv_NewStringUtf8Const (field->name);
|
||||
(elements (result))[offset + i] = rfield;
|
||||
}
|
||||
}
|
||||
jclass superclass = getSuperclass();
|
||||
if (superclass != NULL)
|
||||
{
|
||||
int s_count = superclass->_getFields (result, offset);
|
||||
count += s_count;
|
||||
offset += s_count;
|
||||
}
|
||||
for (int i = 0; i < interface_count; ++i)
|
||||
{
|
||||
int f_count = interfaces[i]->_getFields (result, offset);
|
||||
count += f_count;
|
||||
offset += f_count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
JArray<java::lang::reflect::Field *> *
|
||||
java::lang::Class::getFields (void)
|
||||
{
|
||||
JvFail ("java::lang::Class::getFields not implemented");
|
||||
using namespace java::lang::reflect;
|
||||
|
||||
int count = _getFields (NULL, 0);
|
||||
|
||||
JArray<java::lang::reflect::Field *> *result
|
||||
= ((JArray<java::lang::reflect::Field *> *)
|
||||
JvNewObjectArray (count, &FieldClass, NULL));
|
||||
|
||||
_getFields (result, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
JArray<jclass> *
|
||||
@ -275,9 +444,30 @@ java::lang::Class::getInterfaces (void)
|
||||
}
|
||||
|
||||
java::lang::reflect::Method *
|
||||
java::lang::Class::getMethod (jstring, JArray<jclass> *)
|
||||
java::lang::Class::getMethod (jstring name, JArray<jclass> *param_types)
|
||||
{
|
||||
JvFail ("java::lang::Class::getMethod not implemented");
|
||||
jstring partial_sig = getSignature (param_types);
|
||||
jint p_len = partial_sig->length();
|
||||
_Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
|
||||
for (Class *klass = this; klass; klass = klass->getSuperclass())
|
||||
{
|
||||
int i = klass->isPrimitive () ? 0 : klass->method_count;
|
||||
while (--i >= 0)
|
||||
{
|
||||
// FIXME: access checks.
|
||||
if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
|
||||
&& _Jv_equaln (klass->methods[i].signature, partial_sig, p_len))
|
||||
{
|
||||
// Found it.
|
||||
using namespace java::lang::reflect;
|
||||
Method *rmethod = new Method ();
|
||||
rmethod->offset = (char*) (&klass->methods[i]) - (char*) methods;
|
||||
rmethod->declaringClass = klass;
|
||||
return rmethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
JvThrow (new java::lang::NoSuchMethodException);
|
||||
}
|
||||
|
||||
JArray<java::lang::reflect::Method *> *
|
||||
@ -494,6 +684,8 @@ java::lang::Class::initializeClass (void)
|
||||
// Some class-related convenience functions.
|
||||
//
|
||||
|
||||
// Find a method declared in the class. If it is not declared locally
|
||||
// (or if it is inherited), return NULL.
|
||||
_Jv_Method *
|
||||
_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
|
||||
_Jv_Utf8Const *signature)
|
||||
@ -507,6 +699,21 @@ _Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_Jv_Method *
|
||||
_Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
|
||||
_Jv_Utf8Const *signature)
|
||||
{
|
||||
for (; klass; klass = klass->getSuperclass())
|
||||
{
|
||||
_Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
|
||||
|
||||
if (meth)
|
||||
return meth;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// NOTE: MCACHE_SIZE should be a power of 2 minus one.
|
||||
#define MCACHE_SIZE 1023
|
||||
|
||||
@ -553,16 +760,6 @@ void *
|
||||
_Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
|
||||
_Jv_Utf8Const *signature)
|
||||
{
|
||||
// FIXME: can't do this until we have a working class loader.
|
||||
// This probably isn't the right thing to do anyway, since we can't
|
||||
// call a method of a class until the class is linked. But this
|
||||
// captures the general idea.
|
||||
// klass->getClassLoader()->resolveClass(klass);
|
||||
//
|
||||
// KKT: This is unnessecary, exactly for the reason you present:
|
||||
// _Jv_LookupInterfaceMethod is only called on object instances, and
|
||||
// such have already been initialized (which includes resolving).
|
||||
|
||||
void *ncode = _Jv_FindMethodInCache (klass, name, signature);
|
||||
if (ncode != 0)
|
||||
return ncode;
|
||||
|
@ -28,12 +28,12 @@ public final class Constructor extends AccessibleObject implements Member
|
||||
if (! (obj instanceof Constructor))
|
||||
return false;
|
||||
Constructor c = (Constructor) obj;
|
||||
return decl_class == c.decl_class && index == c.index;
|
||||
return declaringClass == c.declaringClass && offset == c.offset;
|
||||
}
|
||||
|
||||
public Class getDeclaringClass ()
|
||||
{
|
||||
return decl_class;
|
||||
return declaringClass;
|
||||
}
|
||||
|
||||
public Class[] getExceptionTypes ()
|
||||
@ -41,40 +41,39 @@ public final class Constructor extends AccessibleObject implements Member
|
||||
return (Class[]) exception_types.clone();
|
||||
}
|
||||
|
||||
public int getModifiers ()
|
||||
{
|
||||
return modifiers;
|
||||
}
|
||||
public native int getModifiers ();
|
||||
|
||||
public String getName ()
|
||||
{
|
||||
return decl_class.getName();
|
||||
}
|
||||
{
|
||||
return declaringClass.getName();
|
||||
}
|
||||
|
||||
public Class[] getParameterTypes ()
|
||||
{
|
||||
if (parameter_types == null)
|
||||
getType ();
|
||||
return (Class[]) parameter_types.clone();
|
||||
}
|
||||
|
||||
public int hashCode ()
|
||||
{
|
||||
// FIXME.
|
||||
return getName().hashCode();
|
||||
return getName().hashCode() + declaringClass.getName().hashCode();
|
||||
}
|
||||
|
||||
// FIXME: this must be native. Should share implementation with
|
||||
// Method.invoke.
|
||||
public Object newInstance (Object[] args)
|
||||
// Update cached values from method descriptor in class.
|
||||
private native void getType ();
|
||||
|
||||
public native Object newInstance (Object[] args)
|
||||
throws InstantiationException, IllegalAccessException,
|
||||
IllegalArgumentException, InvocationTargetException
|
||||
{
|
||||
return null;
|
||||
}
|
||||
IllegalArgumentException, InvocationTargetException;
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
if (parameter_types == null)
|
||||
getType ();
|
||||
StringBuffer b = new StringBuffer ();
|
||||
b.append(Modifier.toString(modifiers));
|
||||
b.append(Modifier.toString(getModifiers()));
|
||||
b.append(" ");
|
||||
b.append(getName());
|
||||
b.append("(");
|
||||
@ -88,19 +87,19 @@ public final class Constructor extends AccessibleObject implements Member
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
// Can't create these. FIXME.
|
||||
// Can't create these.
|
||||
private Constructor ()
|
||||
{
|
||||
}
|
||||
|
||||
// Declaring class.
|
||||
private Class decl_class;
|
||||
private Class declaringClass;
|
||||
|
||||
// Exception types.
|
||||
private Class[] exception_types;
|
||||
// Modifiers.
|
||||
private int modifiers;
|
||||
// Parameter types.
|
||||
private Class[] parameter_types;
|
||||
// Index of this method in declaring class' method table.
|
||||
private int index;
|
||||
|
||||
// Offset in bytes from the start of declaringClass's methods array.
|
||||
private int offset;
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ details. */
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import gnu.gcj.RawData;
|
||||
|
||||
/**
|
||||
* @author Tom Tromey <tromey@cygnus.com>
|
||||
* @date December 12, 1998
|
||||
@ -17,7 +19,7 @@ package java.lang.reflect;
|
||||
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
|
||||
* "The Java Language Specification", ISBN 0-201-63451-1
|
||||
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
|
||||
* Status: Incomplete: invoke() needs to be finished.
|
||||
* Status: Complete, but not correct: access checks aren't done.
|
||||
*/
|
||||
|
||||
public final class Method extends AccessibleObject implements Member
|
||||
@ -66,6 +68,30 @@ public final class Method extends AccessibleObject implements Member
|
||||
return name.hashCode() + declaringClass.getName().hashCode();
|
||||
}
|
||||
|
||||
// This is used to perform an actual method call via ffi.
|
||||
private static final native void hack_call (RawData cif,
|
||||
RawData method,
|
||||
RawData ret_value,
|
||||
RawData values);
|
||||
|
||||
// Perform an ffi call while capturing exceptions. We have to do
|
||||
// this because we can't catch Java exceptions from C++.
|
||||
static final Throwable hack_trampoline (RawData cif,
|
||||
RawData method,
|
||||
RawData ret_value,
|
||||
RawData values)
|
||||
{
|
||||
try
|
||||
{
|
||||
hack_call (cif, method, ret_value, values);
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public native Object invoke (Object obj, Object[] args)
|
||||
throws IllegalAccessException, IllegalArgumentException,
|
||||
InvocationTargetException;
|
||||
|
53
libjava/java/lang/reflect/natConstructor.cc
Normal file
53
libjava/java/lang/reflect/natConstructor.cc
Normal file
@ -0,0 +1,53 @@
|
||||
// natConstructor.cc - Native code for Constructor class.
|
||||
|
||||
/* Copyright (C) 1999, 2000 Cygnus Solutions
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
This software is copyrighted work licensed under the terms of the
|
||||
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
||||
details. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <gcj/cni.h>
|
||||
#include <jvm.h>
|
||||
|
||||
#include <java/lang/reflect/Constructor.h>
|
||||
#include <java/lang/reflect/Method.h>
|
||||
#include <java/lang/reflect/InvocationTargetException.h>
|
||||
#include <java/lang/reflect/Modifier.h>
|
||||
#include <java/lang/InstantiationException.h>
|
||||
#include <gcj/method.h>
|
||||
|
||||
jint
|
||||
java::lang::reflect::Constructor::getModifiers ()
|
||||
{
|
||||
return _Jv_FromReflectedConstructor (this)->accflags;
|
||||
}
|
||||
|
||||
void
|
||||
java::lang::reflect::Constructor::getType ()
|
||||
{
|
||||
_Jv_GetTypesFromSignature (_Jv_FromReflectedConstructor (this),
|
||||
declaringClass,
|
||||
¶meter_types,
|
||||
NULL);
|
||||
}
|
||||
|
||||
jobject
|
||||
java::lang::reflect::Constructor::newInstance (jobjectArray args)
|
||||
{
|
||||
if (parameter_types == NULL)
|
||||
getType ();
|
||||
|
||||
using namespace java::lang::reflect;
|
||||
if (Modifier::isAbstract (declaringClass->getModifiers()))
|
||||
JvThrow (new InstantiationException);
|
||||
|
||||
jmethodID meth = _Jv_FromReflectedConstructor (this);
|
||||
// In the constructor case the return type is the type of the
|
||||
// constructor.
|
||||
return _Jv_CallNonvirtualMethodA (NULL, declaringClass, meth, true,
|
||||
parameter_types, args);
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
// natMethod.cc - Native code for Method class.
|
||||
|
||||
/* Copyright (C) 1998, 1999 Cygnus Solutions
|
||||
/* Copyright (C) 1998, 1999, 2000 Cygnus Solutions
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
@ -8,14 +8,13 @@ This software is copyrighted work licensed under the terms of the
|
||||
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
||||
details. */
|
||||
|
||||
// This is about 90% done. Search for FIXME to see what remains.
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <gcj/cni.h>
|
||||
#include <jvm.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>
|
||||
|
||||
@ -32,14 +31,15 @@ details. */
|
||||
#include <java/lang/NullPointerException.h>
|
||||
#include <java/lang/Class.h>
|
||||
#include <gcj/method.h>
|
||||
#include <gnu/gcj/RawData.h>
|
||||
|
||||
#define ObjectClass _CL_Q34java4lang6Object
|
||||
extern java::lang::Class ObjectClass;
|
||||
#define ClassClass _CL_Q34java4lang5Class
|
||||
extern java::lang::Class ClassClass;
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if 0
|
||||
|
||||
#include <ffi.h>
|
||||
|
||||
#define VoidClass _CL_Q34java4lang4Void
|
||||
@ -145,147 +145,46 @@ get_ffi_type (jclass klass)
|
||||
return r;
|
||||
}
|
||||
|
||||
// FIXME: the body of this method should be a separate function so
|
||||
// that Constructor can use it too.
|
||||
jobject
|
||||
java::lang::reflect::Method::invoke (jobject obj,
|
||||
jobjectArray args)
|
||||
// Actually perform an FFI call.
|
||||
void
|
||||
java::lang::reflect::Method::hack_call (gnu::gcj::RawData *rcif,
|
||||
gnu::gcj::RawData *rmethod,
|
||||
gnu::gcj::RawData *rret_value,
|
||||
gnu::gcj::RawData *rvalues)
|
||||
{
|
||||
// FIXME: we need to be a friend of Class here.
|
||||
_Jv_Method *meth = decl_class->methods[index];
|
||||
if (! java::lang::reflect::Modifier::isStatic(modifiers))
|
||||
ffi_cif *cif = (ffi_cif *) rcif;
|
||||
void (*method) (...) = (void (*) (...)) rmethod;
|
||||
void *ret_value = (void *) rret_value;
|
||||
void **values = (void **) rvalues;
|
||||
|
||||
ffi_call (cif, method, ret_value, values);
|
||||
}
|
||||
|
||||
jobject
|
||||
java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
|
||||
{
|
||||
if (parameter_types == NULL)
|
||||
getType ();
|
||||
|
||||
jmethodID meth = _Jv_FromReflectedMethod (this);
|
||||
if (! java::lang::reflect::Modifier::isStatic(meth->accflags))
|
||||
{
|
||||
jclass k = obj ? obj->getClass() : NULL;
|
||||
if (! obj || ! decl_class->isAssignableFrom(k))
|
||||
if (! obj)
|
||||
JvThrow (new java::lang::NullPointerException);
|
||||
if (! declaringClass->isAssignableFrom(k))
|
||||
JvThrow (new java::lang::IllegalArgumentException);
|
||||
// FIXME: access checks.
|
||||
meth = _Jv_LookupMethod (k, meth->name, meth->signature);
|
||||
|
||||
// Find the possibly overloaded method based on the runtime type
|
||||
// of the object.
|
||||
meth = _Jv_LookupDeclaredMethod (k, meth->name, meth->signature);
|
||||
}
|
||||
|
||||
// FIXME: access checks.
|
||||
|
||||
if (parameter_types->length != args->length)
|
||||
JvThrow (new java::lang::IllegalArgumentException);
|
||||
|
||||
ffi_type *rtype = get_ffi_type (return_type);
|
||||
ffi_type **argtypes = (ffi_type **) alloca (parameter_types->length
|
||||
* sizeof (ffi_type *));
|
||||
|
||||
jobject *paramelts = elements (parameter_types);
|
||||
jobject *argelts = elements (args);
|
||||
|
||||
int size = 0;
|
||||
for (int i = 0; i < parameter_types->length; ++i)
|
||||
{
|
||||
jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
|
||||
argtypes[i] = get_ffi_type (k);
|
||||
if (paramelts[i]->isPrimitive())
|
||||
{
|
||||
if (! argelts[i]
|
||||
|| ! k->isPrimitive ()
|
||||
|| ! can_widen (k, paramelts[i]))
|
||||
JvThrow (new java::lang::IllegalArgumentException);
|
||||
size += paramelts[i]->size();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
|
||||
JvThrow (new java::lang::IllegalArgumentException);
|
||||
size += sizeof (jobject);
|
||||
}
|
||||
}
|
||||
|
||||
ffi_cif cif;
|
||||
if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, parameter_types->length,
|
||||
rtype, argtypes) != FFI_OK)
|
||||
{
|
||||
// FIXME: throw some kind of VirtualMachineError here.
|
||||
}
|
||||
|
||||
char *values = (char *) alloca (size);
|
||||
char *p = values;
|
||||
|
||||
#define COPY(Where, What, Type) \
|
||||
do { \
|
||||
Type val = (What); \
|
||||
memcpy ((Where), &val, sizeof (Type)); \
|
||||
Where += sizeof (Type); \
|
||||
} while (0)
|
||||
|
||||
for (int i = 0; i < parameter_types->length; ++i)
|
||||
{
|
||||
java::lang::Number *num = (java::lang::Number *) paramelts[i];
|
||||
if (paramelts[i] == JvPrimClass (byte))
|
||||
COPY (p, num->byteValue(), jbyte);
|
||||
else if (paramelts[i] == JvPrimClass (short))
|
||||
COPY (p, num->shortValue(), jshort);
|
||||
else if (paramelts[i] == JvPrimClass (int))
|
||||
COPY (p, num->intValue(), jint);
|
||||
else if (paramelts[i] == JvPrimClass (long))
|
||||
COPY (p, num->longValue(), jlong);
|
||||
else if (paramelts[i] == JvPrimClass (float))
|
||||
COPY (p, num->floatValue(), jfloat);
|
||||
else if (paramelts[i] == JvPrimClass (double))
|
||||
COPY (p, num->doubleValue(), jdouble);
|
||||
else if (paramelts[i] == JvPrimClass (boolean))
|
||||
COPY (p, ((java::lang::Boolean *) argelts[i])->booleanValue(), jboolean);
|
||||
else if (paramelts[i] == JvPrimClass (char))
|
||||
COPY (p, ((java::lang::Character *) argelts[i])->charValue(), jchar);
|
||||
else
|
||||
{
|
||||
JvAssert (! paramelts[i]->isPrimitive());
|
||||
COPY (p, argelts[i], jobject);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: exception handling.
|
||||
java::lang::Throwable *ex;
|
||||
jdouble ret_value; // Largest possible value. Hopefully
|
||||
// it is aligned!
|
||||
ex = TRAMP_CALL (ffi_call (&cif, meth->ncode, &ret_value, (void *) values));
|
||||
|
||||
if (ex)
|
||||
JvThrow (new InvocationTargetException (ex));
|
||||
|
||||
jobject r;
|
||||
#define VAL(Wrapper, Type) (new Wrapper (* (Type *) &ret_value))
|
||||
if (return_type == JvPrimClass (byte))
|
||||
r = VAL (java::lang::Byte, jbyte);
|
||||
else if (return_type == JvPrimClass (short))
|
||||
r = VAL (java::lang::Short, jshort);
|
||||
else if (return_type == JvPrimClass (int))
|
||||
r = VAL (java::lang::Integer, jint);
|
||||
else if (return_type == JvPrimClass (long))
|
||||
r = VAL (java::lang::Long, jlong);
|
||||
else if (return_type == JvPrimClass (float))
|
||||
r = VAL (java::lang::Float, jfloat);
|
||||
else if (return_type == JvPrimClass (double))
|
||||
r = VAL (java::lang::Double, jdouble);
|
||||
else if (return_type == JvPrimClass (boolean))
|
||||
r = VAL (java::lang::Boolean, jboolean);
|
||||
else if (return_type == JvPrimClass (char))
|
||||
r = VAL (java::lang::Character, jchar);
|
||||
else if (return_type == JvPrimClass (void))
|
||||
r = NULL;
|
||||
else
|
||||
{
|
||||
JvAssert (! return_type->isPrimitive());
|
||||
r = VAL (java::lang::Object, jobject);
|
||||
}
|
||||
|
||||
return r;
|
||||
return _Jv_CallNonvirtualMethodA (obj, return_type, meth, false,
|
||||
parameter_types, args);
|
||||
}
|
||||
|
||||
#else /* 0 */
|
||||
|
||||
jobject
|
||||
java::lang::reflect::Method::invoke (jobject, jobjectArray)
|
||||
{
|
||||
JvFail ("not enabled yet");
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
jint
|
||||
java::lang::reflect::Method::getModifiers ()
|
||||
{
|
||||
@ -305,7 +204,20 @@ java::lang::reflect::Method::getName ()
|
||||
void
|
||||
java::lang::reflect::Method::getType ()
|
||||
{
|
||||
_Jv_Utf8Const* sig = _Jv_FromReflectedMethod (this)->signature;
|
||||
_Jv_GetTypesFromSignature (_Jv_FromReflectedMethod (this),
|
||||
declaringClass,
|
||||
¶meter_types,
|
||||
&return_type);
|
||||
}
|
||||
|
||||
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->getClassLoader();
|
||||
char *ptr = sig->data;
|
||||
int numArgs = 0;
|
||||
@ -355,7 +267,7 @@ java::lang::reflect::Method::getType ()
|
||||
default:
|
||||
return;
|
||||
case ')':
|
||||
argPtr = &return_type;
|
||||
argPtr = return_type_out;
|
||||
continue;
|
||||
case '(':
|
||||
continue;
|
||||
@ -381,7 +293,187 @@ java::lang::reflect::Method::getType ()
|
||||
// FIXME: 2'nd argument should be "current loader"
|
||||
while (--num_arrays >= 0)
|
||||
type = _Jv_FindArrayClass (type, 0);
|
||||
*argPtr++ = type;
|
||||
// ARGPTR can be NULL if we are processing the return value of a
|
||||
// call from Constructor.
|
||||
if (argPtr)
|
||||
*argPtr++ = type;
|
||||
}
|
||||
parameter_types = args;
|
||||
*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.
|
||||
jobject
|
||||
_Jv_CallNonvirtualMethodA (jobject obj,
|
||||
jclass return_type,
|
||||
jmethodID meth,
|
||||
jboolean is_constructor,
|
||||
JArray<jclass> *parameter_types,
|
||||
jobjectArray args)
|
||||
{
|
||||
JvAssert (! is_constructor || ! obj);
|
||||
JvAssert (! is_constructor || ! return_type);
|
||||
|
||||
// FIXME: access checks.
|
||||
|
||||
if (parameter_types->length != args->length)
|
||||
JvThrow (new java::lang::IllegalArgumentException);
|
||||
|
||||
// See whether call needs an object as the first argument. A
|
||||
// constructor does need a `this' argument, but it is one we create.
|
||||
jboolean needs_this = false;
|
||||
if (is_constructor
|
||||
|| ! java::lang::reflect::Modifier::isStatic(meth->accflags))
|
||||
needs_this = true;
|
||||
|
||||
int param_count = parameter_types->length;
|
||||
if (needs_this)
|
||||
++param_count;
|
||||
|
||||
ffi_type *rtype = get_ffi_type (return_type);
|
||||
ffi_type **argtypes = (ffi_type **) alloca (param_count
|
||||
* sizeof (ffi_type *));
|
||||
|
||||
jclass *paramelts = elements (parameter_types);
|
||||
jobject *argelts = elements (args);
|
||||
|
||||
// FIXME: at some point the compiler is going to add extra arguments
|
||||
// to some functions. In particular we are going to do this for
|
||||
// handling access checks in reflection. We must add these hidden
|
||||
// arguments here.
|
||||
|
||||
// Special case for the `this' argument of a constructor. Note that
|
||||
// the JDK 1.2 docs specify that the new object must be allocated
|
||||
// before argument conversions are done.
|
||||
if (is_constructor)
|
||||
{
|
||||
// FIXME: must special-case String, arrays, maybe others here.
|
||||
obj = JvAllocObject (return_type);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int size = 0;
|
||||
if (needs_this)
|
||||
{
|
||||
// The `NULL' type is `Object'.
|
||||
argtypes[i++] = get_ffi_type (NULL);
|
||||
size += sizeof (jobject);
|
||||
}
|
||||
|
||||
for (; i < param_count; ++i)
|
||||
{
|
||||
jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
|
||||
argtypes[i] = get_ffi_type (k);
|
||||
if (paramelts[i]->isPrimitive())
|
||||
{
|
||||
if (! argelts[i]
|
||||
|| ! k->isPrimitive ()
|
||||
|| ! can_widen (k, paramelts[i]))
|
||||
JvThrow (new java::lang::IllegalArgumentException);
|
||||
size += paramelts[i]->size();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
|
||||
JvThrow (new java::lang::IllegalArgumentException);
|
||||
size += sizeof (jobject);
|
||||
}
|
||||
}
|
||||
|
||||
ffi_cif cif;
|
||||
if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, param_count,
|
||||
rtype, argtypes) != FFI_OK)
|
||||
{
|
||||
// FIXME: throw some kind of VirtualMachineError here.
|
||||
}
|
||||
|
||||
char *values = (char *) alloca (size);
|
||||
char *p = values;
|
||||
|
||||
#define COPY(Where, What, Type) \
|
||||
do { \
|
||||
Type val = (What); \
|
||||
memcpy ((Where), &val, sizeof (Type)); \
|
||||
Where += sizeof (Type); \
|
||||
} while (0)
|
||||
|
||||
i = 0;
|
||||
if (needs_this)
|
||||
{
|
||||
COPY (p, obj, jobject);
|
||||
++i;
|
||||
}
|
||||
|
||||
for (; i < param_count; ++i)
|
||||
{
|
||||
java::lang::Number *num = (java::lang::Number *) paramelts[i];
|
||||
if (paramelts[i] == JvPrimClass (byte))
|
||||
COPY (p, num->byteValue(), jbyte);
|
||||
else if (paramelts[i] == JvPrimClass (short))
|
||||
COPY (p, num->shortValue(), jshort);
|
||||
else if (paramelts[i] == JvPrimClass (int))
|
||||
COPY (p, num->intValue(), jint);
|
||||
else if (paramelts[i] == JvPrimClass (long))
|
||||
COPY (p, num->longValue(), jlong);
|
||||
else if (paramelts[i] == JvPrimClass (float))
|
||||
COPY (p, num->floatValue(), jfloat);
|
||||
else if (paramelts[i] == JvPrimClass (double))
|
||||
COPY (p, num->doubleValue(), jdouble);
|
||||
else if (paramelts[i] == JvPrimClass (boolean))
|
||||
COPY (p, ((java::lang::Boolean *) argelts[i])->booleanValue(),
|
||||
jboolean);
|
||||
else if (paramelts[i] == JvPrimClass (char))
|
||||
COPY (p, ((java::lang::Character *) argelts[i])->charValue(), jchar);
|
||||
else
|
||||
{
|
||||
JvAssert (! paramelts[i]->isPrimitive());
|
||||
COPY (p, argelts[i], jobject);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: initialize class here.
|
||||
|
||||
// Largest possible value. Hopefully it is aligned!
|
||||
jdouble ret_value;
|
||||
java::lang::Throwable *ex;
|
||||
using namespace java::lang;
|
||||
using namespace java::lang::reflect;
|
||||
ex = Method::hack_trampoline ((gnu::gcj::RawData *) &cif,
|
||||
(gnu::gcj::RawData *) meth->ncode,
|
||||
(gnu::gcj::RawData *) &ret_value,
|
||||
(gnu::gcj::RawData *) values);
|
||||
|
||||
if (ex)
|
||||
JvThrow (new InvocationTargetException (ex));
|
||||
|
||||
jobject r;
|
||||
#define VAL(Wrapper, Type) (new Wrapper (* (Type *) &ret_value))
|
||||
if (return_type == JvPrimClass (byte))
|
||||
r = VAL (java::lang::Byte, jbyte);
|
||||
else if (return_type == JvPrimClass (short))
|
||||
r = VAL (java::lang::Short, jshort);
|
||||
else if (return_type == JvPrimClass (int))
|
||||
r = VAL (java::lang::Integer, jint);
|
||||
else if (return_type == JvPrimClass (long))
|
||||
r = VAL (java::lang::Long, jlong);
|
||||
else if (return_type == JvPrimClass (float))
|
||||
r = VAL (java::lang::Float, jfloat);
|
||||
else if (return_type == JvPrimClass (double))
|
||||
r = VAL (java::lang::Double, jdouble);
|
||||
else if (return_type == JvPrimClass (boolean))
|
||||
r = VAL (java::lang::Boolean, jboolean);
|
||||
else if (return_type == JvPrimClass (char))
|
||||
r = VAL (java::lang::Character, jchar);
|
||||
else if (return_type == JvPrimClass (void))
|
||||
r = NULL;
|
||||
else
|
||||
{
|
||||
JvAssert (return_type == NULL || ! return_type->isPrimitive());
|
||||
r = * (Object **) &ret_value;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -16,8 +16,6 @@ details. */
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#pragma implementation "gcj/array.h"
|
||||
|
||||
#include <gcj/cni.h>
|
||||
#include <jvm.h>
|
||||
#include <java-signal.h>
|
||||
@ -143,6 +141,26 @@ _Jv_equal (Utf8Const* a, jstring str, jint hash)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Like _Jv_equal, but stop after N characters. */
|
||||
jboolean
|
||||
_Jv_equaln (Utf8Const *a, jstring str, jint n)
|
||||
{
|
||||
jint len = str->length();
|
||||
jint i = 0;
|
||||
jchar *sptr = _Jv_GetStringChars (str);
|
||||
register unsigned char* ptr = (unsigned char*) a->data;
|
||||
register unsigned char* limit = ptr + a->length;
|
||||
for (; n-- > 0; i++, sptr++)
|
||||
{
|
||||
int ch = UTF8_GET (ptr, limit);
|
||||
if (i == len)
|
||||
return ch < 0;
|
||||
if (ch != *sptr)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Count the number of Unicode chars encoded in a given Ut8 string. */
|
||||
int
|
||||
_Jv_strLengthUtf8(char* str, int len)
|
||||
|
@ -321,21 +321,6 @@ _Jv_ResolveField (_Jv_Field *field, java::lang::ClassLoader *loader)
|
||||
}
|
||||
}
|
||||
|
||||
_Jv_Method*
|
||||
_Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
|
||||
_Jv_Utf8Const *signature)
|
||||
{
|
||||
for (; klass; klass = klass->getSuperclass())
|
||||
{
|
||||
_Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
|
||||
|
||||
if (meth)
|
||||
return meth;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** FIXME: this is a terribly inefficient algorithm! It would improve
|
||||
things if compiled classes to know vtable offset, and _Jv_Method had
|
||||
a field for this.
|
||||
|
@ -76,12 +76,14 @@ DLLTOOL = @DLLTOOL@
|
||||
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
||||
EXCEPTIONSPEC = @EXCEPTIONSPEC@
|
||||
EXEEXT = @EXEEXT@
|
||||
FORCELIBGCCSPEC = @FORCELIBGCCSPEC@
|
||||
GCDEPS = @GCDEPS@
|
||||
GCINCS = @GCINCS@
|
||||
GCLIBS = @GCLIBS@
|
||||
GCOBJS = @GCOBJS@
|
||||
GCSPEC = @GCSPEC@
|
||||
LD = @LD@
|
||||
LIBDATASTARTSPEC = @LIBDATASTARTSPEC@
|
||||
LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@
|
||||
LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@
|
||||
LIBGCJ_JAVAFLAGS = @LIBGCJ_JAVAFLAGS@
|
||||
@ -90,7 +92,6 @@ LN_S = @LN_S@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NM = @NM@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
PACKAGE = @PACKAGE@
|
||||
PERL = @PERL@
|
||||
RANLIB = @RANLIB@
|
||||
@ -100,6 +101,7 @@ THREADINCS = @THREADINCS@
|
||||
THREADLIBS = @THREADLIBS@
|
||||
THREADOBJS = @THREADOBJS@
|
||||
THREADSPEC = @THREADSPEC@
|
||||
USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
|
||||
VERSION = @VERSION@
|
||||
ZDEPS = @ZDEPS@
|
||||
ZINCS = @ZINCS@
|
||||
|
Loading…
Reference in New Issue
Block a user