[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
18 changed files with 739 additions and 232 deletions
|
@ -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>
|
1999-12-22 Bryce McKinlay <bryce@albatross.co.nz>
|
||||||
|
|
||||||
* java/lang/natObject.cc (notify): Throw message with
|
* java/lang/natObject.cc (notify): Throw message with
|
||||||
|
|
|
@ -74,8 +74,10 @@ JAVAC = $(GCJ) -C
|
||||||
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
||||||
|
|
||||||
WARNINGS = -W -Wall
|
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@ \
|
AM_CXXFLAGS = -fno-rtti -fvtable-thunks @LIBGCJ_CXXFLAGS@ @EXCEPTIONSPEC@ \
|
||||||
$(WARNINGS)
|
$(WARNINGS) -D_GNU_SOURCE
|
||||||
if USING_GCC
|
if USING_GCC
|
||||||
AM_CFLAGS = @LIBGCJ_CFLAGS@ $(WARNINGS)
|
AM_CFLAGS = @LIBGCJ_CFLAGS@ $(WARNINGS)
|
||||||
else
|
else
|
||||||
|
@ -229,6 +231,12 @@ java/lang/String.h: java/lang/String.class libgcj.zip
|
||||||
-friend 'jstring _Jv_AllocString (jsize);' \
|
-friend 'jstring _Jv_AllocString (jsize);' \
|
||||||
$(basename $<)
|
$(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
|
java/lang/reflect/Field.h: java/lang/reflect/Field.class libgcj.zip
|
||||||
$(GCJH) -classpath $(top_builddir) \
|
$(GCJH) -classpath $(top_builddir) \
|
||||||
-friend 'jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);' \
|
-friend 'jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);' \
|
||||||
|
@ -797,6 +805,7 @@ java/lang/natString.cc \
|
||||||
java/lang/natSystem.cc \
|
java/lang/natSystem.cc \
|
||||||
java/lang/natThread.cc \
|
java/lang/natThread.cc \
|
||||||
java/lang/reflect/natArray.cc \
|
java/lang/reflect/natArray.cc \
|
||||||
|
java/lang/reflect/natConstructor.cc \
|
||||||
java/lang/reflect/natField.cc \
|
java/lang/reflect/natField.cc \
|
||||||
java/lang/reflect/natMethod.cc \
|
java/lang/reflect/natMethod.cc \
|
||||||
java/net/natInetAddress.cc \
|
java/net/natInetAddress.cc \
|
||||||
|
|
|
@ -158,7 +158,7 @@ EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
||||||
|
|
||||||
WARNINGS = -W -Wall
|
WARNINGS = -W -Wall
|
||||||
AM_CXXFLAGS = -fno-rtti -fvtable-thunks @LIBGCJ_CXXFLAGS@ @EXCEPTIONSPEC@ \
|
AM_CXXFLAGS = -fno-rtti -fvtable-thunks @LIBGCJ_CXXFLAGS@ @EXCEPTIONSPEC@ \
|
||||||
$(WARNINGS)
|
$(WARNINGS) -D_GNU_SOURCE
|
||||||
|
|
||||||
@USING_GCC_TRUE@AM_CFLAGS = \
|
@USING_GCC_TRUE@AM_CFLAGS = \
|
||||||
@USING_GCC_TRUE@@LIBGCJ_CFLAGS@ $(WARNINGS)
|
@USING_GCC_TRUE@@LIBGCJ_CFLAGS@ $(WARNINGS)
|
||||||
|
@ -619,6 +619,7 @@ java/lang/natString.cc \
|
||||||
java/lang/natSystem.cc \
|
java/lang/natSystem.cc \
|
||||||
java/lang/natThread.cc \
|
java/lang/natThread.cc \
|
||||||
java/lang/reflect/natArray.cc \
|
java/lang/reflect/natArray.cc \
|
||||||
|
java/lang/reflect/natConstructor.cc \
|
||||||
java/lang/reflect/natField.cc \
|
java/lang/reflect/natField.cc \
|
||||||
java/lang/reflect/natMethod.cc \
|
java/lang/reflect/natMethod.cc \
|
||||||
java/net/natInetAddress.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)
|
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
|
||||||
TAR = gtar
|
TAR = tar
|
||||||
GZIP_ENV = --best
|
GZIP_ENV = --best
|
||||||
DIST_SUBDIRS = testsuite gcj include gcj include
|
DIST_SUBDIRS = testsuite gcj include gcj include
|
||||||
DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||||
|
@ -1267,7 +1268,7 @@ distdir: $(DISTFILES)
|
||||||
@for file in $(DISTFILES); do \
|
@for file in $(DISTFILES); do \
|
||||||
d=$(srcdir); \
|
d=$(srcdir); \
|
||||||
if test -d $$d/$$file; then \
|
if test -d $$d/$$file; then \
|
||||||
cp -pr $$d/$$file $(distdir)/$$file; \
|
cp -pr $$/$$file $(distdir)/$$file; \
|
||||||
else \
|
else \
|
||||||
test -f $(distdir)/$$file \
|
test -f $(distdir)/$$file \
|
||||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
|| 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);' \
|
-friend 'jstring _Jv_AllocString (jsize);' \
|
||||||
$(basename $<)
|
$(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
|
java/lang/reflect/Field.h: java/lang/reflect/Field.class libgcj.zip
|
||||||
$(GCJH) -classpath $(top_builddir) \
|
$(GCJH) -classpath $(top_builddir) \
|
||||||
-friend 'jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);' \
|
-friend 'jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);' \
|
||||||
|
|
|
@ -76,12 +76,14 @@ DLLTOOL = @DLLTOOL@
|
||||||
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
||||||
EXCEPTIONSPEC = @EXCEPTIONSPEC@
|
EXCEPTIONSPEC = @EXCEPTIONSPEC@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
|
FORCELIBGCCSPEC = @FORCELIBGCCSPEC@
|
||||||
GCDEPS = @GCDEPS@
|
GCDEPS = @GCDEPS@
|
||||||
GCINCS = @GCINCS@
|
GCINCS = @GCINCS@
|
||||||
GCLIBS = @GCLIBS@
|
GCLIBS = @GCLIBS@
|
||||||
GCOBJS = @GCOBJS@
|
GCOBJS = @GCOBJS@
|
||||||
GCSPEC = @GCSPEC@
|
GCSPEC = @GCSPEC@
|
||||||
LD = @LD@
|
LD = @LD@
|
||||||
|
LIBDATASTARTSPEC = @LIBDATASTARTSPEC@
|
||||||
LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@
|
LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@
|
||||||
LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@
|
LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@
|
||||||
LIBGCJ_JAVAFLAGS = @LIBGCJ_JAVAFLAGS@
|
LIBGCJ_JAVAFLAGS = @LIBGCJ_JAVAFLAGS@
|
||||||
|
@ -90,7 +92,6 @@ LN_S = @LN_S@
|
||||||
MAINT = @MAINT@
|
MAINT = @MAINT@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
NM = @NM@
|
NM = @NM@
|
||||||
OBJDUMP = @OBJDUMP@
|
|
||||||
PACKAGE = @PACKAGE@
|
PACKAGE = @PACKAGE@
|
||||||
PERL = @PERL@
|
PERL = @PERL@
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
|
@ -100,6 +101,7 @@ THREADINCS = @THREADINCS@
|
||||||
THREADLIBS = @THREADLIBS@
|
THREADLIBS = @THREADLIBS@
|
||||||
THREADOBJS = @THREADOBJS@
|
THREADOBJS = @THREADOBJS@
|
||||||
THREADSPEC = @THREADSPEC@
|
THREADSPEC = @THREADSPEC@
|
||||||
|
USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
|
||||||
VERSION = @VERSION@
|
VERSION = @VERSION@
|
||||||
ZDEPS = @ZDEPS@
|
ZDEPS = @ZDEPS@
|
||||||
ZINCS = @ZINCS@
|
ZINCS = @ZINCS@
|
||||||
|
|
|
@ -11,8 +11,6 @@ details. */
|
||||||
#ifndef __GCJ_ARRAY_H__
|
#ifndef __GCJ_ARRAY_H__
|
||||||
#define __GCJ_ARRAY_H__
|
#define __GCJ_ARRAY_H__
|
||||||
|
|
||||||
#pragma interface
|
|
||||||
|
|
||||||
#include <java/lang/Object.h>
|
#include <java/lang/Object.h>
|
||||||
|
|
||||||
extern "Java" {
|
extern "Java" {
|
||||||
|
|
|
@ -18,4 +18,11 @@ _Jv_FromReflectedMethod(java::lang::reflect::Method *method)
|
||||||
((char *) method->declaringClass->methods + method->offset);
|
((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__ */
|
#endif /* __GCJ_METHOD_H__ */
|
||||||
|
|
|
@ -76,12 +76,14 @@ DLLTOOL = @DLLTOOL@
|
||||||
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
||||||
EXCEPTIONSPEC = @EXCEPTIONSPEC@
|
EXCEPTIONSPEC = @EXCEPTIONSPEC@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
|
FORCELIBGCCSPEC = @FORCELIBGCCSPEC@
|
||||||
GCDEPS = @GCDEPS@
|
GCDEPS = @GCDEPS@
|
||||||
GCINCS = @GCINCS@
|
GCINCS = @GCINCS@
|
||||||
GCLIBS = @GCLIBS@
|
GCLIBS = @GCLIBS@
|
||||||
GCOBJS = @GCOBJS@
|
GCOBJS = @GCOBJS@
|
||||||
GCSPEC = @GCSPEC@
|
GCSPEC = @GCSPEC@
|
||||||
LD = @LD@
|
LD = @LD@
|
||||||
|
LIBDATASTARTSPEC = @LIBDATASTARTSPEC@
|
||||||
LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@
|
LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@
|
||||||
LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@
|
LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@
|
||||||
LIBGCJ_JAVAFLAGS = @LIBGCJ_JAVAFLAGS@
|
LIBGCJ_JAVAFLAGS = @LIBGCJ_JAVAFLAGS@
|
||||||
|
@ -90,7 +92,6 @@ LN_S = @LN_S@
|
||||||
MAINT = @MAINT@
|
MAINT = @MAINT@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
NM = @NM@
|
NM = @NM@
|
||||||
OBJDUMP = @OBJDUMP@
|
|
||||||
PACKAGE = @PACKAGE@
|
PACKAGE = @PACKAGE@
|
||||||
PERL = @PERL@
|
PERL = @PERL@
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
|
@ -100,6 +101,7 @@ THREADINCS = @THREADINCS@
|
||||||
THREADLIBS = @THREADLIBS@
|
THREADLIBS = @THREADLIBS@
|
||||||
THREADOBJS = @THREADOBJS@
|
THREADOBJS = @THREADOBJS@
|
||||||
THREADSPEC = @THREADSPEC@
|
THREADSPEC = @THREADSPEC@
|
||||||
|
USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
|
||||||
VERSION = @VERSION@
|
VERSION = @VERSION@
|
||||||
ZDEPS = @ZDEPS@
|
ZDEPS = @ZDEPS@
|
||||||
ZINCS = @ZINCS@
|
ZINCS = @ZINCS@
|
||||||
|
|
|
@ -53,6 +53,7 @@ _Jv_Utf8Const *_Jv_makeUtf8Const (char *s, int len);
|
||||||
_Jv_Utf8Const *_Jv_makeUtf8Const (jstring string);
|
_Jv_Utf8Const *_Jv_makeUtf8Const (jstring string);
|
||||||
extern jboolean _Jv_equalUtf8Consts (_Jv_Utf8Const *, _Jv_Utf8Const *);
|
extern jboolean _Jv_equalUtf8Consts (_Jv_Utf8Const *, _Jv_Utf8Const *);
|
||||||
extern jboolean _Jv_equal (_Jv_Utf8Const *, jstring, jint);
|
extern jboolean _Jv_equal (_Jv_Utf8Const *, jstring, jint);
|
||||||
|
extern jboolean _Jv_equaln (_Jv_Utf8Const *, jstring, jint);
|
||||||
|
|
||||||
#define StringClass _CL_Q34java4lang6String
|
#define StringClass _CL_Q34java4lang6String
|
||||||
extern java::lang::Class StringClass;
|
extern java::lang::Class StringClass;
|
||||||
|
@ -161,6 +162,13 @@ extern jclass _Jv_FindClass (_Jv_Utf8Const *name,
|
||||||
java::lang::ClassLoader *loader);
|
java::lang::ClassLoader *loader);
|
||||||
extern jclass _Jv_FindClassFromSignature (char *,
|
extern jclass _Jv_FindClassFromSignature (char *,
|
||||||
java::lang::ClassLoader *loader);
|
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)
|
extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
|
||||||
__attribute__((__malloc__));
|
__attribute__((__malloc__));
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Class.h - Header file for java.lang.Class. -*- c++ -*-
|
// 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.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -94,12 +94,16 @@ public:
|
||||||
|
|
||||||
java::lang::reflect::Field *getField (jstring);
|
java::lang::reflect::Field *getField (jstring);
|
||||||
private:
|
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);
|
java::lang::reflect::Field *getField (jstring, jint);
|
||||||
public:
|
public:
|
||||||
JArray<java::lang::reflect::Field *> *getFields (void);
|
JArray<java::lang::reflect::Field *> *getFields (void);
|
||||||
|
|
||||||
JArray<jclass> *getInterfaces (void);
|
JArray<jclass> *getInterfaces (void);
|
||||||
|
|
||||||
|
void getSignature (java::lang::StringBuffer *buffer);
|
||||||
|
static jstring getSignature (JArray<jclass> *);
|
||||||
java::lang::reflect::Method *getMethod (jstring, JArray<jclass> *);
|
java::lang::reflect::Method *getMethod (jstring, JArray<jclass> *);
|
||||||
JArray<java::lang::reflect::Method *> *getMethods (void);
|
JArray<java::lang::reflect::Method *> *getMethods (void);
|
||||||
|
|
||||||
|
@ -156,6 +160,8 @@ private:
|
||||||
// Friend functions implemented in natClass.cc.
|
// Friend functions implemented in natClass.cc.
|
||||||
friend _Jv_Method *_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
|
friend _Jv_Method *_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
|
||||||
_Jv_Utf8Const *signature);
|
_Jv_Utf8Const *signature);
|
||||||
|
friend _Jv_Method* _Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
|
||||||
|
_Jv_Utf8Const*);
|
||||||
friend void _Jv_InitClass (jclass klass);
|
friend void _Jv_InitClass (jclass klass);
|
||||||
|
|
||||||
friend jfieldID JvGetFirstInstanceField (jclass);
|
friend jfieldID JvGetFirstInstanceField (jclass);
|
||||||
|
@ -166,6 +172,7 @@ private:
|
||||||
friend jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv *, jclass, jfieldID);
|
friend jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv *, jclass, jfieldID);
|
||||||
friend jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);
|
friend jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);
|
||||||
friend jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
|
friend jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
|
||||||
|
friend jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);
|
||||||
|
|
||||||
friend class _Jv_PrimClass;
|
friend class _Jv_PrimClass;
|
||||||
|
|
||||||
|
@ -190,8 +197,6 @@ private:
|
||||||
#ifdef INTERPRETER
|
#ifdef INTERPRETER
|
||||||
friend jboolean _Jv_IsInterpretedClass (jclass);
|
friend jboolean _Jv_IsInterpretedClass (jclass);
|
||||||
friend void _Jv_InitField (jobject, jclass, _Jv_Field*);
|
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 *,
|
friend int _Jv_DetermineVTableIndex (jclass, _Jv_Utf8Const *,
|
||||||
_Jv_Utf8Const*);
|
_Jv_Utf8Const*);
|
||||||
friend void _Jv_InitField (jobject, jclass, int);
|
friend void _Jv_InitField (jobject, jclass, int);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Class.java - Representation of a Java class.
|
// 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.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -36,14 +36,27 @@ public final class Class implements Serializable
|
||||||
|
|
||||||
public native Constructor getConstructor (Class[] parameterTypes)
|
public native Constructor getConstructor (Class[] parameterTypes)
|
||||||
throws NoSuchMethodException, SecurityException;
|
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)
|
public native Constructor getDeclaredConstructor (Class[] parameterTypes)
|
||||||
throws NoSuchMethodException, SecurityException;
|
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)
|
public native Field getDeclaredField (String fieldName)
|
||||||
throws NoSuchFieldException, SecurityException;
|
throws NoSuchFieldException, SecurityException;
|
||||||
public native Field[] getDeclaredFields () throws SecurityException;
|
public native Field[] getDeclaredFields () throws SecurityException;
|
||||||
|
@ -69,10 +82,15 @@ public final class Class implements Serializable
|
||||||
throw new NoSuchFieldException(fieldName);
|
throw new NoSuchFieldException(fieldName);
|
||||||
return fld;
|
return fld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private native Field[] _getFields (Field[] result, int offset);
|
||||||
public native Field[] getFields () throws SecurityException;
|
public native Field[] getFields () throws SecurityException;
|
||||||
|
|
||||||
public native Class[] getInterfaces ();
|
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)
|
public native Method getMethod (String methodName, Class[] parameterTypes)
|
||||||
throws NoSuchMethodException, SecurityException;
|
throws NoSuchMethodException, SecurityException;
|
||||||
public native Method[] getMethods () throws SecurityException;
|
public native Method[] getMethods () throws SecurityException;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// natClass.cc - Implementation of java.lang.Class native methods.
|
// 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.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ details. */
|
||||||
#include <java/lang/NullPointerException.h>
|
#include <java/lang/NullPointerException.h>
|
||||||
#include <java/lang/System.h>
|
#include <java/lang/System.h>
|
||||||
#include <java/lang/SecurityManager.h>
|
#include <java/lang/SecurityManager.h>
|
||||||
|
#include <java/lang/StringBuffer.h>
|
||||||
|
|
||||||
#include <java-cpool.h>
|
#include <java-cpool.h>
|
||||||
|
|
||||||
|
@ -55,6 +56,8 @@ extern java::lang::Class ClassClass;
|
||||||
extern java::lang::Class MethodClass;
|
extern java::lang::Class MethodClass;
|
||||||
#define FieldClass _CL_Q44java4lang7reflect5Field
|
#define FieldClass _CL_Q44java4lang7reflect5Field
|
||||||
extern java::lang::Class FieldClass;
|
extern java::lang::Class FieldClass;
|
||||||
|
#define ConstructorClass _CL_Q44java4lang7reflect11Constructor
|
||||||
|
extern java::lang::Class ConstructorClass;
|
||||||
|
|
||||||
// Some constants we use to look up the class initializer.
|
// Some constants we use to look up the class initializer.
|
||||||
static _Jv_Utf8Const *void_signature = _Jv_makeUtf8Const ("()V", 3);
|
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::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 *> *
|
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::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 *> *
|
int i = isPrimitive () ? 0 : method_count;
|
||||||
java::lang::Class::getDeclaredConstructors (void)
|
while (--i >= 0)
|
||||||
{
|
{
|
||||||
JvFail ("java::lang::Class::getDeclaredConstructors not implemented");
|
// 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 *
|
java::lang::reflect::Field *
|
||||||
|
@ -187,18 +258,67 @@ java::lang::Class::getDeclaredFields (void)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
java::lang::reflect::Method *
|
void
|
||||||
java::lang::Class::getDeclaredMethod (jstring, JArray<jclass> *)
|
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 *> *
|
JArray<java::lang::reflect::Method *> *
|
||||||
java::lang::Class::getDeclaredMethods (void)
|
java::lang::Class::getDeclaredMethods (void)
|
||||||
{
|
{
|
||||||
int numMethods = 0;
|
int numMethods = 0;
|
||||||
|
int max = isPrimitive () ? 0 : method_count;
|
||||||
int i;
|
int i;
|
||||||
for (i = method_count; --i >= 0; )
|
for (i = max; --i >= 0; )
|
||||||
{
|
{
|
||||||
_Jv_Method *method = &methods[i];
|
_Jv_Method *method = &methods[i];
|
||||||
if (method->name == NULL
|
if (method->name == NULL
|
||||||
|
@ -211,15 +331,16 @@ java::lang::Class::getDeclaredMethods (void)
|
||||||
= (JArray<java::lang::reflect::Method *> *)
|
= (JArray<java::lang::reflect::Method *> *)
|
||||||
JvNewObjectArray (numMethods, &MethodClass, NULL);
|
JvNewObjectArray (numMethods, &MethodClass, NULL);
|
||||||
java::lang::reflect::Method** mptr = elements (result);
|
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];
|
_Jv_Method *method = &methods[i];
|
||||||
if (method->name == NULL
|
if (method->name == NULL
|
||||||
|| _Jv_equalUtf8Consts (method->name, clinit_name)
|
|| _Jv_equalUtf8Consts (method->name, clinit_name)
|
||||||
|| _Jv_equalUtf8Consts (method->name, init_name))
|
|| _Jv_equalUtf8Consts (method->name, init_name))
|
||||||
continue;
|
continue;
|
||||||
java::lang::reflect::Method* rmethod = new java::lang::reflect::Method ();
|
java::lang::reflect::Method* rmethod
|
||||||
rmethod->offset = (char*) mptr - (char*) elements (result);
|
= new java::lang::reflect::Method ();
|
||||||
|
rmethod->offset = (char*) method - (char*) methods;
|
||||||
rmethod->declaringClass = this;
|
rmethod->declaringClass = this;
|
||||||
*mptr++ = rmethod;
|
*mptr++ = rmethod;
|
||||||
}
|
}
|
||||||
|
@ -258,10 +379,58 @@ java::lang::Class::getDeclaringClass (void)
|
||||||
return NULL; // Placate compiler.
|
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 *> *
|
JArray<java::lang::reflect::Field *> *
|
||||||
java::lang::Class::getFields (void)
|
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> *
|
JArray<jclass> *
|
||||||
|
@ -275,9 +444,30 @@ java::lang::Class::getInterfaces (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
java::lang::reflect::Method *
|
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 *> *
|
JArray<java::lang::reflect::Method *> *
|
||||||
|
@ -494,6 +684,8 @@ java::lang::Class::initializeClass (void)
|
||||||
// Some class-related convenience functions.
|
// 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_Method *
|
||||||
_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
|
_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
|
||||||
_Jv_Utf8Const *signature)
|
_Jv_Utf8Const *signature)
|
||||||
|
@ -507,6 +699,21 @@ _Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
|
||||||
return NULL;
|
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.
|
// NOTE: MCACHE_SIZE should be a power of 2 minus one.
|
||||||
#define MCACHE_SIZE 1023
|
#define MCACHE_SIZE 1023
|
||||||
|
|
||||||
|
@ -553,16 +760,6 @@ void *
|
||||||
_Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
|
_Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
|
||||||
_Jv_Utf8Const *signature)
|
_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);
|
void *ncode = _Jv_FindMethodInCache (klass, name, signature);
|
||||||
if (ncode != 0)
|
if (ncode != 0)
|
||||||
return ncode;
|
return ncode;
|
||||||
|
|
|
@ -28,12 +28,12 @@ public final class Constructor extends AccessibleObject implements Member
|
||||||
if (! (obj instanceof Constructor))
|
if (! (obj instanceof Constructor))
|
||||||
return false;
|
return false;
|
||||||
Constructor c = (Constructor) obj;
|
Constructor c = (Constructor) obj;
|
||||||
return decl_class == c.decl_class && index == c.index;
|
return declaringClass == c.declaringClass && offset == c.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class getDeclaringClass ()
|
public Class getDeclaringClass ()
|
||||||
{
|
{
|
||||||
return decl_class;
|
return declaringClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class[] getExceptionTypes ()
|
public Class[] getExceptionTypes ()
|
||||||
|
@ -41,40 +41,39 @@ public final class Constructor extends AccessibleObject implements Member
|
||||||
return (Class[]) exception_types.clone();
|
return (Class[]) exception_types.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getModifiers ()
|
public native int getModifiers ();
|
||||||
{
|
|
||||||
return modifiers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName ()
|
public String getName ()
|
||||||
{
|
{
|
||||||
return decl_class.getName();
|
return declaringClass.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class[] getParameterTypes ()
|
public Class[] getParameterTypes ()
|
||||||
{
|
{
|
||||||
|
if (parameter_types == null)
|
||||||
|
getType ();
|
||||||
return (Class[]) parameter_types.clone();
|
return (Class[]) parameter_types.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int hashCode ()
|
public int hashCode ()
|
||||||
{
|
{
|
||||||
// FIXME.
|
// FIXME.
|
||||||
return getName().hashCode();
|
return getName().hashCode() + declaringClass.getName().hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: this must be native. Should share implementation with
|
// Update cached values from method descriptor in class.
|
||||||
// Method.invoke.
|
private native void getType ();
|
||||||
public Object newInstance (Object[] args)
|
|
||||||
|
public native Object newInstance (Object[] args)
|
||||||
throws InstantiationException, IllegalAccessException,
|
throws InstantiationException, IllegalAccessException,
|
||||||
IllegalArgumentException, InvocationTargetException
|
IllegalArgumentException, InvocationTargetException;
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString ()
|
public String toString ()
|
||||||
{
|
{
|
||||||
|
if (parameter_types == null)
|
||||||
|
getType ();
|
||||||
StringBuffer b = new StringBuffer ();
|
StringBuffer b = new StringBuffer ();
|
||||||
b.append(Modifier.toString(modifiers));
|
b.append(Modifier.toString(getModifiers()));
|
||||||
b.append(" ");
|
b.append(" ");
|
||||||
b.append(getName());
|
b.append(getName());
|
||||||
b.append("(");
|
b.append("(");
|
||||||
|
@ -88,19 +87,19 @@ public final class Constructor extends AccessibleObject implements Member
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't create these. FIXME.
|
// Can't create these.
|
||||||
private Constructor ()
|
private Constructor ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declaring class.
|
// Declaring class.
|
||||||
private Class decl_class;
|
private Class declaringClass;
|
||||||
|
|
||||||
// Exception types.
|
// Exception types.
|
||||||
private Class[] exception_types;
|
private Class[] exception_types;
|
||||||
// Modifiers.
|
|
||||||
private int modifiers;
|
|
||||||
// Parameter types.
|
// Parameter types.
|
||||||
private Class[] 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;
|
package java.lang.reflect;
|
||||||
|
|
||||||
|
import gnu.gcj.RawData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Tom Tromey <tromey@cygnus.com>
|
* @author Tom Tromey <tromey@cygnus.com>
|
||||||
* @date December 12, 1998
|
* @date December 12, 1998
|
||||||
|
@ -17,7 +19,7 @@ package java.lang.reflect;
|
||||||
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
|
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
|
||||||
* "The Java Language Specification", ISBN 0-201-63451-1
|
* "The Java Language Specification", ISBN 0-201-63451-1
|
||||||
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
|
* 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
|
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();
|
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)
|
public native Object invoke (Object obj, Object[] args)
|
||||||
throws IllegalAccessException, IllegalArgumentException,
|
throws IllegalAccessException, IllegalArgumentException,
|
||||||
InvocationTargetException;
|
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.
|
// 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.
|
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
|
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
// This is about 90% done. Search for FIXME to see what remains.
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <gcj/cni.h>
|
#include <gcj/cni.h>
|
||||||
#include <jvm.h>
|
#include <jvm.h>
|
||||||
|
|
||||||
#include <java/lang/reflect/Method.h>
|
#include <java/lang/reflect/Method.h>
|
||||||
|
#include <java/lang/reflect/Constructor.h>
|
||||||
#include <java/lang/reflect/InvocationTargetException.h>
|
#include <java/lang/reflect/InvocationTargetException.h>
|
||||||
#include <java/lang/reflect/Modifier.h>
|
#include <java/lang/reflect/Modifier.h>
|
||||||
|
|
||||||
|
@ -32,14 +31,15 @@ details. */
|
||||||
#include <java/lang/NullPointerException.h>
|
#include <java/lang/NullPointerException.h>
|
||||||
#include <java/lang/Class.h>
|
#include <java/lang/Class.h>
|
||||||
#include <gcj/method.h>
|
#include <gcj/method.h>
|
||||||
|
#include <gnu/gcj/RawData.h>
|
||||||
|
|
||||||
|
#define ObjectClass _CL_Q34java4lang6Object
|
||||||
|
extern java::lang::Class ObjectClass;
|
||||||
#define ClassClass _CL_Q34java4lang5Class
|
#define ClassClass _CL_Q34java4lang5Class
|
||||||
extern java::lang::Class ClassClass;
|
extern java::lang::Class ClassClass;
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
#include <ffi.h>
|
#include <ffi.h>
|
||||||
|
|
||||||
#define VoidClass _CL_Q34java4lang4Void
|
#define VoidClass _CL_Q34java4lang4Void
|
||||||
|
@ -145,147 +145,46 @@ get_ffi_type (jclass klass)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: the body of this method should be a separate function so
|
// Actually perform an FFI call.
|
||||||
// that Constructor can use it too.
|
void
|
||||||
jobject
|
java::lang::reflect::Method::hack_call (gnu::gcj::RawData *rcif,
|
||||||
java::lang::reflect::Method::invoke (jobject obj,
|
gnu::gcj::RawData *rmethod,
|
||||||
jobjectArray args)
|
gnu::gcj::RawData *rret_value,
|
||||||
|
gnu::gcj::RawData *rvalues)
|
||||||
{
|
{
|
||||||
// FIXME: we need to be a friend of Class here.
|
ffi_cif *cif = (ffi_cif *) rcif;
|
||||||
_Jv_Method *meth = decl_class->methods[index];
|
void (*method) (...) = (void (*) (...)) rmethod;
|
||||||
if (! java::lang::reflect::Modifier::isStatic(modifiers))
|
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;
|
jclass k = obj ? obj->getClass() : NULL;
|
||||||
if (! obj || ! decl_class->isAssignableFrom(k))
|
if (! obj)
|
||||||
JvThrow (new java::lang::NullPointerException);
|
JvThrow (new java::lang::NullPointerException);
|
||||||
|
if (! declaringClass->isAssignableFrom(k))
|
||||||
|
JvThrow (new java::lang::IllegalArgumentException);
|
||||||
// FIXME: access checks.
|
// 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.
|
return _Jv_CallNonvirtualMethodA (obj, return_type, meth, false,
|
||||||
|
parameter_types, args);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* 0 */
|
|
||||||
|
|
||||||
jobject
|
|
||||||
java::lang::reflect::Method::invoke (jobject, jobjectArray)
|
|
||||||
{
|
|
||||||
JvFail ("not enabled yet");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* 0 */
|
|
||||||
|
|
||||||
jint
|
jint
|
||||||
java::lang::reflect::Method::getModifiers ()
|
java::lang::reflect::Method::getModifiers ()
|
||||||
{
|
{
|
||||||
|
@ -305,7 +204,20 @@ java::lang::reflect::Method::getName ()
|
||||||
void
|
void
|
||||||
java::lang::reflect::Method::getType ()
|
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();
|
java::lang::ClassLoader *loader = declaringClass->getClassLoader();
|
||||||
char *ptr = sig->data;
|
char *ptr = sig->data;
|
||||||
int numArgs = 0;
|
int numArgs = 0;
|
||||||
|
@ -355,7 +267,7 @@ java::lang::reflect::Method::getType ()
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
case ')':
|
case ')':
|
||||||
argPtr = &return_type;
|
argPtr = return_type_out;
|
||||||
continue;
|
continue;
|
||||||
case '(':
|
case '(':
|
||||||
continue;
|
continue;
|
||||||
|
@ -381,7 +293,187 @@ java::lang::reflect::Method::getType ()
|
||||||
// FIXME: 2'nd argument should be "current loader"
|
// FIXME: 2'nd argument should be "current loader"
|
||||||
while (--num_arrays >= 0)
|
while (--num_arrays >= 0)
|
||||||
type = _Jv_FindArrayClass (type, 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 <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#pragma implementation "gcj/array.h"
|
|
||||||
|
|
||||||
#include <gcj/cni.h>
|
#include <gcj/cni.h>
|
||||||
#include <jvm.h>
|
#include <jvm.h>
|
||||||
#include <java-signal.h>
|
#include <java-signal.h>
|
||||||
|
@ -143,6 +141,26 @@ _Jv_equal (Utf8Const* a, jstring str, jint hash)
|
||||||
return true;
|
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. */
|
/* Count the number of Unicode chars encoded in a given Ut8 string. */
|
||||||
int
|
int
|
||||||
_Jv_strLengthUtf8(char* str, int len)
|
_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
|
/** FIXME: this is a terribly inefficient algorithm! It would improve
|
||||||
things if compiled classes to know vtable offset, and _Jv_Method had
|
things if compiled classes to know vtable offset, and _Jv_Method had
|
||||||
a field for this.
|
a field for this.
|
||||||
|
|
|
@ -76,12 +76,14 @@ DLLTOOL = @DLLTOOL@
|
||||||
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
|
||||||
EXCEPTIONSPEC = @EXCEPTIONSPEC@
|
EXCEPTIONSPEC = @EXCEPTIONSPEC@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
|
FORCELIBGCCSPEC = @FORCELIBGCCSPEC@
|
||||||
GCDEPS = @GCDEPS@
|
GCDEPS = @GCDEPS@
|
||||||
GCINCS = @GCINCS@
|
GCINCS = @GCINCS@
|
||||||
GCLIBS = @GCLIBS@
|
GCLIBS = @GCLIBS@
|
||||||
GCOBJS = @GCOBJS@
|
GCOBJS = @GCOBJS@
|
||||||
GCSPEC = @GCSPEC@
|
GCSPEC = @GCSPEC@
|
||||||
LD = @LD@
|
LD = @LD@
|
||||||
|
LIBDATASTARTSPEC = @LIBDATASTARTSPEC@
|
||||||
LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@
|
LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@
|
||||||
LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@
|
LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@
|
||||||
LIBGCJ_JAVAFLAGS = @LIBGCJ_JAVAFLAGS@
|
LIBGCJ_JAVAFLAGS = @LIBGCJ_JAVAFLAGS@
|
||||||
|
@ -90,7 +92,6 @@ LN_S = @LN_S@
|
||||||
MAINT = @MAINT@
|
MAINT = @MAINT@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
NM = @NM@
|
NM = @NM@
|
||||||
OBJDUMP = @OBJDUMP@
|
|
||||||
PACKAGE = @PACKAGE@
|
PACKAGE = @PACKAGE@
|
||||||
PERL = @PERL@
|
PERL = @PERL@
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
|
@ -100,6 +101,7 @@ THREADINCS = @THREADINCS@
|
||||||
THREADLIBS = @THREADLIBS@
|
THREADLIBS = @THREADLIBS@
|
||||||
THREADOBJS = @THREADOBJS@
|
THREADOBJS = @THREADOBJS@
|
||||||
THREADSPEC = @THREADSPEC@
|
THREADSPEC = @THREADSPEC@
|
||||||
|
USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
|
||||||
VERSION = @VERSION@
|
VERSION = @VERSION@
|
||||||
ZDEPS = @ZDEPS@
|
ZDEPS = @ZDEPS@
|
||||||
ZINCS = @ZINCS@
|
ZINCS = @ZINCS@
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue