Commit 58eb6e7c by Anthony Green

[multiple changes]

1999-08-09  Anthony Green  <green@cygnus.com>

        * gij.cc: New file.

        * include/config.h.in: Rebuilt.
        * acconfig.h: Add INTERPRETER.

        * configure: Rebuilt.

        * Makefile.in: Rebuilt.
        * Makefile.am (libffi_files): Identify the libffi object files for
        inclusion in libgcj.
        (LIBFFIINCS): Define.

        * interpret.cc (gnu::gcj::runtime::MethodInvocation::continue1):
        Dummy definition for configurations without an interpreter.

        * java/net/natPlainSocketImpl.cc (getOption): Disamiguate call to
        java::lang::Boolean constructor.

        * include/java-interp.h: Always include java-cpool.h.

        * java/lang/natClassLoader.cc (getVMClassLoader0): Always return 0
        when INTERPRETER not defined.

        * java/lang/Class.h (finalize): Define.

        * gnu/gcj/util/path/DirectoryPathEntry.java (getURL): Catch
        IOException from File.getCanonicalPath.
        (getStream): Likewise.

        * NEWS: More news.
        * THANKS: More thanks.

1999-08-09  Kresten Krab Thorup  <krab@gnu.org>

        * resolve.cc (get_ffi_type_from_signature): Generate uint16 for
        jchar type.
        (_Jv_PrepareClass): Allow non-abstract classes to
        have abstract subclasses.
        (_Jv_ResolvePoolEntry): Revert subclass check for protected
        fields and methods.
        * interpret.cc (continue1/perform_invoke): Don't sign extend
        uint16 return val.
        (continue1/lshl,lshr): Push long, not int.
        (continue1/ulshr): Use UINT64, not long long.
        * defineclass.cc (handleFieldsEnd): Handle case when all fields
        are static.
        * java/lang/natClass.cc (forName): Add call to _Jv_InitClass.
        * java/lang/FirstThread.java (run): Add top-level exception
        handler.
        (run0): Renamed from run.

1999-08-08  Kresten Krab Thorup  <krab@gnu.org>

        * configure.in (--with-interpreter): Added.
        * include/config.h.in (INTERPRETER): Added.

        * java/lang/ClassLoader.java: File replaced.
        * java/lang/VMClassLoader.java: New file.
        * java/lang/natClassLoader.cc: New file.
        * gnu/gcj/runtime/MethodInvocation.java: New file.
        * gnu/gcj/util/path/SearchPath.java: New file.
        * gnu/gcj/util/path/PathEntry.java: New file.
        * gnu/gcj/util/path/DirectoryPathEntry.java: New file.
        * gnu/gcj/util/path/ZipPathEntry.java: New file.
        * gnu/gcj/util/path/URLPathEntry.java: New file.
        * gnu/gcj/util/path/CacheEntry.java: New file.
        * include/java-interp.h: New file.
        * include/java-cpool.h: New file.
        * include/java-insns.h: New file.
        * defineclass.cc: New file.
        * interpret.cc: New file.
        * resolve.cc: New file.

        * java/lang/natClass.cc (loaded_classes, _Jv_RegisterClass,
        _Jv_RegisterClasses, _Jv_FindClassInCache, _Jv_FindClass,
        _Jv_NewClass, _Jv_FindArrayClass): Moved to natClassLoader.cc.
        (finalize): New.
        (STATE_NOTHING, STATE_RESOLVED, STATE_IN_PROGRESS, STATE_DONE,
        STATE_ERROR): Moved to java/lang/Class.h and renamed with JV_
        prefix.
        (initializeClass): Use new JV_ prefixed names.  Also, call
        ClassLoader::resolveClass instead of _Jv_ResolveClass.

        * java/lang/Class.h (JV_STATE_PRELOADING, JV_STATE_LOADING,
        JV_STATE_LOADED, JV_STATE_COMPILED, JV_STATE_PREPARED,
        JV_STATE_LINKED): New.
        (_Jv_WaitForState, _Jv_RegisterInitiatingLoader,
        _Jv_UnregisterClass, _Jv_InternClassStrings): New friends.
        (_Jv_IsInterpretedClass, _Jv_InitField, _Jv_LookupDeclaredMethod,
        _Jv_DetermineVTableIndex, _Jv_ResolvePoolEntry, _Jv_PrepareClass,
        _Jv_ClassReader, _Jv_InterpClass, _Jv_InterpMethod,
        _Jv_InterpMethodInvocation): New friends for interpreter.
        (finalize): New.
        (CONSTANT_Class, CONSTANT_String, etc.): Moved to
        include/java-cpool.h and renamed with JV_ prefix.

        * include/jvm.h (_Jv_makeUtf8Const, _Jv_makeUtf8TypeConst): New
        decls.
        (_Jv_UnregisterClass): New decl.

        * java/lang/natClassLoader.cc (_Jv_FindArrayClass): Added
        class loader argument.
        (_Jv_FindClass): Use class loader.

        * prims.cc (_Jv_makeUtf8Const): New function.
        (_Jv_NewObjectArray): Change use of _Jv_FindArrayClass.
        (_Jv_NewPrimArray): Ditto.
        (_Jv_FindClassFromSignature): Ditto.
        * java/lang/reflect/natArray.cc (newInstance): Ditto.
        * java/lang/reflect/natMethod.cc (getType): Ditto.

        * include/java-field.h (_Jv_Field::isRef): Make robust for
        non-resolved contexts.

        * boehm.cc (_Jv_MarkObj): Mark interpreter-related fields.
        Also, don't mark class->next field.

        * java/lang/VirtualMachineError.java: Added FIXME note.

        * configure.in (INTERPSPEC): New spec.
        * libgcj.spec.in: Added INTERPSPEC.
        * Makefile.am: Added gcjh friends for java/lang/VMClassLoader and
        gnu/gcj/runtime/MethodInvocation.
        (libgcj_la_SOURCES): Added resolve.cc defineclass.cc interpret.cc.
        (ordinary_java_source_files): Added above mentioned java classes.

        * configure: Rebuilt.
        * Makefile.in: Rebuilt.

From-SVN: r28597
parent 63e5e3e0
1999-08-09 Anthony Green <green@cygnus.com>
* gij.cc: New file.
* include/config.h.in: Rebuilt.
* acconfig.h: Add INTERPRETER.
* Makefile.in: Rebuilt.
* Makefile.am (libffi_files): Identify the libffi object files for
inclusion in libgcj.
(LIBFFIINCS): Define.
* interpret.cc (gnu::gcj::runtime::MethodInvocation::continue1):
Dummy definition for configurations without an interpreter.
* java/net/natPlainSocketImpl.cc (getOption): Disamiguate call to
java::lang::Boolean constructor.
* include/java-interp.h: Always include java-cpool.h.
* java/lang/natClassLoader.cc (getVMClassLoader0): Always return 0
when INTERPRETER not defined.
* java/lang/Class.h (finalize): Define.
* gnu/gcj/util/path/DirectoryPathEntry.java (getURL): Catch
IOException from File.getCanonicalPath.
(getStream): Likewise.
* NEWS: More news.
* THANKS: More thanks.
1999-08-09 Kresten Krab Thorup <krab@gnu.org>
* resolve.cc (get_ffi_type_from_signature): Generate uint16 for
jchar type.
(_Jv_PrepareClass): Allow non-abstract classes to
have abstract subclasses.
(_Jv_ResolvePoolEntry): Revert subclass check for protected
fields and methods.
* interpret.cc (continue1/perform_invoke): Don't sign extend
uint16 return val.
(continue1/lshl,lshr): Push long, not int.
(continue1/ulshr): Use UINT64, not long long.
* defineclass.cc (handleFieldsEnd): Handle case when all fields
are static.
* java/lang/natClass.cc (forName): Add call to _Jv_InitClass.
* java/lang/FirstThread.java (run): Add top-level exception
handler.
(run0): Renamed from run.
1999-08-08 Kresten Krab Thorup <krab@gnu.org>
* configure.in (--with-interpreter): Added.
* include/config.h.in (INTERPRETER): Added.
* java/lang/ClassLoader.java: File replaced.
* java/lang/VMClassLoader.java: New file.
* java/lang/natClassLoader.cc: New file.
* gnu/gcj/runtime/MethodInvocation.java: New file.
* gnu/gcj/util/path/SearchPath.java: New file.
* gnu/gcj/util/path/PathEntry.java: New file.
* gnu/gcj/util/path/DirectoryPathEntry.java: New file.
* gnu/gcj/util/path/ZipPathEntry.java: New file.
* gnu/gcj/util/path/URLPathEntry.java: New file.
* gnu/gcj/util/path/CacheEntry.java: New file.
* include/java-interp.h: New file.
* include/java-cpool.h: New file.
* include/java-insns.h: New file.
* defineclass.cc: New file.
* interpret.cc: New file.
* resolve.cc: New file.
* java/lang/natClass.cc (loaded_classes, _Jv_RegisterClass,
_Jv_RegisterClasses, _Jv_FindClassInCache, _Jv_FindClass,
_Jv_NewClass, _Jv_FindArrayClass): Moved to natClassLoader.cc.
(finalize): New.
(STATE_NOTHING, STATE_RESOLVED, STATE_IN_PROGRESS, STATE_DONE,
STATE_ERROR): Moved to java/lang/Class.h and renamed with JV_
prefix.
(initializeClass): Use new JV_ prefixed names. Also, call
ClassLoader::resolveClass instead of _Jv_ResolveClass.
* java/lang/Class.h (JV_STATE_PRELOADING, JV_STATE_LOADING,
JV_STATE_LOADED, JV_STATE_COMPILED, JV_STATE_PREPARED,
JV_STATE_LINKED): New.
(_Jv_WaitForState, _Jv_RegisterInitiatingLoader,
_Jv_UnregisterClass, _Jv_InternClassStrings): New friends.
(_Jv_IsInterpretedClass, _Jv_InitField, _Jv_LookupDeclaredMethod,
_Jv_DetermineVTableIndex, _Jv_ResolvePoolEntry, _Jv_PrepareClass,
_Jv_ClassReader, _Jv_InterpClass, _Jv_InterpMethod,
_Jv_InterpMethodInvocation): New friends for interpreter.
(finalize): New.
(CONSTANT_Class, CONSTANT_String, etc.): Moved to
include/java-cpool.h and renamed with JV_ prefix.
* include/jvm.h (_Jv_makeUtf8Const, _Jv_makeUtf8TypeConst): New
decls.
(_Jv_UnregisterClass): New decl.
* java/lang/natClassLoader.cc (_Jv_FindArrayClass): Added
class loader argument.
(_Jv_FindClass): Use class loader.
* prims.cc (_Jv_makeUtf8Const): New function.
(_Jv_NewObjectArray): Change use of _Jv_FindArrayClass.
(_Jv_NewPrimArray): Ditto.
(_Jv_FindClassFromSignature): Ditto.
* java/lang/reflect/natArray.cc (newInstance): Ditto.
* java/lang/reflect/natMethod.cc (getType): Ditto.
* include/java-field.h (_Jv_Field::isRef): Make robust for
non-resolved contexts.
* boehm.cc (_Jv_MarkObj): Mark interpreter-related fields.
Also, don't mark class->next field.
* java/lang/VirtualMachineError.java: Added FIXME note.
* configure.in (INTERPSPEC): New spec.
* libgcj.spec.in: Added INTERPSPEC.
* Makefile.am: Added gcjh friends for java/lang/VMClassLoader and
gnu/gcj/runtime/MethodInvocation.
(libgcj_la_SOURCES): Added resolve.cc defineclass.cc interpret.cc.
(ordinary_java_source_files): Added above mentioned java classes.
* configure: Rebuilt.
* Makefile.in: Rebuilt.
1999-08-06 Tom Tromey <tromey@cygnus.com> 1999-08-06 Tom Tromey <tromey@cygnus.com>
* configure: Rebuilt. * configure: Rebuilt.
......
...@@ -27,7 +27,7 @@ data_DATA = libgcj.zip ...@@ -27,7 +27,7 @@ data_DATA = libgcj.zip
## For now, only on native systems. ## For now, only on native systems.
if NATIVE if NATIVE
bin_PROGRAMS = jv-convert bin_PROGRAMS = jv-convert gij
endif endif
## ################################################################ ## ################################################################
...@@ -77,8 +77,10 @@ endif ...@@ -77,8 +77,10 @@ endif
JCFLAGS = -g JCFLAGS = -g
JC1FLAGS = -g @LIBGCJ_JAVAFLAGS@ JC1FLAGS = -g @LIBGCJ_JAVAFLAGS@
LIBFFIINCS = -I$(top_srcdir)/../libffi/include -I../libffi/include
INCLUDES = -Iinclude -I$(top_srcdir)/include $(GCINCS) $(THREADINCS) \ INCLUDES = -Iinclude -I$(top_srcdir)/include $(GCINCS) $(THREADINCS) \
$(EH_COMMON_INCLUDE) $(ZINCS) $(EH_COMMON_INCLUDE) $(ZINCS) $(LIBFFIINCS)
DIVIDESPEC = @DIVIDESPEC@ DIVIDESPEC = @DIVIDESPEC@
...@@ -97,13 +99,17 @@ c_files = $(c_source_files:.c=.lo) ...@@ -97,13 +99,17 @@ c_files = $(c_source_files:.c=.lo)
javao_files = $(java_source_files:.java=.lo) \ javao_files = $(java_source_files:.java=.lo) \
$(built_java_source_files:.java=.lo) $(built_java_source_files:.java=.lo)
libgcj_la_SOURCES = prims.cc jni.cc exception.cc ## Extract the libffi object file names.
libffi_files = `$(AR) t ../libffi/.libs/libffi.a 2>/dev/null | sed 's/\.o/\.lo/g' | sed 's/^/..\/libffi\//g'`
libgcj_la_SOURCES = prims.cc jni.cc exception.cc \
resolve.cc defineclass.cc interpret.cc
EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \ EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \
$(c_source_files) $(java_source_files) $(built_java_source_files) $(c_source_files) $(java_source_files) $(built_java_source_files)
libgcj_la_DEPENDENCIES = libgcj.zip $(javao_files) $(nat_files) \ libgcj_la_DEPENDENCIES = libgcj.zip $(javao_files) $(nat_files) \
$(c_files) $(GCOBJS) $(THREADOBJS) $(c_files) $(GCOBJS) $(THREADOBJS)
libgcj_la_LIBADD = $(javao_files) $(nat_files) $(c_files) $(GCOBJS) \ libgcj_la_LIBADD = $(javao_files) $(nat_files) $(c_files) $(GCOBJS) \
$(THREADOBJS) $(THREADOBJS) $(libffi_files)
libgcj_la_LDFLAGS = -rpath $(toolexeclibdir) \ libgcj_la_LDFLAGS = -rpath $(toolexeclibdir) \
## The mysterious backslash is consumed by make. ## The mysterious backslash is consumed by make.
-version-info `grep -v '^\#' $(srcdir)/libtool-version` -version-info `grep -v '^\#' $(srcdir)/libtool-version`
...@@ -230,6 +236,16 @@ java/lang/reflect/Method.h: java/lang/reflect/Method.class libgcj.zip ...@@ -230,6 +236,16 @@ java/lang/reflect/Method.h: java/lang/reflect/Method.class libgcj.zip
-friend 'java::lang::Class;' \ -friend 'java::lang::Class;' \
$(basename $<) $(basename $<)
java/lang/VMClassLoader.h: java/lang/VMClassLoader.class libgcj.zip
$(GCJH) -classpath $(top_builddir) \
-friend 'java::lang::ClassLoader;' \
$(basename $<)
gnu/gcj/runtime/MethodInvocation.h: gnu/gcj/runtime/MethodInvocation.class libgcj.zip
$(GCJH) -classpath $(top_builddir) \
-friend 'class _Jv_InterpMethod;' \
$(basename $<)
## ################################################################ ## ################################################################
...@@ -299,6 +315,26 @@ jv_convert_LDADD = $(convert_source_files:.java=.lo) libgcj.la \ ...@@ -299,6 +315,26 @@ jv_convert_LDADD = $(convert_source_files:.java=.lo) libgcj.la \
jv_convert_DEPENDENCIES = $(convert_source_files:.java=.lo) \ jv_convert_DEPENDENCIES = $(convert_source_files:.java=.lo) \
$(GCDEPS) $(THREADDEPS) $(ZDEPS) libgcj.la libgcj.spec $(GCDEPS) $(THREADDEPS) $(ZDEPS) libgcj.la libgcj.spec
gij_SOURCES =
EXTRA_gij_SOURCES = gij.cc
## We need -nodefaultlibs because we want to avoid gcj's `-lgcj'. We
## need this because we are explicitly using libtool to link using the
## `.la' file.
gij_LDFLAGS = -rpath $(toolexeclibdir)
gij_LINK = $(LIBTOOL) --mode=link $(GCJ) $(JC1FLAGS) $(LDFLAGS) \
-o gij
## We explicitly link in the libraries we need. This way we don't
## need -nodefaultlibs, so we can still rely on gcj picking up the
## system libraries we need (via the specs file).
## We need the -L so that gcj can find libgcj with `-lgcj'.
## FIXME: should be _libs on some systems.
gij_LDADD = gij.lo libgcj.la \
$(GCLIBS) $(THREADLIBS) $(ZLIBS) -L$(here)/.libs
## Depend on the spec file to make sure it is up to date before
## linking this program.
gij_DEPENDENCIES = gij.lo \
$(GCDEPS) $(THREADDEPS) $(ZDEPS) libgcj.la libgcj.spec
# The Unicode consortium does not permit re-distributing the file JIS0201.TXT. # The Unicode consortium does not permit re-distributing the file JIS0201.TXT.
# You can get it from ftp://ftp.unicode.org/Public/MAPPINGS/EASTASIA/JIS/. # You can get it from ftp://ftp.unicode.org/Public/MAPPINGS/EASTASIA/JIS/.
...@@ -444,6 +480,13 @@ built_java_source_files = java/lang/ConcreteProcess.java ...@@ -444,6 +480,13 @@ built_java_source_files = java/lang/ConcreteProcess.java
## convert_source_files. If the .java file has a hand-maintained ## convert_source_files. If the .java file has a hand-maintained
## header, please list it in special_java_source_files. ## header, please list it in special_java_source_files.
ordinary_java_source_files = $(convert_source_files) \ ordinary_java_source_files = $(convert_source_files) \
gnu/gcj/runtime/MethodInvocation.java \
gnu/gcj/util/path/SearchPath.java \
gnu/gcj/util/path/PathEntry.java \
gnu/gcj/util/path/DirectoryPathEntry.java \
gnu/gcj/util/path/ZipPathEntry.java \
gnu/gcj/util/path/URLPathEntry.java \
gnu/gcj/util/path/CacheEntry.java \
gnu/gcj/text/BaseBreakIterator.java \ gnu/gcj/text/BaseBreakIterator.java \
gnu/gcj/text/CharacterBreakIterator.java \ gnu/gcj/text/CharacterBreakIterator.java \
gnu/gcj/text/LineBreakIterator.java \ gnu/gcj/text/LineBreakIterator.java \
...@@ -522,6 +565,7 @@ java/lang/ClassCastException.java \ ...@@ -522,6 +565,7 @@ java/lang/ClassCastException.java \
java/lang/ClassCircularityError.java \ java/lang/ClassCircularityError.java \
java/lang/ClassFormatError.java \ java/lang/ClassFormatError.java \
java/lang/ClassLoader.java \ java/lang/ClassLoader.java \
java/lang/VMClassLoader.java \
java/lang/ClassNotFoundException.java \ java/lang/ClassNotFoundException.java \
java/lang/CloneNotSupportedException.java \ java/lang/CloneNotSupportedException.java \
java/lang/Cloneable.java \ java/lang/Cloneable.java \
...@@ -719,6 +763,7 @@ java/io/natFile.cc \ ...@@ -719,6 +763,7 @@ java/io/natFile.cc \
java/io/natFileDescriptor.cc \ java/io/natFileDescriptor.cc \
java/lang/natCharacter.cc \ java/lang/natCharacter.cc \
java/lang/natClass.cc \ java/lang/natClass.cc \
java/lang/natClassLoader.cc \
java/lang/natConcreteProcess.cc \ java/lang/natConcreteProcess.cc \
java/lang/natDouble.cc \ java/lang/natDouble.cc \
java/lang/natFirstThread.cc \ java/lang/natFirstThread.cc \
......
...@@ -78,6 +78,7 @@ GCINCS = @GCINCS@ ...@@ -78,6 +78,7 @@ GCINCS = @GCINCS@
GCLIBS = @GCLIBS@ GCLIBS = @GCLIBS@
GCOBJS = @GCOBJS@ GCOBJS = @GCOBJS@
GCSPEC = @GCSPEC@ GCSPEC = @GCSPEC@
INTERPSPEC = @INTERPSPEC@
LD = @LD@ LD = @LD@
LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@ LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@
LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@ LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@
...@@ -120,7 +121,7 @@ toolexeclib_DATA = libgcj.spec ...@@ -120,7 +121,7 @@ toolexeclib_DATA = libgcj.spec
data_DATA = libgcj.zip data_DATA = libgcj.zip
@NATIVE_TRUE@bin_PROGRAMS = \ @NATIVE_TRUE@bin_PROGRAMS = \
@NATIVE_TRUE@jv-convert @NATIVE_TRUE@jv-convert gij
@CANADIAN_TRUE@@NULL_TARGET_TRUE@GCJ = \ @CANADIAN_TRUE@@NULL_TARGET_TRUE@GCJ = \
@CANADIAN_TRUE@@NULL_TARGET_TRUE@gcj @CANADIAN_TRUE@@NULL_TARGET_TRUE@gcj
@CANADIAN_TRUE@@NULL_TARGET_FALSE@GCJ = \ @CANADIAN_TRUE@@NULL_TARGET_FALSE@GCJ = \
...@@ -156,8 +157,10 @@ AM_CXXFLAGS = -fno-rtti -fvtable-thunks @LIBGCJ_CXXFLAGS@ $(WARNINGS) ...@@ -156,8 +157,10 @@ AM_CXXFLAGS = -fno-rtti -fvtable-thunks @LIBGCJ_CXXFLAGS@ $(WARNINGS)
JCFLAGS = -g JCFLAGS = -g
JC1FLAGS = -g @LIBGCJ_JAVAFLAGS@ JC1FLAGS = -g @LIBGCJ_JAVAFLAGS@
LIBFFIINCS = -I$(top_srcdir)/../libffi/include -I../libffi/include
INCLUDES = -Iinclude -I$(top_srcdir)/include $(GCINCS) $(THREADINCS) \ INCLUDES = -Iinclude -I$(top_srcdir)/include $(GCINCS) $(THREADINCS) \
$(EH_COMMON_INCLUDE) $(ZINCS) $(EH_COMMON_INCLUDE) $(ZINCS) $(LIBFFIINCS)
DIVIDESPEC = @DIVIDESPEC@ DIVIDESPEC = @DIVIDESPEC@
...@@ -168,7 +171,11 @@ javao_files = $(java_source_files:.java=.lo) \ ...@@ -168,7 +171,11 @@ javao_files = $(java_source_files:.java=.lo) \
$(built_java_source_files:.java=.lo) $(built_java_source_files:.java=.lo)
libgcj_la_SOURCES = prims.cc jni.cc exception.cc libffi_files = `$(AR) t ../libffi/.libs/libffi.a 2>/dev/null | sed 's/\.o/\.lo/g' | sed 's/^/..\/libffi\//g'`
libgcj_la_SOURCES = prims.cc jni.cc exception.cc \
resolve.cc defineclass.cc interpret.cc
EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \ EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \
$(c_source_files) $(java_source_files) $(built_java_source_files) $(c_source_files) $(java_source_files) $(built_java_source_files)
...@@ -176,7 +183,7 @@ libgcj_la_DEPENDENCIES = libgcj.zip $(javao_files) $(nat_files) \ ...@@ -176,7 +183,7 @@ libgcj_la_DEPENDENCIES = libgcj.zip $(javao_files) $(nat_files) \
$(c_files) $(GCOBJS) $(THREADOBJS) $(c_files) $(GCOBJS) $(THREADOBJS)
libgcj_la_LIBADD = $(javao_files) $(nat_files) $(c_files) $(GCOBJS) \ libgcj_la_LIBADD = $(javao_files) $(nat_files) $(c_files) $(GCOBJS) \
$(THREADOBJS) $(THREADOBJS) $(libffi_files)
libgcj_la_LDFLAGS = -rpath $(toolexeclibdir) \ libgcj_la_LDFLAGS = -rpath $(toolexeclibdir) \
-version-info `grep -v '^\#' $(srcdir)/libtool-version` -version-info `grep -v '^\#' $(srcdir)/libtool-version`
...@@ -217,6 +224,19 @@ jv_convert_DEPENDENCIES = $(convert_source_files:.java=.lo) \ ...@@ -217,6 +224,19 @@ jv_convert_DEPENDENCIES = $(convert_source_files:.java=.lo) \
$(GCDEPS) $(THREADDEPS) $(ZDEPS) libgcj.la libgcj.spec $(GCDEPS) $(THREADDEPS) $(ZDEPS) libgcj.la libgcj.spec
gij_SOURCES =
EXTRA_gij_SOURCES = gij.cc
gij_LDFLAGS = -rpath $(toolexeclibdir)
gij_LINK = $(LIBTOOL) --mode=link $(GCJ) $(JC1FLAGS) $(LDFLAGS) \
-o gij
gij_LDADD = gij.lo libgcj.la \
$(GCLIBS) $(THREADLIBS) $(ZLIBS) -L$(here)/.libs
gij_DEPENDENCIES = gij.lo \
$(GCDEPS) $(THREADDEPS) $(ZDEPS) libgcj.la libgcj.spec
gen_from_JIS_SOURCES = gen_from_JIS_SOURCES =
EXTRA_gen_from_JIS_SOURCES = $(srcdir)/$(CONVERT_DIR)/gen-from-JIS.c \ EXTRA_gen_from_JIS_SOURCES = $(srcdir)/$(CONVERT_DIR)/gen-from-JIS.c \
$(srcdir)/$(CONVERT_DIR)/make-trie.c \ $(srcdir)/$(CONVERT_DIR)/make-trie.c \
...@@ -294,6 +314,13 @@ java/awt/peer/WindowPeer.java ...@@ -294,6 +314,13 @@ java/awt/peer/WindowPeer.java
built_java_source_files = java/lang/ConcreteProcess.java built_java_source_files = java/lang/ConcreteProcess.java
ordinary_java_source_files = $(convert_source_files) \ ordinary_java_source_files = $(convert_source_files) \
gnu/gcj/runtime/MethodInvocation.java \
gnu/gcj/util/path/SearchPath.java \
gnu/gcj/util/path/PathEntry.java \
gnu/gcj/util/path/DirectoryPathEntry.java \
gnu/gcj/util/path/ZipPathEntry.java \
gnu/gcj/util/path/URLPathEntry.java \
gnu/gcj/util/path/CacheEntry.java \
gnu/gcj/text/BaseBreakIterator.java \ gnu/gcj/text/BaseBreakIterator.java \
gnu/gcj/text/CharacterBreakIterator.java \ gnu/gcj/text/CharacterBreakIterator.java \
gnu/gcj/text/LineBreakIterator.java \ gnu/gcj/text/LineBreakIterator.java \
...@@ -372,6 +399,7 @@ java/lang/ClassCastException.java \ ...@@ -372,6 +399,7 @@ java/lang/ClassCastException.java \
java/lang/ClassCircularityError.java \ java/lang/ClassCircularityError.java \
java/lang/ClassFormatError.java \ java/lang/ClassFormatError.java \
java/lang/ClassLoader.java \ java/lang/ClassLoader.java \
java/lang/VMClassLoader.java \
java/lang/ClassNotFoundException.java \ java/lang/ClassNotFoundException.java \
java/lang/CloneNotSupportedException.java \ java/lang/CloneNotSupportedException.java \
java/lang/Cloneable.java \ java/lang/Cloneable.java \
...@@ -569,6 +597,7 @@ java/io/natFile.cc \ ...@@ -569,6 +597,7 @@ java/io/natFile.cc \
java/io/natFileDescriptor.cc \ java/io/natFileDescriptor.cc \
java/lang/natCharacter.cc \ java/lang/natCharacter.cc \
java/lang/natClass.cc \ java/lang/natClass.cc \
java/lang/natClassLoader.cc \
java/lang/natConcreteProcess.cc \ java/lang/natConcreteProcess.cc \
java/lang/natDouble.cc \ java/lang/natDouble.cc \
java/lang/natFirstThread.cc \ java/lang/natFirstThread.cc \
...@@ -655,13 +684,15 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I./include ...@@ -655,13 +684,15 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I./include
CPPFLAGS = @CPPFLAGS@ CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
LIBS = @LIBS@ LIBS = @LIBS@
libgcj_la_OBJECTS = prims.lo jni.lo exception.lo libgcj_la_OBJECTS = prims.lo jni.lo exception.lo resolve.lo \
@NATIVE_TRUE@bin_PROGRAMS = jv-convert$(EXEEXT) defineclass.lo interpret.lo
@NATIVE_TRUE@bin_PROGRAMS = jv-convert$(EXEEXT) gij$(EXEEXT)
@NATIVE_TRUE@@MAINTAINER_MODE_TRUE@noinst_PROGRAMS = \ @NATIVE_TRUE@@MAINTAINER_MODE_TRUE@noinst_PROGRAMS = \
@NATIVE_TRUE@@MAINTAINER_MODE_TRUE@gen-from-JIS$(EXEEXT) @NATIVE_TRUE@@MAINTAINER_MODE_TRUE@gen-from-JIS$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
jv_convert_OBJECTS = jv_convert_OBJECTS =
gij_OBJECTS =
gen_from_JIS_OBJECTS = gen_from_JIS_OBJECTS =
gen_from_JIS_LDFLAGS = gen_from_JIS_LDFLAGS =
CXXFLAGS = @CXXFLAGS@ CXXFLAGS = @CXXFLAGS@
...@@ -688,9 +719,9 @@ GZIP_ENV = --best ...@@ -688,9 +719,9 @@ GZIP_ENV = --best
DIST_SUBDIRS = testsuite DIST_SUBDIRS = testsuite
DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/$(srcdir)/$(CONVERT_DIR)/make-trie.P .deps/boehm.P \ .deps/$(srcdir)/$(CONVERT_DIR)/make-trie.P .deps/boehm.P \
.deps/exception.P .deps/gnu/gcj/RawData.P \ .deps/defineclass.P .deps/exception.P .deps/gij.P \
.deps/gnu/gcj/convert/BytesToUnicode.P .deps/gnu/gcj/convert/Convert.P \ .deps/gnu/gcj/RawData.P .deps/gnu/gcj/convert/BytesToUnicode.P \
.deps/gnu/gcj/convert/Input_8859_1.P \ .deps/gnu/gcj/convert/Convert.P .deps/gnu/gcj/convert/Input_8859_1.P \
.deps/gnu/gcj/convert/Input_EUCJIS.P \ .deps/gnu/gcj/convert/Input_EUCJIS.P \
.deps/gnu/gcj/convert/Input_JavaSrc.P \ .deps/gnu/gcj/convert/Input_JavaSrc.P \
.deps/gnu/gcj/convert/Input_SJIS.P .deps/gnu/gcj/convert/Input_UTF8.P \ .deps/gnu/gcj/convert/Input_SJIS.P .deps/gnu/gcj/convert/Input_UTF8.P \
...@@ -703,6 +734,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ ...@@ -703,6 +734,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/gnu/gcj/protocol/file/Handler.P \ .deps/gnu/gcj/protocol/file/Handler.P \
.deps/gnu/gcj/protocol/http/Connection.P \ .deps/gnu/gcj/protocol/http/Connection.P \
.deps/gnu/gcj/protocol/http/Handler.P \ .deps/gnu/gcj/protocol/http/Handler.P \
.deps/gnu/gcj/runtime/MethodInvocation.P \
.deps/gnu/gcj/text/BaseBreakIterator.P \ .deps/gnu/gcj/text/BaseBreakIterator.P \
.deps/gnu/gcj/text/CharacterBreakIterator.P \ .deps/gnu/gcj/text/CharacterBreakIterator.P \
.deps/gnu/gcj/text/LineBreakIterator.P \ .deps/gnu/gcj/text/LineBreakIterator.P \
...@@ -711,6 +743,12 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ ...@@ -711,6 +743,12 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/gnu/gcj/text/SentenceBreakIterator.P \ .deps/gnu/gcj/text/SentenceBreakIterator.P \
.deps/gnu/gcj/text/WordBreakIterator.P \ .deps/gnu/gcj/text/WordBreakIterator.P \
.deps/gnu/gcj/util/EnumerationChain.P \ .deps/gnu/gcj/util/EnumerationChain.P \
.deps/gnu/gcj/util/path/CacheEntry.P \
.deps/gnu/gcj/util/path/DirectoryPathEntry.P \
.deps/gnu/gcj/util/path/PathEntry.P \
.deps/gnu/gcj/util/path/SearchPath.P \
.deps/gnu/gcj/util/path/URLPathEntry.P \
.deps/gnu/gcj/util/path/ZipPathEntry.P .deps/interpret.P \
.deps/java/io/BufferedInputStream.P \ .deps/java/io/BufferedInputStream.P \
.deps/java/io/BufferedOutputStream.P .deps/java/io/BufferedReader.P \ .deps/java/io/BufferedOutputStream.P .deps/java/io/BufferedReader.P \
.deps/java/io/BufferedWriter.P .deps/java/io/ByteArrayInputStream.P \ .deps/java/io/BufferedWriter.P .deps/java/io/ByteArrayInputStream.P \
...@@ -788,8 +826,9 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ ...@@ -788,8 +826,9 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/lang/Throwable.P .deps/java/lang/UnknownError.P \ .deps/java/lang/Throwable.P .deps/java/lang/UnknownError.P \
.deps/java/lang/UnsatisfiedLinkError.P \ .deps/java/lang/UnsatisfiedLinkError.P \
.deps/java/lang/UnsupportedOperationException.P \ .deps/java/lang/UnsupportedOperationException.P \
.deps/java/lang/VerifyError.P .deps/java/lang/VirtualMachineError.P \ .deps/java/lang/VMClassLoader.P .deps/java/lang/VerifyError.P \
.deps/java/lang/Void.P .deps/java/lang/dtoa.P .deps/java/lang/e_acos.P \ .deps/java/lang/VirtualMachineError.P .deps/java/lang/Void.P \
.deps/java/lang/dtoa.P .deps/java/lang/e_acos.P \
.deps/java/lang/e_asin.P .deps/java/lang/e_atan2.P \ .deps/java/lang/e_asin.P .deps/java/lang/e_atan2.P \
.deps/java/lang/e_exp.P .deps/java/lang/e_fmod.P \ .deps/java/lang/e_exp.P .deps/java/lang/e_fmod.P \
.deps/java/lang/e_log.P .deps/java/lang/e_pow.P \ .deps/java/lang/e_log.P .deps/java/lang/e_pow.P \
...@@ -872,9 +911,9 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ ...@@ -872,9 +911,9 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/util/zip/ZipException.P .deps/java/util/zip/ZipFile.P \ .deps/java/util/zip/ZipException.P .deps/java/util/zip/ZipFile.P \
.deps/java/util/zip/ZipInputStream.P \ .deps/java/util/zip/ZipInputStream.P \
.deps/java/util/zip/ZipOutputStream.P .deps/jni.P .deps/no-threads.P \ .deps/java/util/zip/ZipOutputStream.P .deps/jni.P .deps/no-threads.P \
.deps/nogc.P .deps/posix-threads.P .deps/prims.P .deps/nogc.P .deps/posix-threads.P .deps/prims.P .deps/resolve.P
SOURCES = $(libgcj_la_SOURCES) $(EXTRA_libgcj_la_SOURCES) $(jv_convert_SOURCES) $(EXTRA_jv_convert_SOURCES) $(gen_from_JIS_SOURCES) $(EXTRA_gen_from_JIS_SOURCES) SOURCES = $(libgcj_la_SOURCES) $(EXTRA_libgcj_la_SOURCES) $(jv_convert_SOURCES) $(EXTRA_jv_convert_SOURCES) $(gij_SOURCES) $(EXTRA_gij_SOURCES) $(gen_from_JIS_SOURCES) $(EXTRA_gen_from_JIS_SOURCES)
OBJECTS = $(libgcj_la_OBJECTS) $(jv_convert_OBJECTS) $(gen_from_JIS_OBJECTS) OBJECTS = $(libgcj_la_OBJECTS) $(jv_convert_OBJECTS) $(gij_OBJECTS) $(gen_from_JIS_OBJECTS)
all: all-redirect all: all-redirect
.SUFFIXES: .SUFFIXES:
...@@ -1022,6 +1061,10 @@ jv-convert$(EXEEXT): $(jv_convert_OBJECTS) $(jv_convert_DEPENDENCIES) ...@@ -1022,6 +1061,10 @@ jv-convert$(EXEEXT): $(jv_convert_OBJECTS) $(jv_convert_DEPENDENCIES)
@rm -f jv-convert$(EXEEXT) @rm -f jv-convert$(EXEEXT)
$(jv_convert_LINK) $(jv_convert_LDFLAGS) $(jv_convert_OBJECTS) $(jv_convert_LDADD) $(LIBS) $(jv_convert_LINK) $(jv_convert_LDFLAGS) $(jv_convert_OBJECTS) $(jv_convert_LDADD) $(LIBS)
gij$(EXEEXT): $(gij_OBJECTS) $(gij_DEPENDENCIES)
@rm -f gij$(EXEEXT)
$(gij_LINK) $(gij_LDFLAGS) $(gij_OBJECTS) $(gij_LDADD) $(LIBS)
gen-from-JIS$(EXEEXT): $(gen_from_JIS_OBJECTS) $(gen_from_JIS_DEPENDENCIES) gen-from-JIS$(EXEEXT): $(gen_from_JIS_OBJECTS) $(gen_from_JIS_DEPENDENCIES)
@rm -f gen-from-JIS$(EXEEXT) @rm -f gen-from-JIS$(EXEEXT)
$(LINK) $(gen_from_JIS_LDFLAGS) $(gen_from_JIS_OBJECTS) $(gen_from_JIS_LDADD) $(LIBS) $(LINK) $(gen_from_JIS_LDFLAGS) $(gen_from_JIS_OBJECTS) $(gen_from_JIS_LDADD) $(LIBS)
...@@ -1451,6 +1494,16 @@ java/lang/reflect/Method.h: java/lang/reflect/Method.class libgcj.zip ...@@ -1451,6 +1494,16 @@ java/lang/reflect/Method.h: java/lang/reflect/Method.class libgcj.zip
-friend 'java::lang::Class;' \ -friend 'java::lang::Class;' \
$(basename $<) $(basename $<)
java/lang/VMClassLoader.h: java/lang/VMClassLoader.class libgcj.zip
$(GCJH) -classpath $(top_builddir) \
-friend 'java::lang::ClassLoader;' \
$(basename $<)
gnu/gcj/runtime/MethodInvocation.h: gnu/gcj/runtime/MethodInvocation.class libgcj.zip
$(GCJH) -classpath $(top_builddir) \
-friend 'class _Jv_InterpMethod;' \
$(basename $<)
maintainer-check: libgcj.la maintainer-check: libgcj.la
$(NM) .libs/libgcj.a | grep ' T ' \ $(NM) .libs/libgcj.a | grep ' T ' \
| grep -v '4java' \ | grep -v '4java' \
......
New in libgcj X.XX:
* libgcj now includes a bytecode interpreter.
New in libgcj 2.95: New in libgcj 2.95:
* First public release * First public release
...@@ -10,9 +10,10 @@ Eric Christopher echristo@cygnus.com ...@@ -10,9 +10,10 @@ Eric Christopher echristo@cygnus.com
Franz Sirl Franz.Sirl-kernel@lauterbach.com Franz Sirl Franz.Sirl-kernel@lauterbach.com
Geoff Berry gcb@gnu.org Geoff Berry gcb@gnu.org
Gilles Zunino Gilles.Zunino@hei.fr Gilles Zunino Gilles.Zunino@hei.fr
Per Bothner per@bother.com Kresten Krab Thorup krab@gnu.org
Per Bothner per@bothner.com
Rainer Orth ro@TechFak.Uni-Bielefeld.DE Rainer Orth ro@TechFak.Uni-Bielefeld.DE
Stu Grossman grossman@cygnus.com Stu Grossman grossman@juniper.com
Tom Tromey tromey@cygnus.com Tom Tromey tromey@cygnus.com
Urban Widmark urban@svenskatest.se Urban Widmark urban@svenskatest.se
Warren Levy warrenl@cygnus.com Warren Levy warrenl@cygnus.com
...@@ -93,3 +93,6 @@ ...@@ -93,3 +93,6 @@
#undef HAVE_READDIR_R #undef HAVE_READDIR_R
#undef HAVE_GETHOSTBYNAME_R #undef HAVE_GETHOSTBYNAME_R
#undef HAVE_GETHOSTBYADDR_R #undef HAVE_GETHOSTBYADDR_R
/* Define if you want a bytecode interpreter. */
#undef INTERPRETER
...@@ -16,6 +16,7 @@ details. */ ...@@ -16,6 +16,7 @@ details. */
#include <java/lang/Class.h> #include <java/lang/Class.h>
#include <jvm.h> #include <jvm.h>
#include <java-field.h> #include <java-field.h>
#include <java-interp.h>
// We need to include gc_priv.h. However, it tries to include // We need to include gc_priv.h. However, it tries to include
// config.h if it hasn't already been included. So we force the // config.h if it hasn't already been included. So we force the
...@@ -97,8 +98,14 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/) ...@@ -97,8 +98,14 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/)
{ {
jclass c = (jclass) addr; jclass c = (jclass) addr;
#if 0
// The next field should probably not be marked, since this is
// only used in the class hash table. Marking this field
// basically prohibits class unloading. --Kresten
w = (word) c->next; w = (word) c->next;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c2label); MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c2label);
#endif
w = (word) c->name; w = (word) c->name;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c3label); MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c3label);
w = (word) c->superclass; w = (word) c->superclass;
...@@ -109,12 +116,23 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/) ...@@ -109,12 +116,23 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/)
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c5label); MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c5label);
} }
#ifdef INTERPRETER
if (_Jv_IsInterpretedClass (c))
{
w = (word) c->constants.tags;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c5alabel);
w = (word) c->constants.data;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c5blabel);
}
#endif
// If the class is an array, then the methods field holds a // If the class is an array, then the methods field holds a
// pointer to the element class. If the class is primitive, // pointer to the element class. If the class is primitive,
// then the methods field holds a pointer to the array class. // then the methods field holds a pointer to the array class.
w = (word) c->methods; w = (word) c->methods;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c6label); MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c6label);
if (! c->isArray() && ! c->isPrimitive()) if (! c->isArray() && ! c->isPrimitive())
{ {
// Scan each method in the cases where `methods' really // Scan each method in the cases where `methods' really
...@@ -127,7 +145,19 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/) ...@@ -127,7 +145,19 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/)
w = (word) c->methods[i].signature; w = (word) c->methods[i].signature;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c,
cm2label); cm2label);
// FIXME: `ncode' entry? // FIXME: `ncode' entry?
#ifdef INTERPRETER
// The interpreter installs a heap-allocated
// trampoline here, so we'll mark it.
if (_Jv_IsInterpretedClass (c))
{
w = (word) c->methods[i].ncode;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c,
cm3label);
}
#endif
} }
} }
...@@ -136,12 +166,34 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/) ...@@ -136,12 +166,34 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/)
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8label); MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8label);
for (int i = 0; i < c->field_count; ++i) for (int i = 0; i < c->field_count; ++i)
{ {
_Jv_Field* field = &c->fields[i];
#ifndef COMPACT_FIELDS #ifndef COMPACT_FIELDS
w = (word) c->fields[i].name; w = (word) field->name;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8alabel); MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8alabel);
#endif #endif
w = (word) c->fields[i].type; w = (word) field->type;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8blabel); MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8blabel);
// For the interpreter, we also need to mark the memory
// containing static members
if (field->flags & 0x0008)
{
w = (word) field->u.addr;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8clabel);
// also, if the static member is a reference,
// mark also the value pointed to. We check for isResolved
// since marking can happen before memory is allocated for
// static members.
if (JvFieldIsRef (field) && field->isResolved())
{
jobject val = *(jobject*) field->u.addr;
w = (word) val;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit,
c, c8elabel);
}
}
} }
w = (word) c->vtable; w = (word) c->vtable;
...@@ -155,6 +207,28 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/) ...@@ -155,6 +207,28 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/)
} }
w = (word) c->loader; w = (word) c->loader;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, cBlabel); MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, cBlabel);
#ifdef INTERPRETER
if (_Jv_IsInterpretedClass (c))
{
_Jv_InterpClass* ic = (_Jv_InterpClass*)c;
w = (word) ic->interpreted_methods;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, ic, cElabel);
for (int i = 0; i < c->method_count; i++)
{
w = (word) ic->interpreted_methods[i];
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, ic, \
cFlabel);
}
w = (word) ic->field_initializers;
MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, ic, cGlabel);
}
#endif
} }
else else
{ {
......
...@@ -35,6 +35,8 @@ ac_help="$ac_help ...@@ -35,6 +35,8 @@ ac_help="$ac_help
ac_help="$ac_help ac_help="$ac_help
--enable-libgcj-debug Enable runtime debugging code" --enable-libgcj-debug Enable runtime debugging code"
ac_help="$ac_help ac_help="$ac_help
--enable-interpreter Enable interpreter"
ac_help="$ac_help
--with-ecos Enable runtime eCos target support." --with-ecos Enable runtime eCos target support."
ac_help="$ac_help ac_help="$ac_help
--with-system-zlib Use installed libz" --with-system-zlib Use installed libz"
...@@ -59,6 +61,7 @@ program_suffix=NONE ...@@ -59,6 +61,7 @@ program_suffix=NONE
program_transform_name=s,x,x, program_transform_name=s,x,x,
silent= silent=
site= site=
sitefile=
srcdir= srcdir=
target=NONE target=NONE
verbose= verbose=
...@@ -173,6 +176,7 @@ Configuration: ...@@ -173,6 +176,7 @@ Configuration:
--help print this message --help print this message
--no-create do not create output files --no-create do not create output files
--quiet, --silent do not print \`checking...' messages --quiet, --silent do not print \`checking...' messages
--site-file=FILE use FILE as the site file
--version print the version of autoconf that created configure --version print the version of autoconf that created configure
Directory and file names: Directory and file names:
--prefix=PREFIX install architecture-independent files in PREFIX --prefix=PREFIX install architecture-independent files in PREFIX
...@@ -343,6 +347,11 @@ EOF ...@@ -343,6 +347,11 @@ EOF
-site=* | --site=* | --sit=*) -site=* | --site=* | --sit=*)
site="$ac_optarg" ;; site="$ac_optarg" ;;
-site-file | --site-file | --site-fil | --site-fi | --site-f)
ac_prev=sitefile ;;
-site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
sitefile="$ac_optarg" ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr) -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;; ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
...@@ -508,12 +517,16 @@ fi ...@@ -508,12 +517,16 @@ fi
srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
# Prefer explicitly selected file to automatically selected ones. # Prefer explicitly selected file to automatically selected ones.
if test -z "$CONFIG_SITE"; then if test -z "$sitefile"; then
if test "x$prefix" != xNONE; then if test -z "$CONFIG_SITE"; then
CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" if test "x$prefix" != xNONE; then
else CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" else
CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
fi
fi fi
else
CONFIG_SITE="$sitefile"
fi fi
for ac_site_file in $CONFIG_SITE; do for ac_site_file in $CONFIG_SITE; do
if test -r "$ac_site_file"; then if test -r "$ac_site_file"; then
...@@ -601,7 +614,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } ...@@ -601,7 +614,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi fi
echo $ac_n "checking host system type""... $ac_c" 1>&6 echo $ac_n "checking host system type""... $ac_c" 1>&6
echo "configure:605: checking host system type" >&5 echo "configure:618: checking host system type" >&5
host_alias=$host host_alias=$host
case "$host_alias" in case "$host_alias" in
...@@ -622,7 +635,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` ...@@ -622,7 +635,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$host" 1>&6 echo "$ac_t""$host" 1>&6
echo $ac_n "checking target system type""... $ac_c" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6
echo "configure:626: checking target system type" >&5 echo "configure:639: checking target system type" >&5
target_alias=$target target_alias=$target
case "$target_alias" in case "$target_alias" in
...@@ -640,7 +653,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` ...@@ -640,7 +653,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$target" 1>&6 echo "$ac_t""$target" 1>&6
echo $ac_n "checking build system type""... $ac_c" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6
echo "configure:644: checking build system type" >&5 echo "configure:657: checking build system type" >&5
build_alias=$build build_alias=$build
case "$build_alias" in case "$build_alias" in
...@@ -688,7 +701,7 @@ fi ...@@ -688,7 +701,7 @@ fi
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh. # ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:692: checking for a BSD compatible install" >&5 echo "configure:705: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
...@@ -741,7 +754,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' ...@@ -741,7 +754,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
echo "configure:745: checking whether build environment is sane" >&5 echo "configure:758: checking whether build environment is sane" >&5
# Just in case # Just in case
sleep 1 sleep 1
echo timestamp > conftestfile echo timestamp > conftestfile
...@@ -798,7 +811,7 @@ test "$program_suffix" != NONE && ...@@ -798,7 +811,7 @@ test "$program_suffix" != NONE &&
test "$program_transform_name" = "" && program_transform_name="s,x,x," test "$program_transform_name" = "" && program_transform_name="s,x,x,"
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
echo "configure:802: checking whether ${MAKE-make} sets \${MAKE}" >&5 echo "configure:815: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
...@@ -831,12 +844,12 @@ else ...@@ -831,12 +844,12 @@ else
fi fi
echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
echo "configure:835: checking for Cygwin environment" >&5 echo "configure:848: checking for Cygwin environment" >&5
if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 840 "configure" #line 853 "configure"
#include "confdefs.h" #include "confdefs.h"
int main() { int main() {
...@@ -847,7 +860,7 @@ int main() { ...@@ -847,7 +860,7 @@ int main() {
return __CYGWIN__; return __CYGWIN__;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:851: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:864: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_cygwin=yes ac_cv_cygwin=yes
else else
...@@ -864,19 +877,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6 ...@@ -864,19 +877,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6
CYGWIN= CYGWIN=
test "$ac_cv_cygwin" = yes && CYGWIN=yes test "$ac_cv_cygwin" = yes && CYGWIN=yes
echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
echo "configure:868: checking for mingw32 environment" >&5 echo "configure:881: checking for mingw32 environment" >&5
if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 873 "configure" #line 886 "configure"
#include "confdefs.h" #include "confdefs.h"
int main() { int main() {
return __MINGW32__; return __MINGW32__;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:880: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:893: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_mingw32=yes ac_cv_mingw32=yes
else else
...@@ -924,7 +937,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } ...@@ -924,7 +937,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi fi
echo $ac_n "checking host system type""... $ac_c" 1>&6 echo $ac_n "checking host system type""... $ac_c" 1>&6
echo "configure:928: checking host system type" >&5 echo "configure:941: checking host system type" >&5
host_alias=$host host_alias=$host
case "$host_alias" in case "$host_alias" in
...@@ -966,7 +979,7 @@ EOF ...@@ -966,7 +979,7 @@ EOF
missing_dir=`cd $ac_aux_dir && pwd` missing_dir=`cd $ac_aux_dir && pwd`
echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
echo "configure:970: checking for working aclocal" >&5 echo "configure:983: checking for working aclocal" >&5
# Run test in a subshell; some versions of sh will print an error if # Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected. # an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh. # Redirect stdin to placate older versions of autoconf. Sigh.
...@@ -979,7 +992,7 @@ else ...@@ -979,7 +992,7 @@ else
fi fi
echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
echo "configure:983: checking for working autoconf" >&5 echo "configure:996: checking for working autoconf" >&5
# Run test in a subshell; some versions of sh will print an error if # Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected. # an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh. # Redirect stdin to placate older versions of autoconf. Sigh.
...@@ -992,7 +1005,7 @@ else ...@@ -992,7 +1005,7 @@ else
fi fi
echo $ac_n "checking for working automake""... $ac_c" 1>&6 echo $ac_n "checking for working automake""... $ac_c" 1>&6
echo "configure:996: checking for working automake" >&5 echo "configure:1009: checking for working automake" >&5
# Run test in a subshell; some versions of sh will print an error if # Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected. # an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh. # Redirect stdin to placate older versions of autoconf. Sigh.
...@@ -1005,7 +1018,7 @@ else ...@@ -1005,7 +1018,7 @@ else
fi fi
echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
echo "configure:1009: checking for working autoheader" >&5 echo "configure:1022: checking for working autoheader" >&5
# Run test in a subshell; some versions of sh will print an error if # Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected. # an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh. # Redirect stdin to placate older versions of autoconf. Sigh.
...@@ -1018,7 +1031,7 @@ else ...@@ -1018,7 +1031,7 @@ else
fi fi
echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
echo "configure:1022: checking for working makeinfo" >&5 echo "configure:1035: checking for working makeinfo" >&5
# Run test in a subshell; some versions of sh will print an error if # Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected. # an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh. # Redirect stdin to placate older versions of autoconf. Sigh.
...@@ -1043,7 +1056,7 @@ fi ...@@ -1043,7 +1056,7 @@ fi
# Extract the first word of "gcc", so it can be a program name with args. # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2 set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1047: checking for $ac_word" >&5 echo "configure:1060: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1073,7 +1086,7 @@ if test -z "$CC"; then ...@@ -1073,7 +1086,7 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args. # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2 set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1077: checking for $ac_word" >&5 echo "configure:1090: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1122,7 +1135,7 @@ fi ...@@ -1122,7 +1135,7 @@ fi
fi fi
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
echo "configure:1126: checking whether we are using GNU C" >&5 echo "configure:1139: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1131,7 +1144,7 @@ else ...@@ -1131,7 +1144,7 @@ else
yes; yes;
#endif #endif
EOF EOF
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1135: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1148: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes ac_cv_prog_gcc=yes
else else
ac_cv_prog_gcc=no ac_cv_prog_gcc=no
...@@ -1146,7 +1159,7 @@ if test $ac_cv_prog_gcc = yes; then ...@@ -1146,7 +1159,7 @@ if test $ac_cv_prog_gcc = yes; then
ac_save_CFLAGS="$CFLAGS" ac_save_CFLAGS="$CFLAGS"
CFLAGS= CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:1150: checking whether ${CC-cc} accepts -g" >&5 echo "configure:1163: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1182,7 +1195,7 @@ do ...@@ -1182,7 +1195,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args. # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2 set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1186: checking for $ac_word" >&5 echo "configure:1199: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1215,7 +1228,7 @@ test -n "$CXX" || CXX="gcc" ...@@ -1215,7 +1228,7 @@ test -n "$CXX" || CXX="gcc"
test -z "$CXX" && { echo "configure: error: no acceptable c++ found in \$PATH" 1>&2; exit 1; } test -z "$CXX" && { echo "configure: error: no acceptable c++ found in \$PATH" 1>&2; exit 1; }
echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
echo "configure:1219: checking whether we are using GNU C++" >&5 echo "configure:1232: checking whether we are using GNU C++" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1224,7 +1237,7 @@ else ...@@ -1224,7 +1237,7 @@ else
yes; yes;
#endif #endif
EOF EOF
if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1228: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1241: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gxx=yes ac_cv_prog_gxx=yes
else else
ac_cv_prog_gxx=no ac_cv_prog_gxx=no
...@@ -1239,7 +1252,7 @@ if test $ac_cv_prog_gxx = yes; then ...@@ -1239,7 +1252,7 @@ if test $ac_cv_prog_gxx = yes; then
ac_save_CXXFLAGS="$CXXFLAGS" ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS= CXXFLAGS=
echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
echo "configure:1243: checking whether ${CXX-g++} accepts -g" >&5 echo "configure:1256: checking whether ${CXX-g++} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1272,7 +1285,7 @@ fi ...@@ -1272,7 +1285,7 @@ fi
# LIBGCJ_CONFIGURE, which doesn't work because that means that it will # LIBGCJ_CONFIGURE, which doesn't work because that means that it will
# be run before AC_CANONICAL_HOST. # be run before AC_CANONICAL_HOST.
echo $ac_n "checking build system type""... $ac_c" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6
echo "configure:1276: checking build system type" >&5 echo "configure:1289: checking build system type" >&5
build_alias=$build build_alias=$build
case "$build_alias" in case "$build_alias" in
...@@ -1293,7 +1306,7 @@ echo "$ac_t""$build" 1>&6 ...@@ -1293,7 +1306,7 @@ echo "$ac_t""$build" 1>&6
# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
set dummy ${ac_tool_prefix}as; ac_word=$2 set dummy ${ac_tool_prefix}as; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1297: checking for $ac_word" >&5 echo "configure:1310: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1325,7 +1338,7 @@ fi ...@@ -1325,7 +1338,7 @@ fi
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2 set dummy ${ac_tool_prefix}ar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1329: checking for $ac_word" >&5 echo "configure:1342: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1357,7 +1370,7 @@ fi ...@@ -1357,7 +1370,7 @@ fi
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1361: checking for $ac_word" >&5 echo "configure:1374: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1389,7 +1402,7 @@ if test -n "$ac_tool_prefix"; then ...@@ -1389,7 +1402,7 @@ if test -n "$ac_tool_prefix"; then
# Extract the first word of "ranlib", so it can be a program name with args. # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2 set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1393: checking for $ac_word" >&5 echo "configure:1406: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1434,7 +1447,7 @@ fi ...@@ -1434,7 +1447,7 @@ fi
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh. # ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:1438: checking for a BSD compatible install" >&5 echo "configure:1451: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
...@@ -1488,7 +1501,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ...@@ -1488,7 +1501,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
echo "configure:1492: checking whether to enable maintainer-specific portions of Makefiles" >&5 echo "configure:1505: checking whether to enable maintainer-specific portions of Makefiles" >&5
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
if test "${enable_maintainer_mode+set}" = set; then if test "${enable_maintainer_mode+set}" = set; then
enableval="$enable_maintainer_mode" enableval="$enable_maintainer_mode"
...@@ -1522,7 +1535,7 @@ if false; then ...@@ -1522,7 +1535,7 @@ if false; then
echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
echo "configure:1526: checking for executable suffix" >&5 echo "configure:1539: checking for executable suffix" >&5
if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1532,7 +1545,7 @@ else ...@@ -1532,7 +1545,7 @@ else
rm -f conftest* rm -f conftest*
echo 'int main () { return 0; }' > conftest.$ac_ext echo 'int main () { return 0; }' > conftest.$ac_ext
ac_cv_exeext= ac_cv_exeext=
if { (eval echo configure:1536: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then if { (eval echo configure:1549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
for file in conftest.*; do for file in conftest.*; do
case $file in case $file in
*.c | *.o | *.obj | *.ilk | *.pdb) ;; *.c | *.o | *.obj | *.ilk | *.pdb) ;;
...@@ -1654,7 +1667,7 @@ fi ...@@ -1654,7 +1667,7 @@ fi
# Extract the first word of "ranlib", so it can be a program name with args. # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2 set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1658: checking for $ac_word" >&5 echo "configure:1671: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1684,7 +1697,7 @@ fi ...@@ -1684,7 +1697,7 @@ fi
# Extract the first word of "gcc", so it can be a program name with args. # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2 set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1688: checking for $ac_word" >&5 echo "configure:1701: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1714,7 +1727,7 @@ if test -z "$CC"; then ...@@ -1714,7 +1727,7 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args. # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2 set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1718: checking for $ac_word" >&5 echo "configure:1731: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1765,7 +1778,7 @@ fi ...@@ -1765,7 +1778,7 @@ fi
# Extract the first word of "cl", so it can be a program name with args. # Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2 set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1769: checking for $ac_word" >&5 echo "configure:1782: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1797,7 +1810,7 @@ fi ...@@ -1797,7 +1810,7 @@ fi
fi fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
echo "configure:1801: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 echo "configure:1814: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
...@@ -1808,12 +1821,12 @@ cross_compiling=$ac_cv_prog_cc_cross ...@@ -1808,12 +1821,12 @@ cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF cat > conftest.$ac_ext << EOF
#line 1812 "configure" #line 1825 "configure"
#include "confdefs.h" #include "confdefs.h"
main(){return(0);} main(){return(0);}
EOF EOF
if { (eval echo configure:1817: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:1830: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler. # If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then if (./conftest; exit) 2>/dev/null; then
...@@ -1839,12 +1852,12 @@ if test $ac_cv_prog_cc_works = no; then ...@@ -1839,12 +1852,12 @@ if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
echo "configure:1843: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "configure:1856: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
echo "configure:1848: checking whether we are using GNU C" >&5 echo "configure:1861: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1853,7 +1866,7 @@ else ...@@ -1853,7 +1866,7 @@ else
yes; yes;
#endif #endif
EOF EOF
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1857: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1870: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes ac_cv_prog_gcc=yes
else else
ac_cv_prog_gcc=no ac_cv_prog_gcc=no
...@@ -1872,7 +1885,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ...@@ -1872,7 +1885,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS" ac_save_CFLAGS="$CFLAGS"
CFLAGS= CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:1876: checking whether ${CC-cc} accepts -g" >&5 echo "configure:1889: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1915,7 +1928,7 @@ ac_prog=ld ...@@ -1915,7 +1928,7 @@ ac_prog=ld
if test "$ac_cv_prog_gcc" = yes; then if test "$ac_cv_prog_gcc" = yes; then
# Check if gcc -print-prog-name=ld gives a path. # Check if gcc -print-prog-name=ld gives a path.
echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
echo "configure:1919: checking for ld used by GCC" >&5 echo "configure:1932: checking for ld used by GCC" >&5
ac_prog=`($CC -print-prog-name=ld) 2>&5` ac_prog=`($CC -print-prog-name=ld) 2>&5`
case "$ac_prog" in case "$ac_prog" in
# Accept absolute paths. # Accept absolute paths.
...@@ -1939,10 +1952,10 @@ echo "configure:1919: checking for ld used by GCC" >&5 ...@@ -1939,10 +1952,10 @@ echo "configure:1919: checking for ld used by GCC" >&5
esac esac
elif test "$with_gnu_ld" = yes; then elif test "$with_gnu_ld" = yes; then
echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
echo "configure:1943: checking for GNU ld" >&5 echo "configure:1956: checking for GNU ld" >&5
else else
echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
echo "configure:1946: checking for non-GNU ld" >&5 echo "configure:1959: checking for non-GNU ld" >&5
fi fi
if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
...@@ -1978,7 +1991,7 @@ fi ...@@ -1978,7 +1991,7 @@ fi
test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
echo "configure:1982: checking if the linker ($LD) is GNU ld" >&5 echo "configure:1995: checking if the linker ($LD) is GNU ld" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -1994,7 +2007,7 @@ echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6 ...@@ -1994,7 +2007,7 @@ echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
echo "configure:1998: checking for BSD-compatible nm" >&5 echo "configure:2011: checking for BSD-compatible nm" >&5
if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -2031,7 +2044,7 @@ echo "$ac_t""$NM" 1>&6 ...@@ -2031,7 +2044,7 @@ echo "$ac_t""$NM" 1>&6
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
echo "configure:2035: checking whether ln -s works" >&5 echo "configure:2048: checking whether ln -s works" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -2075,8 +2088,8 @@ test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" ...@@ -2075,8 +2088,8 @@ test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
case "$host" in case "$host" in
*-*-irix6*) *-*-irix6*)
# Find out which ABI we are using. # Find out which ABI we are using.
echo '#line 2079 "configure"' > conftest.$ac_ext echo '#line 2092 "configure"' > conftest.$ac_ext
if { (eval echo configure:2080: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:2093: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
case "`/usr/bin/file conftest.o`" in case "`/usr/bin/file conftest.o`" in
*32-bit*) *32-bit*)
LD="${LD-ld} -32" LD="${LD-ld} -32"
...@@ -2097,19 +2110,19 @@ case "$host" in ...@@ -2097,19 +2110,19 @@ case "$host" in
SAVE_CFLAGS="$CFLAGS" SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -belf" CFLAGS="$CFLAGS -belf"
echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
echo "configure:2101: checking whether the C compiler needs -belf" >&5 echo "configure:2114: checking whether the C compiler needs -belf" >&5
if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2106 "configure" #line 2119 "configure"
#include "confdefs.h" #include "confdefs.h"
int main() { int main() {
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2113: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2126: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
lt_cv_cc_needs_belf=yes lt_cv_cc_needs_belf=yes
else else
...@@ -2253,6 +2266,21 @@ EOF ...@@ -2253,6 +2266,21 @@ EOF
fi fi
# Check whether --enable-interpreter or --disable-interpreter was given.
if test "${enable_interpreter+set}" = set; then
enableval="$enable_interpreter"
if test "$enable_interpreter" = yes; then
cat >> confdefs.h <<\EOF
#define INTERPRETER 1
EOF
fi
fi
INTERPSPEC=
TARGET_ECOS="no" TARGET_ECOS="no"
# Check whether --with-ecos or --without-ecos was given. # Check whether --with-ecos or --without-ecos was given.
if test "${with_ecos+set}" = set; then if test "${with_ecos+set}" = set; then
...@@ -2278,7 +2306,7 @@ EOF ...@@ -2278,7 +2306,7 @@ EOF
esac esac
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:2282: checking how to run the C preprocessor" >&5 echo "configure:2310: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory. # On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then if test -n "$CPP" && test -d "$CPP"; then
CPP= CPP=
...@@ -2293,13 +2321,13 @@ else ...@@ -2293,13 +2321,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser, # On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. # not just through cpp.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2297 "configure" #line 2325 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2303: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:2331: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
...@@ -2310,13 +2338,13 @@ else ...@@ -2310,13 +2338,13 @@ else
rm -rf conftest* rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp" CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2314 "configure" #line 2342 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2320: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:2348: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
...@@ -2327,13 +2355,13 @@ else ...@@ -2327,13 +2355,13 @@ else
rm -rf conftest* rm -rf conftest*
CPP="${CC-cc} -nologo -E" CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2331 "configure" #line 2359 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2337: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:2365: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
...@@ -2358,7 +2386,7 @@ fi ...@@ -2358,7 +2386,7 @@ fi
echo "$ac_t""$CPP" 1>&6 echo "$ac_t""$CPP" 1>&6
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2362 "configure" #line 2390 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <stdint.h> #include <stdint.h>
EOF EOF
...@@ -2373,7 +2401,7 @@ fi ...@@ -2373,7 +2401,7 @@ fi
rm -f conftest* rm -f conftest*
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2377 "configure" #line 2405 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <inttypes.h> #include <inttypes.h>
EOF EOF
...@@ -2388,7 +2416,7 @@ fi ...@@ -2388,7 +2416,7 @@ fi
rm -f conftest* rm -f conftest*
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2392 "configure" #line 2420 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
EOF EOF
...@@ -2403,7 +2431,7 @@ fi ...@@ -2403,7 +2431,7 @@ fi
rm -f conftest* rm -f conftest*
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2407 "configure" #line 2435 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/config.h> #include <sys/config.h>
EOF EOF
...@@ -2420,7 +2448,7 @@ rm -f conftest* ...@@ -2420,7 +2448,7 @@ rm -f conftest*
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2424 "configure" #line 2452 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <time.h> #include <time.h>
EOF EOF
...@@ -2435,7 +2463,7 @@ fi ...@@ -2435,7 +2463,7 @@ fi
rm -f conftest* rm -f conftest*
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2439 "configure" #line 2467 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <time.h> #include <time.h>
EOF EOF
...@@ -2473,7 +2501,7 @@ ZLIBSPEC= ...@@ -2473,7 +2501,7 @@ ZLIBSPEC=
libsubdir=.libs libsubdir=.libs
echo $ac_n "checking for garbage collector to use""... $ac_c" 1>&6 echo $ac_n "checking for garbage collector to use""... $ac_c" 1>&6
echo "configure:2477: checking for garbage collector to use" >&5 echo "configure:2505: checking for garbage collector to use" >&5
# Check whether --enable-java-gc or --disable-java-gc was given. # Check whether --enable-java-gc or --disable-java-gc was given.
if test "${enable_java_gc+set}" = set; then if test "${enable_java_gc+set}" = set; then
enableval="$enable_java_gc" enableval="$enable_java_gc"
...@@ -2523,7 +2551,7 @@ esac ...@@ -2523,7 +2551,7 @@ esac
echo $ac_n "checking for threads package to use""... $ac_c" 1>&6 echo $ac_n "checking for threads package to use""... $ac_c" 1>&6
echo "configure:2527: checking for threads package to use" >&5 echo "configure:2555: checking for threads package to use" >&5
# Check whether --enable-threads or --disable-threads was given. # Check whether --enable-threads or --disable-threads was given.
if test "${enable_threads+set}" = set; then if test "${enable_threads+set}" = set; then
enableval="$enable_threads" enableval="$enable_threads"
...@@ -2715,12 +2743,12 @@ else ...@@ -2715,12 +2743,12 @@ else
for ac_func in strerror ioctl select open fsync sleep for ac_func in strerror ioctl select open fsync sleep
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2719: checking for $ac_func" >&5 echo "configure:2747: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2724 "configure" #line 2752 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -2743,7 +2771,7 @@ $ac_func(); ...@@ -2743,7 +2771,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2747: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2775: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -2770,12 +2798,12 @@ done ...@@ -2770,12 +2798,12 @@ done
for ac_func in ctime_r ctime for ac_func in ctime_r ctime
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2774: checking for $ac_func" >&5 echo "configure:2802: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2779 "configure" #line 2807 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -2798,7 +2826,7 @@ $ac_func(); ...@@ -2798,7 +2826,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2802: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2830: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -2825,12 +2853,12 @@ done ...@@ -2825,12 +2853,12 @@ done
for ac_func in gmtime_r localtime_r readdir_r getpwuid_r for ac_func in gmtime_r localtime_r readdir_r getpwuid_r
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2829: checking for $ac_func" >&5 echo "configure:2857: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2834 "configure" #line 2862 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -2853,7 +2881,7 @@ $ac_func(); ...@@ -2853,7 +2881,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2857: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2885: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -2880,12 +2908,12 @@ done ...@@ -2880,12 +2908,12 @@ done
for ac_func in access stat mkdir rename rmdir unlink realpath for ac_func in access stat mkdir rename rmdir unlink realpath
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2884: checking for $ac_func" >&5 echo "configure:2912: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2889 "configure" #line 2917 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -2908,7 +2936,7 @@ $ac_func(); ...@@ -2908,7 +2936,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2912: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -2935,12 +2963,12 @@ done ...@@ -2935,12 +2963,12 @@ done
for ac_func in inet_aton inet_addr for ac_func in inet_aton inet_addr
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2939: checking for $ac_func" >&5 echo "configure:2967: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2944 "configure" #line 2972 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -2963,7 +2991,7 @@ $ac_func(); ...@@ -2963,7 +2991,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2967: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2995: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -2990,12 +3018,12 @@ done ...@@ -2990,12 +3018,12 @@ done
for ac_func in inet_pton uname inet_ntoa for ac_func in inet_pton uname inet_ntoa
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2994: checking for $ac_func" >&5 echo "configure:3022: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2999 "configure" #line 3027 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -3018,7 +3046,7 @@ $ac_func(); ...@@ -3018,7 +3046,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3050: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -3046,12 +3074,12 @@ done ...@@ -3046,12 +3074,12 @@ done
for ac_func in gethostbyname_r for ac_func in gethostbyname_r
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3050: checking for $ac_func" >&5 echo "configure:3078: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3055 "configure" #line 3083 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -3074,7 +3102,7 @@ $ac_func(); ...@@ -3074,7 +3102,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3078: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3106: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -3101,7 +3129,7 @@ EOF ...@@ -3101,7 +3129,7 @@ EOF
# We look for the one that returns `int'. # We look for the one that returns `int'.
# Hopefully this check is robust enough. # Hopefully this check is robust enough.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3105 "configure" #line 3133 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <netdb.h> #include <netdb.h>
EOF EOF
...@@ -3121,7 +3149,7 @@ rm -f conftest* ...@@ -3121,7 +3149,7 @@ rm -f conftest*
*" -D_REENTRANT "*) ;; *" -D_REENTRANT "*) ;;
*) *)
echo $ac_n "checking whether gethostbyname_r declaration requires -D_REENTRANT""... $ac_c" 1>&6 echo $ac_n "checking whether gethostbyname_r declaration requires -D_REENTRANT""... $ac_c" 1>&6
echo "configure:3125: checking whether gethostbyname_r declaration requires -D_REENTRANT" >&5 echo "configure:3153: checking whether gethostbyname_r declaration requires -D_REENTRANT" >&5
if eval "test \"`echo '$''{'libjava_cv_gethostbyname_r_needs_reentrant'+set}'`\" = set"; then if eval "test \"`echo '$''{'libjava_cv_gethostbyname_r_needs_reentrant'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -3134,14 +3162,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes ...@@ -3134,14 +3162,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes
cross_compiling=$ac_cv_prog_cxx_cross cross_compiling=$ac_cv_prog_cxx_cross
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3138 "configure" #line 3166 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <netdb.h> #include <netdb.h>
int main() { int main() {
gethostbyname_r("", 0, 0); gethostbyname_r("", 0, 0);
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3145: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3173: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
libjava_cv_gethostbyname_r_needs_reentrant=no libjava_cv_gethostbyname_r_needs_reentrant=no
else else
...@@ -3151,14 +3179,14 @@ else ...@@ -3151,14 +3179,14 @@ else
CPPFLAGS_SAVE="$CPPFLAGS" CPPFLAGS_SAVE="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -D_REENTRANT" CPPFLAGS="$CPPFLAGS -D_REENTRANT"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3155 "configure" #line 3183 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <netdb.h> #include <netdb.h>
int main() { int main() {
gethostbyname_r("", 0, 0); gethostbyname_r("", 0, 0);
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3162: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3190: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
libjava_cv_gethostbyname_r_needs_reentrant=yes libjava_cv_gethostbyname_r_needs_reentrant=yes
else else
...@@ -3193,12 +3221,12 @@ EOF ...@@ -3193,12 +3221,12 @@ EOF
esac esac
echo $ac_n "checking for struct hostent_data""... $ac_c" 1>&6 echo $ac_n "checking for struct hostent_data""... $ac_c" 1>&6
echo "configure:3197: checking for struct hostent_data" >&5 echo "configure:3225: checking for struct hostent_data" >&5
if eval "test \"`echo '$''{'libjava_cv_struct_hostent_data'+set}'`\" = set"; then if eval "test \"`echo '$''{'libjava_cv_struct_hostent_data'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3202 "configure" #line 3230 "configure"
#include "confdefs.h" #include "confdefs.h"
#if GETHOSTBYNAME_R_NEEDS_REENTRANT && !defined(_REENTRANT) #if GETHOSTBYNAME_R_NEEDS_REENTRANT && !defined(_REENTRANT)
...@@ -3209,7 +3237,7 @@ int main() { ...@@ -3209,7 +3237,7 @@ int main() {
struct hostent_data data; struct hostent_data data;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3213: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3241: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
libjava_cv_struct_hostent_data=yes libjava_cv_struct_hostent_data=yes
else else
...@@ -3238,12 +3266,12 @@ done ...@@ -3238,12 +3266,12 @@ done
for ac_func in gethostbyaddr_r for ac_func in gethostbyaddr_r
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3242: checking for $ac_func" >&5 echo "configure:3270: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3247 "configure" #line 3275 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -3266,7 +3294,7 @@ $ac_func(); ...@@ -3266,7 +3294,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3298: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -3293,7 +3321,7 @@ EOF ...@@ -3293,7 +3321,7 @@ EOF
# We look for the one that returns `int'. # We look for the one that returns `int'.
# Hopefully this check is robust enough. # Hopefully this check is robust enough.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3297 "configure" #line 3325 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <netdb.h> #include <netdb.h>
EOF EOF
...@@ -3317,12 +3345,12 @@ done ...@@ -3317,12 +3345,12 @@ done
for ac_func in gethostname for ac_func in gethostname
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3321: checking for $ac_func" >&5 echo "configure:3349: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3326 "configure" #line 3354 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -3345,7 +3373,7 @@ $ac_func(); ...@@ -3345,7 +3373,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3349: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3377: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -3369,7 +3397,7 @@ EOF ...@@ -3369,7 +3397,7 @@ EOF
EOF EOF
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3373 "configure" #line 3401 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <unistd.h> #include <unistd.h>
EOF EOF
...@@ -3396,12 +3424,12 @@ done ...@@ -3396,12 +3424,12 @@ done
for ac_func in pthread_mutexattr_settype pthread_mutexattr_setkind_np for ac_func in pthread_mutexattr_settype pthread_mutexattr_setkind_np
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3400: checking for $ac_func" >&5 echo "configure:3428: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3405 "configure" #line 3433 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -3424,7 +3452,7 @@ $ac_func(); ...@@ -3424,7 +3452,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3428: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3456: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -3454,12 +3482,12 @@ done ...@@ -3454,12 +3482,12 @@ done
for ac_func in sched_yield for ac_func in sched_yield
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3458: checking for $ac_func" >&5 echo "configure:3486: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3463 "configure" #line 3491 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -3482,7 +3510,7 @@ $ac_func(); ...@@ -3482,7 +3510,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3486: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -3504,7 +3532,7 @@ EOF ...@@ -3504,7 +3532,7 @@ EOF
else else
echo "$ac_t""no" 1>&6 echo "$ac_t""no" 1>&6
echo $ac_n "checking for sched_yield in -lposix4""... $ac_c" 1>&6 echo $ac_n "checking for sched_yield in -lposix4""... $ac_c" 1>&6
echo "configure:3508: checking for sched_yield in -lposix4" >&5 echo "configure:3536: checking for sched_yield in -lposix4" >&5
ac_lib_var=`echo posix4'_'sched_yield | sed 'y%./+-%__p_%'` ac_lib_var=`echo posix4'_'sched_yield | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
...@@ -3512,7 +3540,7 @@ else ...@@ -3512,7 +3540,7 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-lposix4 $LIBS" LIBS="-lposix4 $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3516 "configure" #line 3544 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2 /* We use char because int might match the return type of a gcc2
...@@ -3523,7 +3551,7 @@ int main() { ...@@ -3523,7 +3551,7 @@ int main() {
sched_yield() sched_yield()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3527: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3555: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
...@@ -3548,7 +3576,7 @@ else ...@@ -3548,7 +3576,7 @@ else
echo "$ac_t""no" 1>&6 echo "$ac_t""no" 1>&6
echo $ac_n "checking for sched_yield in -lrt""... $ac_c" 1>&6 echo $ac_n "checking for sched_yield in -lrt""... $ac_c" 1>&6
echo "configure:3552: checking for sched_yield in -lrt" >&5 echo "configure:3580: checking for sched_yield in -lrt" >&5
ac_lib_var=`echo rt'_'sched_yield | sed 'y%./+-%__p_%'` ac_lib_var=`echo rt'_'sched_yield | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
...@@ -3556,7 +3584,7 @@ else ...@@ -3556,7 +3584,7 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-lrt $LIBS" LIBS="-lrt $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3560 "configure" #line 3588 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2 /* We use char because int might match the return type of a gcc2
...@@ -3567,7 +3595,7 @@ int main() { ...@@ -3567,7 +3595,7 @@ int main() {
sched_yield() sched_yield()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3571: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3599: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
...@@ -3604,12 +3632,12 @@ done ...@@ -3604,12 +3632,12 @@ done
for ac_func in gettimeofday time ftime for ac_func in gettimeofday time ftime
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3608: checking for $ac_func" >&5 echo "configure:3636: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3613 "configure" #line 3641 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -3632,7 +3660,7 @@ $ac_func(); ...@@ -3632,7 +3660,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3636: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3664: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -3663,12 +3691,12 @@ done ...@@ -3663,12 +3691,12 @@ done
for ac_func in memmove for ac_func in memmove
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3667: checking for $ac_func" >&5 echo "configure:3695: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3672 "configure" #line 3700 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -3691,7 +3719,7 @@ $ac_func(); ...@@ -3691,7 +3719,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3695: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3723: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -3721,12 +3749,12 @@ done ...@@ -3721,12 +3749,12 @@ done
for ac_func in memcpy for ac_func in memcpy
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3725: checking for $ac_func" >&5 echo "configure:3753: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3730 "configure" #line 3758 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -3749,7 +3777,7 @@ $ac_func(); ...@@ -3749,7 +3777,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3753: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3781: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -3797,7 +3825,7 @@ done ...@@ -3797,7 +3825,7 @@ done
#-------------------------------------------------------------------- #--------------------------------------------------------------------
echo $ac_n "checking for socket libraries""... $ac_c" 1>&6 echo $ac_n "checking for socket libraries""... $ac_c" 1>&6
echo "configure:3801: checking for socket libraries" >&5 echo "configure:3829: checking for socket libraries" >&5
if eval "test \"`echo '$''{'gcj_cv_lib_sockets'+set}'`\" = set"; then if eval "test \"`echo '$''{'gcj_cv_lib_sockets'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -3805,12 +3833,12 @@ else ...@@ -3805,12 +3833,12 @@ else
gcj_checkBoth=0 gcj_checkBoth=0
unset ac_cv_func_connect unset ac_cv_func_connect
echo $ac_n "checking for connect""... $ac_c" 1>&6 echo $ac_n "checking for connect""... $ac_c" 1>&6
echo "configure:3809: checking for connect" >&5 echo "configure:3837: checking for connect" >&5
if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3814 "configure" #line 3842 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char connect(); below. */ which can conflict with char connect(); below. */
...@@ -3833,7 +3861,7 @@ connect(); ...@@ -3833,7 +3861,7 @@ connect();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3837: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_connect=yes" eval "ac_cv_func_connect=yes"
else else
...@@ -3856,7 +3884,7 @@ fi ...@@ -3856,7 +3884,7 @@ fi
if test "$gcj_checkSocket" = 1; then if test "$gcj_checkSocket" = 1; then
unset ac_cv_func_connect unset ac_cv_func_connect
echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6 echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6
echo "configure:3860: checking for main in -lsocket" >&5 echo "configure:3888: checking for main in -lsocket" >&5
ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'` ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
...@@ -3864,14 +3892,14 @@ else ...@@ -3864,14 +3892,14 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS" LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3868 "configure" #line 3896 "configure"
#include "confdefs.h" #include "confdefs.h"
int main() { int main() {
main() main()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3875: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3903: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
...@@ -3898,12 +3926,12 @@ fi ...@@ -3898,12 +3926,12 @@ fi
LIBS="$LIBS -lsocket -lnsl" LIBS="$LIBS -lsocket -lnsl"
unset ac_cv_func_accept unset ac_cv_func_accept
echo $ac_n "checking for accept""... $ac_c" 1>&6 echo $ac_n "checking for accept""... $ac_c" 1>&6
echo "configure:3902: checking for accept" >&5 echo "configure:3930: checking for accept" >&5
if eval "test \"`echo '$''{'ac_cv_func_accept'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_accept'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3907 "configure" #line 3935 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char accept(); below. */ which can conflict with char accept(); below. */
...@@ -3926,7 +3954,7 @@ accept(); ...@@ -3926,7 +3954,7 @@ accept();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_accept=yes" eval "ac_cv_func_accept=yes"
else else
...@@ -3953,12 +3981,12 @@ fi ...@@ -3953,12 +3981,12 @@ fi
gcj_oldLibs=$LIBS gcj_oldLibs=$LIBS
LIBS="$LIBS $gcj_cv_lib_sockets" LIBS="$LIBS $gcj_cv_lib_sockets"
echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
echo "configure:3957: checking for gethostbyname" >&5 echo "configure:3985: checking for gethostbyname" >&5
if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3962 "configure" #line 3990 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char gethostbyname(); below. */ which can conflict with char gethostbyname(); below. */
...@@ -3981,7 +4009,7 @@ gethostbyname(); ...@@ -3981,7 +4009,7 @@ gethostbyname();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3985: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:4013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_gethostbyname=yes" eval "ac_cv_func_gethostbyname=yes"
else else
...@@ -3999,7 +4027,7 @@ if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then ...@@ -3999,7 +4027,7 @@ if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
else else
echo "$ac_t""no" 1>&6 echo "$ac_t""no" 1>&6
echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6 echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
echo "configure:4003: checking for main in -lnsl" >&5 echo "configure:4031: checking for main in -lnsl" >&5
ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'` ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
...@@ -4007,14 +4035,14 @@ else ...@@ -4007,14 +4035,14 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS" LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4011 "configure" #line 4039 "configure"
#include "confdefs.h" #include "confdefs.h"
int main() { int main() {
main() main()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4018: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:4046: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
...@@ -4044,9 +4072,13 @@ fi ...@@ -4044,9 +4072,13 @@ fi
echo "$ac_t""$gcj_cv_lib_sockets" 1>&6 echo "$ac_t""$gcj_cv_lib_sockets" 1>&6
SYSTEMSPEC="$SYSTEMSPEC $gcj_cv_lib_sockets" SYSTEMSPEC="$SYSTEMSPEC $gcj_cv_lib_sockets"
if test "$enable_interpreter" = yes; then
INTERPSPEC=
fi
if test "$with_system_zlib" = yes; then if test "$with_system_zlib" = yes; then
echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6 echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6
echo "configure:4050: checking for deflate in -lz" >&5 echo "configure:4082: checking for deflate in -lz" >&5
ac_lib_var=`echo z'_'deflate | sed 'y%./+-%__p_%'` ac_lib_var=`echo z'_'deflate | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
...@@ -4054,7 +4086,7 @@ else ...@@ -4054,7 +4086,7 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-lz $LIBS" LIBS="-lz $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4058 "configure" #line 4090 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2 /* We use char because int might match the return type of a gcc2
...@@ -4065,7 +4097,7 @@ int main() { ...@@ -4065,7 +4097,7 @@ int main() {
deflate() deflate()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4069: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:4101: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
...@@ -4094,7 +4126,7 @@ fi ...@@ -4094,7 +4126,7 @@ fi
# requires -ldl. # requires -ldl.
if test "$GC" = boehm; then if test "$GC" = boehm; then
echo $ac_n "checking for main in -ldl""... $ac_c" 1>&6 echo $ac_n "checking for main in -ldl""... $ac_c" 1>&6
echo "configure:4098: checking for main in -ldl" >&5 echo "configure:4130: checking for main in -ldl" >&5
ac_lib_var=`echo dl'_'main | sed 'y%./+-%__p_%'` ac_lib_var=`echo dl'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
...@@ -4102,14 +4134,14 @@ else ...@@ -4102,14 +4134,14 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-ldl $LIBS" LIBS="-ldl $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4106 "configure" #line 4138 "configure"
#include "confdefs.h" #include "confdefs.h"
int main() { int main() {
main() main()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4113: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:4145: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
...@@ -4219,17 +4251,17 @@ for ac_hdr in unistd.h bstring.h sys/time.h sys/types.h fcntl.h sys/ioctl.h sys/ ...@@ -4219,17 +4251,17 @@ for ac_hdr in unistd.h bstring.h sys/time.h sys/types.h fcntl.h sys/ioctl.h sys/
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:4223: checking for $ac_hdr" >&5 echo "configure:4255: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4228 "configure" #line 4260 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4233: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:4265: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -4259,17 +4291,17 @@ for ac_hdr in dirent.h ...@@ -4259,17 +4291,17 @@ for ac_hdr in dirent.h
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:4263: checking for $ac_hdr" >&5 echo "configure:4295: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4268 "configure" #line 4300 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4273: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:4305: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -4297,16 +4329,16 @@ done ...@@ -4297,16 +4329,16 @@ done
echo $ac_n "checking whether struct sockaddr_in6 is in netinet/in.h""... $ac_c" 1>&6 echo $ac_n "checking whether struct sockaddr_in6 is in netinet/in.h""... $ac_c" 1>&6
echo "configure:4301: checking whether struct sockaddr_in6 is in netinet/in.h" >&5 echo "configure:4333: checking whether struct sockaddr_in6 is in netinet/in.h" >&5
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4303 "configure" #line 4335 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <netinet/in.h> #include <netinet/in.h>
int main() { int main() {
struct sockaddr_in6 addr6; struct sockaddr_in6 addr6;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4310: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:4342: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
cat >> confdefs.h <<\EOF cat >> confdefs.h <<\EOF
#define HAVE_INET6 1 #define HAVE_INET6 1
...@@ -4322,16 +4354,16 @@ fi ...@@ -4322,16 +4354,16 @@ fi
rm -f conftest* rm -f conftest*
echo $ac_n "checking for socklen_t in sys/socket.h""... $ac_c" 1>&6 echo $ac_n "checking for socklen_t in sys/socket.h""... $ac_c" 1>&6
echo "configure:4326: checking for socklen_t in sys/socket.h" >&5 echo "configure:4358: checking for socklen_t in sys/socket.h" >&5
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4328 "configure" #line 4360 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/socket.h> #include <sys/socket.h>
int main() { int main() {
socklen_t x = 5; socklen_t x = 5;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4335: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:4367: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
cat >> confdefs.h <<\EOF cat >> confdefs.h <<\EOF
#define HAVE_SOCKLEN_T 1 #define HAVE_SOCKLEN_T 1
...@@ -4347,16 +4379,16 @@ fi ...@@ -4347,16 +4379,16 @@ fi
rm -f conftest* rm -f conftest*
echo $ac_n "checking for tm_gmtoff in struct tm""... $ac_c" 1>&6 echo $ac_n "checking for tm_gmtoff in struct tm""... $ac_c" 1>&6
echo "configure:4351: checking for tm_gmtoff in struct tm" >&5 echo "configure:4383: checking for tm_gmtoff in struct tm" >&5
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4353 "configure" #line 4385 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <time.h> #include <time.h>
int main() { int main() {
struct tm tim; tim.tm_gmtoff = 0; struct tm tim; tim.tm_gmtoff = 0;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4360: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:4392: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
cat >> confdefs.h <<\EOF cat >> confdefs.h <<\EOF
#define STRUCT_TM_HAS_GMTOFF 1 #define STRUCT_TM_HAS_GMTOFF 1
...@@ -4369,16 +4401,16 @@ else ...@@ -4369,16 +4401,16 @@ else
rm -rf conftest* rm -rf conftest*
echo "$ac_t""no" 1>&6 echo "$ac_t""no" 1>&6
echo $ac_n "checking for global timezone variable""... $ac_c" 1>&6 echo $ac_n "checking for global timezone variable""... $ac_c" 1>&6
echo "configure:4373: checking for global timezone variable" >&5 echo "configure:4405: checking for global timezone variable" >&5
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4375 "configure" #line 4407 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <time.h> #include <time.h>
int main() { int main() {
long z2 = timezone; long z2 = timezone;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4382: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:4414: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
cat >> confdefs.h <<\EOF cat >> confdefs.h <<\EOF
#define HAVE_TIMEZONE 1 #define HAVE_TIMEZONE 1
...@@ -4398,19 +4430,19 @@ rm -f conftest* ...@@ -4398,19 +4430,19 @@ rm -f conftest*
# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
# for constant arguments. Useless! # for constant arguments. Useless!
echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
echo "configure:4402: checking for working alloca.h" >&5 echo "configure:4434: checking for working alloca.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4407 "configure" #line 4439 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <alloca.h> #include <alloca.h>
int main() { int main() {
char *p = alloca(2 * sizeof(int)); char *p = alloca(2 * sizeof(int));
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4414: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:4446: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
ac_cv_header_alloca_h=yes ac_cv_header_alloca_h=yes
else else
...@@ -4431,12 +4463,12 @@ EOF ...@@ -4431,12 +4463,12 @@ EOF
fi fi
echo $ac_n "checking for alloca""... $ac_c" 1>&6 echo $ac_n "checking for alloca""... $ac_c" 1>&6
echo "configure:4435: checking for alloca" >&5 echo "configure:4467: checking for alloca" >&5
if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4440 "configure" #line 4472 "configure"
#include "confdefs.h" #include "confdefs.h"
#ifdef __GNUC__ #ifdef __GNUC__
...@@ -4464,7 +4496,7 @@ int main() { ...@@ -4464,7 +4496,7 @@ int main() {
char *p = (char *) alloca(1); char *p = (char *) alloca(1);
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4468: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:4500: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
ac_cv_func_alloca_works=yes ac_cv_func_alloca_works=yes
else else
...@@ -4496,12 +4528,12 @@ EOF ...@@ -4496,12 +4528,12 @@ EOF
echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
echo "configure:4500: checking whether alloca needs Cray hooks" >&5 echo "configure:4532: checking whether alloca needs Cray hooks" >&5
if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4505 "configure" #line 4537 "configure"
#include "confdefs.h" #include "confdefs.h"
#if defined(CRAY) && ! defined(CRAY2) #if defined(CRAY) && ! defined(CRAY2)
webecray webecray
...@@ -4526,12 +4558,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6 ...@@ -4526,12 +4558,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
if test $ac_cv_os_cray = yes; then if test $ac_cv_os_cray = yes; then
for ac_func in _getb67 GETB67 getb67; do for ac_func in _getb67 GETB67 getb67; do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:4530: checking for $ac_func" >&5 echo "configure:4562: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4535 "configure" #line 4567 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -4554,7 +4586,7 @@ $ac_func(); ...@@ -4554,7 +4586,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4558: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:4590: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -4581,7 +4613,7 @@ done ...@@ -4581,7 +4613,7 @@ done
fi fi
echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
echo "configure:4585: checking stack direction for C alloca" >&5 echo "configure:4617: checking stack direction for C alloca" >&5
if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -4589,7 +4621,7 @@ else ...@@ -4589,7 +4621,7 @@ else
ac_cv_c_stack_direction=0 ac_cv_c_stack_direction=0
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4593 "configure" #line 4625 "configure"
#include "confdefs.h" #include "confdefs.h"
find_stack_direction () find_stack_direction ()
{ {
...@@ -4608,7 +4640,7 @@ main () ...@@ -4608,7 +4640,7 @@ main ()
exit (find_stack_direction() < 0); exit (find_stack_direction() < 0);
} }
EOF EOF
if { (eval echo configure:4612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null if { (eval echo configure:4644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then then
ac_cv_c_stack_direction=1 ac_cv_c_stack_direction=1
else else
...@@ -4635,7 +4667,7 @@ do ...@@ -4635,7 +4667,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args. # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2 set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:4639: checking for $ac_word" >&5 echo "configure:4671: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_PERL'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_PERL'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -4868,6 +4900,7 @@ s%@LIBTOOL@%$LIBTOOL%g ...@@ -4868,6 +4900,7 @@ s%@LIBTOOL@%$LIBTOOL%g
s%@COMPPATH@%$COMPPATH%g s%@COMPPATH@%$COMPPATH%g
s%@TESTSUBDIR_TRUE@%$TESTSUBDIR_TRUE%g s%@TESTSUBDIR_TRUE@%$TESTSUBDIR_TRUE%g
s%@TESTSUBDIR_FALSE@%$TESTSUBDIR_FALSE%g s%@TESTSUBDIR_FALSE@%$TESTSUBDIR_FALSE%g
s%@INTERPSPEC@%$INTERPSPEC%g
s%@CPP@%$CPP%g s%@CPP@%$CPP%g
s%@SYSTEMSPEC@%$SYSTEMSPEC%g s%@SYSTEMSPEC@%$SYSTEMSPEC%g
s%@ZLIBSPEC@%$ZLIBSPEC%g s%@ZLIBSPEC@%$ZLIBSPEC%g
......
...@@ -42,6 +42,17 @@ AC_ARG_ENABLE(libgcj-debug, ...@@ -42,6 +42,17 @@ AC_ARG_ENABLE(libgcj-debug,
AC_DEFINE(DEBUG) AC_DEFINE(DEBUG)
fi) fi)
dnl See if the user has the enterpreter included.
AC_ARG_ENABLE(interpreter,
[ --enable-interpreter Enable interpreter],
if test "$enable_interpreter" = yes; then
AC_DEFINE(INTERPRETER)
fi)
dnl This becomes -lffi if the interpreter is enables
INTERPSPEC=
AC_SUBST(INTERPSPEC)
dnl If the target is an eCos system, use the appropriate eCos dnl If the target is an eCos system, use the appropriate eCos
dnl I/O routines. dnl I/O routines.
dnl FIXME: this should not be a local option but a global target dnl FIXME: this should not be a local option but a global target
...@@ -447,6 +458,10 @@ else ...@@ -447,6 +458,10 @@ else
]) ])
SYSTEMSPEC="$SYSTEMSPEC $gcj_cv_lib_sockets" SYSTEMSPEC="$SYSTEMSPEC $gcj_cv_lib_sockets"
if test "$enable_interpreter" = yes; then
INTERPSPEC=
fi
if test "$with_system_zlib" = yes; then if test "$with_system_zlib" = yes; then
AC_CHECK_LIB(z, deflate, ZLIBSPEC=-lz, ZLIBSPEC=-lzgcj) AC_CHECK_LIB(z, deflate, ZLIBSPEC=-lz, ZLIBSPEC=-lzgcj)
else else
......
// defineclass.cc - defining a class from .class format.
/* Copyright (C) 1999 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. */
/*
Author: Kresten Krab Thorup <krab@gnu.org>
Written using the online versions of Java Language Specification (1st
ed.) and The Java Virtual Machine Specification (2nd ed.).
Future work may include reading (and handling) attributes which are
currently being ignored ("InnerClasses", "LineNumber", etc...).
*/
#include <java-interp.h>
#ifdef INTERPRETER
#include <java-cpool.h>
#include <cni.h>
#include <java/lang/Class.h>
#include <java/lang/Float.h>
#include <java/lang/Double.h>
#include <java/lang/Character.h>
#include <java/lang/LinkageError.h>
#include <java/lang/InternalError.h>
#include <java/lang/ClassFormatError.h>
#include <java/lang/NoClassDefFoundError.h>
#include <java/lang/ClassCircularityError.h>
#include <java/lang/ClassNotFoundException.h>
#include <java/lang/IncompatibleClassChangeError.h>
#define ClassClass _CL_Q34java4lang5Class
extern java::lang::Class ClassClass;
#define StringClass _CL_Q34java4lang6String
extern java::lang::Class StringClass;
#define ClassObject _CL_Q34java4lang6Object
extern java::lang::Class ClassObject;
// we don't verify method names that match these.
static _Jv_Utf8Const *clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
// these go in some seperate functions, to avoid having _Jv_InitClass
// inserted all over the place.
static void throw_internal_error (char *msg)
__attribute__ ((__noreturn__));
static void throw_no_class_def_found_error (jstring msg)
__attribute__ ((__noreturn__));
static void throw_no_class_def_found_error (char *msg)
__attribute__ ((__noreturn__));
static void throw_class_format_error (jstring msg)
__attribute__ ((__noreturn__));
static void throw_class_format_error (char *msg)
__attribute__ ((__noreturn__));
static void throw_incompatible_class_change_error (jstring msg)
__attribute__ ((__noreturn__));
static void throw_class_circularity_error (jstring msg)
__attribute__ ((__noreturn__));
static jdouble long_bits_to_double (jlong);
static jfloat int_bits_to_float (jint);
/**
* We define class reading using a class. It is practical, since then
* the entire class-reader can be a friend of class Class (it needs to
* write all it's different structures); but also because this makes it
* easy to make class definition reentrant, and thus two threads can be
* defining classes at the same time. This class (_Jv_ClassReader) is
* never exposed outside this file, so we don't have to worry about
* public or private members here.
*/
struct _Jv_ClassReader {
// do verification? Currently, there is no option to disable this.
// This flag just controls the verificaiton done by the class loader;
// i.e., checking the integrity of the constant pool; and it is
// allways on. You always want this as far as I can see, but it also
// controls weither identifiers and type descriptors/signatures are
// verified as legal. This could be somewhat more expensive since it
// will call Characher.isJavaIdentifier{Start,Part} for each character
// in any identifier (field name or method name) it comes by. Thus,
// it might be useful to turn off this verification for classes that
// come from a trusted source. However, for GCJ, trusted classes are
// most likely to be linked in.
bool verify;
// input data.
unsigned char *bytes;
int len;
// current input position
int pos;
// the constant pool data
int pool_count;
unsigned char *tags;
unsigned int *offsets;
// the class to define (see java-interp.h)
_Jv_InterpClass *def;
/* check that the given number of input bytes are available */
inline void check (int num)
{
if (pos + num > len)
throw_class_format_error ("Premature end of data");
}
/* skip a given number of bytes in input */
inline void skip (int num)
{
check (num);
pos += num;
}
/* read an unsignend 1-byte unit */
inline static jint get1u (unsigned char* bytes)
{
return bytes[0];
}
/* read an unsigned 1-byte unit */
inline jint read1u ()
{
skip (1);
return get1u (bytes+pos-1);
}
/* read an unsigned 2-byte unit */
inline static jint get2u (unsigned char *bytes)
{
return (((jint)bytes[0]) << 8) | ((jint)bytes[1]);
}
/* read an unsigned 2-byte unit */
inline jint read2u ()
{
skip (2);
return get2u (bytes+pos-2);
}
/* read a 4-byte unit */
static jint get4 (unsigned char *bytes)
{
return (((jint)bytes[0]) << 24)
| (((jint)bytes[1]) << 16)
| (((jint)bytes[2]) << 8)
| (((jint)bytes[3]) << 0);
}
/* read a 4-byte unit, (we don't do that quite so often) */
inline jint read4 ()
{
skip (4);
return get4 (bytes+pos-4);
}
/* read a 8-byte unit */
static jlong get8 (unsigned char* bytes)
{
return (((jlong)bytes[0]) << 56)
| (((jlong)bytes[1]) << 48)
| (((jlong)bytes[2]) << 40)
| (((jlong)bytes[3]) << 32)
| (((jlong)bytes[4]) << 24)
| (((jlong)bytes[5]) << 16)
| (((jlong)bytes[6]) << 8)
| (((jlong)bytes[7]) << 0);
}
/* read a 8-byte unit */
inline jlong read8 ()
{
skip (8);
return get8 (bytes+pos-8);
}
inline void check_tag (int index, char expected_tag)
{
if (index < 0
|| index > pool_count
|| tags[index] != expected_tag)
throw_class_format_error ("erroneous constant pool tag");
}
_Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length)
{
if (klass == 0 || length < 0 || offset+length > data->length)
throw_internal_error ("arguments to _Jv_DefineClass");
verify = true;
bytes = (unsigned char*) (elements (data)+offset);
len = length;
pos = 0;
def = (_Jv_InterpClass*) klass;
}
/** and here goes the parser members defined out-of-line */
void parse ();
void read_constpool ();
void prepare_pool_entry (int index, unsigned char tag);
void read_fields ();
void read_methods ();
void read_one_class_attribute ();
void read_one_method_attribute (int method);
void read_one_code_attribute (int method);
void read_one_field_attribute (int field);
/** check an utf8 entry, without creating a Utf8Const object */
bool is_attribute_name (int index, char *name);
/** here goes the class-loader members defined out-of-line */
void handleConstantPool ();
void handleClassBegin (int, int, int);
void handleInterfacesBegin (int);
void handleInterface (int, int);
void handleFieldsBegin (int);
void handleField (int, int, int, int);
void handleFieldsEnd ();
void handleConstantValueAttribute (int,int);
void handleMethodsBegin (int);
void handleMethod (int, int, int, int);
void handleMethodsEnd ();
void handleCodeAttribute (int, int, int, int, int, int);
void handleExceptionTableEntry (int, int, int, int, int, int);
void checkExtends (jclass sub, jclass super);
void checkImplements (jclass sub, jclass super);
/*
* FIXME: we should keep a hash table of utf8-strings, since many will
* be the same. It's a little tricky, however, because the hash table
* needs to interact gracefully with the garbage collector. Much
* memory is to be saved by this, however! perhaps the improvement
* could be implemented in prims.cc (_Jv_makeUtf8Const), since it
* computes the hash value anyway.
*/
static const int PUBLIC = 0x001;
static const int PRIVATE = 0x002;
static const int PROTECTED = 0x004;
static const int STATIC = 0x008;
static const int FINAL = 0x010;
static const int SYNCHRONIZED = 0x020;
static const int VOLATILE = 0x040;
static const int TRANSIENT = 0x080;
static const int NATIVE = 0x100;
static const int INTERFACE = 0x200;
static const int ABSTRACT = 0x400;
static const int ALL_FLAGS = 0x7FF;
};
/* This is used for the isJavaIdentifierStart & isJavaIdentifierPart
methods, so we avoid doing _Jv_InitClass all the time */
static const java::lang::Character *character = 0;
static void prepare_character ();
void
_Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length)
{
if (character == 0)
prepare_character ();
_Jv_ClassReader reader (klass, data, offset, length);
reader.parse();
/* that's it! */
}
/** put it after _Jv_DefineClass, so it doesn't get inlined */
static void prepare_character ()
{
character = new java::lang::Character ('!');
}
/** This section defines the parsing/scanning of the class data */
void
_Jv_ClassReader::parse ()
{
int magic = read4 ();
/* FIXME: Decide which range of version numbers to allow */
/* int minor_version = */ read2u ();
/* int major_verson = */ read2u ();
if (magic != (int) 0xCAFEBABE)
throw_class_format_error ("bad magic number");
pool_count = read2u ();
read_constpool ();
int access_flags = read2u ();
int this_class = read2u ();
int super_class = read2u ();
check_tag (this_class, JV_CONSTANT_Class);
if (super_class != 0)
check_tag (super_class, JV_CONSTANT_Class);
handleClassBegin (access_flags, this_class, super_class);
int interfaces_count = read2u ();
handleInterfacesBegin (interfaces_count);
for (int i = 0; i < interfaces_count; i++)
{
int iface = read2u ();
check_tag (iface, JV_CONSTANT_Class);
handleInterface (i, iface);
}
read_fields ();
read_methods ();
int attributes_count = read2u ();
for (int i = 0; i < attributes_count; i++)
{
read_one_class_attribute ();
}
if (pos != len)
throw_class_format_error ("unused data before end of file");
// tell everyone we're done.
def->state = JV_STATE_LOADED;
def->notifyAll ();
}
void _Jv_ClassReader::read_constpool ()
{
tags = (unsigned char*) _Jv_AllocBytesChecked (pool_count);
offsets = (unsigned int *) _Jv_AllocBytesChecked (sizeof (int)
* pool_count) ;
/** first, we scan the constant pool, collecting tags and offsets */
tags[0] = JV_CONSTANT_Undefined;
offsets[0] = pos;
for (int c = 1; c < pool_count; c++)
{
tags[c] = read1u ();
offsets[c] = pos;
switch (tags[c])
{
case JV_CONSTANT_String:
case JV_CONSTANT_Class:
skip (2);
break;
case JV_CONSTANT_Fieldref:
case JV_CONSTANT_Methodref:
case JV_CONSTANT_InterfaceMethodref:
case JV_CONSTANT_NameAndType:
case JV_CONSTANT_Integer:
case JV_CONSTANT_Float:
skip (4);
break;
case JV_CONSTANT_Double:
case JV_CONSTANT_Long:
skip (8);
tags[++c] = JV_CONSTANT_Undefined;
break;
case JV_CONSTANT_Utf8:
{
int len = read2u ();
skip (len);
}
break;
case JV_CONSTANT_Unicode:
throw_class_format_error ("unicode not supported");
break;
default:
throw_class_format_error ("erroneous constant pool tag");
}
}
handleConstantPool ();
}
void _Jv_ClassReader::read_fields ()
{
int fields_count = read2u ();
handleFieldsBegin (fields_count);
for (int i = 0; i < fields_count; i++)
{
int access_flags = read2u ();
int name_index = read2u ();
int descriptor_index = read2u ();
int attributes_count = read2u ();
check_tag (name_index, JV_CONSTANT_Utf8);
prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
check_tag (descriptor_index, JV_CONSTANT_Utf8);
prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
handleField (i, access_flags, name_index, descriptor_index);
for (int j = 0; j < attributes_count; j++)
{
read_one_field_attribute (i);
}
}
handleFieldsEnd ();
}
bool
_Jv_ClassReader::is_attribute_name (int index, char *name)
{
check_tag (index, JV_CONSTANT_Utf8);
int len = get2u (bytes+offsets[index]);
if (len != (int) strlen (name))
return false;
else
return !memcmp (bytes+offsets[index]+2, name, len);
}
void _Jv_ClassReader::read_one_field_attribute (int field_index)
{
int name = read2u ();
int length = read4 ();
if (is_attribute_name (name, "ConstantValue"))
{
int cv = read2u ();
if (cv < pool_count
&& cv > 0
&& (tags[cv] == JV_CONSTANT_Integer
|| tags[cv] == JV_CONSTANT_Float
|| tags[cv] == JV_CONSTANT_Long
|| tags[cv] == JV_CONSTANT_Double
|| tags[cv] == JV_CONSTANT_String))
{
handleConstantValueAttribute (field_index, cv);
}
else
{
throw_class_format_error ("erroneous ConstantValue attribute");
}
if (length != 2)
throw_class_format_error ("erroneous ConstantValue attribute");
}
else
{
skip (length);
}
}
void _Jv_ClassReader::read_methods ()
{
int methods_count = read2u ();
handleMethodsBegin (methods_count);
for (int i = 0; i < methods_count; i++)
{
int access_flags = read2u ();
int name_index = read2u ();
int descriptor_index = read2u ();
int attributes_count = read2u ();
check_tag (name_index, JV_CONSTANT_Utf8);
prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
check_tag (name_index, JV_CONSTANT_Utf8);
prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
handleMethod (i, access_flags, name_index,
descriptor_index);
for (int j = 0; j < attributes_count; j++)
{
read_one_method_attribute (i);
}
}
handleMethodsEnd ();
}
void _Jv_ClassReader::read_one_method_attribute (int method_index)
{
int name = read2u ();
int length = read4 ();
if (is_attribute_name (name, "Exceptions"))
{
/* we ignore this for now */
skip (length);
}
else if (is_attribute_name (name, "Code"))
{
int start_off = pos;
int max_stack = read2u ();
int max_locals = read2u ();
int code_length = read4 ();
int code_start = pos;
skip (code_length);
int exception_table_length = read2u ();
handleCodeAttribute (method_index,
max_stack, max_locals,
code_start, code_length,
exception_table_length);
for (int i = 0; i < exception_table_length; i++)
{
int start_pc = read2u ();
int end_pc = read2u ();
int handler_pc = read2u ();
int catch_type = read2u ();
if (start_pc > end_pc
|| start_pc < 0
|| end_pc >= code_length
|| handler_pc >= code_length)
throw_class_format_error ("erroneous exception handler info");
if (! (tags[catch_type] == JV_CONSTANT_Class
|| tags[catch_type] == 0))
{
throw_class_format_error ("erroneous exception handler info");
}
handleExceptionTableEntry (method_index,
i,
start_pc,
end_pc,
handler_pc,
catch_type);
}
int attributes_count = read2u ();
for (int i = 0; i < attributes_count; i++)
{
read_one_code_attribute (method_index);
}
if ((pos - start_off) != length)
throw_class_format_error ("code attribute too short");
}
else
{
/* ignore unknown attributes */
skip (length);
}
}
void _Jv_ClassReader::read_one_code_attribute (int /*method*/)
{
/* ignore for now, ... later we may want to pick up
line number information, for debugging purposes;
in fact, the whole debugger issue is open! */
/* int name = */ read2u ();
int length = read4 ();
skip (length);
}
void _Jv_ClassReader::read_one_class_attribute ()
{
/* we also ignore the class attributes, ...
some day we'll add inner-classes support. */
/* int name = */ read2u ();
int length = read4 ();
skip (length);
}
/* this section defines the semantic actions of the parser */
void _Jv_ClassReader::handleConstantPool ()
{
/** now, we actually define the class' constant pool */
// the pool is scanned explicitly by the collector
jbyte *pool_tags = (jbyte*) _Jv_AllocBytesChecked (pool_count);
void **pool_data = (void**) _Jv_AllocBytesChecked (pool_count * sizeof (void*));
def->constants.tags = pool_tags;
def->constants.data = pool_data;
def->constants.size = pool_count;
// Here we make a pass to collect the strings! We do this, because
// internally in the GCJ runtime, classes are encoded with .'s not /'s.
// Therefore, we first collect the strings, and then translate the rest
// of the utf8-entries (thus not representing strings) from /-notation
// to .-notation.
for (int i = 1; i < pool_count; i++)
{
if (tags[i] == JV_CONSTANT_String)
{
unsigned char* str_data = bytes + offsets [i];
int utf_index = get2u (str_data);
check_tag (utf_index, JV_CONSTANT_Utf8);
unsigned char *utf_data = bytes + offsets[utf_index];
int len = get2u (utf_data);
pool_data[i] = (void*)_Jv_makeUtf8Const ((char*)(utf_data+2), len);
pool_tags[i] = JV_CONSTANT_String;
}
else
{
pool_tags[i] = JV_CONSTANT_Undefined;
}
}
// and now, we scan everything else but strings & utf8-entries. This
// leaves out those utf8-entries which are not used; which will be left
// with a tag of JV_CONSTANT_Undefined in the class definition.
for (int index = 1; index < pool_count; index++)
{
switch (tags[index])
{
case JV_CONSTANT_Undefined:
case JV_CONSTANT_String:
case JV_CONSTANT_Utf8:
continue;
default:
prepare_pool_entry (index, tags[index]);
}
}
}
/* this is a recursive procedure, which will prepare pool entries as needed.
Which is how we avoid initializing those entries which go unused. */
void
_Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
{
/* these two, pool_data and pool_tags, point into the class
structure we are currently defining */
unsigned char *pool_tags = (unsigned char*) def->constants.tags;
void **pool_data = (void**) def->constants.data;
/* this entry was already prepared */
if (pool_tags[index] == this_tag)
return;
/* this_data points to the constant-pool information for the current
constant-pool entry */
unsigned char *this_data = bytes + offsets[index];
switch (this_tag)
{
case JV_CONSTANT_Utf8:
{
// If we came here, it is because some other tag needs this
// utf8-entry for type information! Thus, we translate /'s to .'s in
// order to accomondate gcj's internal representation.
int len = get2u (this_data);
char *buffer = (char*) alloca (len);
char *s = ((char*) this_data)+2;
/* FIXME: avoid using a buffer here */
for (int i = 0; i < len; i++)
{
if (s[i] == '/')
buffer[i] = '.';
else
buffer[i] = (char) s[i];
}
pool_data[index] = (void*)_Jv_makeUtf8Const (buffer, len);
pool_tags[index] = JV_CONSTANT_Utf8;
}
break;
case JV_CONSTANT_Class:
{
int utf_index = get2u (this_data);
check_tag (utf_index, JV_CONSTANT_Utf8);
prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
if (verify)
_Jv_VerifyClassName ((_Jv_Utf8Const*)pool_data[utf_index]);
pool_data[index] = pool_data[utf_index];
pool_tags[index] = JV_CONSTANT_Class;
}
break;
case JV_CONSTANT_String:
// already handled before...
break;
case JV_CONSTANT_Fieldref:
case JV_CONSTANT_Methodref:
case JV_CONSTANT_InterfaceMethodref:
{
int class_index = get2u (this_data);
int nat_index = get2u (this_data+2);
check_tag (class_index, JV_CONSTANT_Class);
prepare_pool_entry (class_index, JV_CONSTANT_Class);
check_tag (nat_index, JV_CONSTANT_NameAndType);
prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
// here, verify the signature and identifier name
if (verify)
{
_Jv_ushort name_index, type_index;
_Jv_loadIndexes ((const void**)&pool_data[nat_index],
name_index, type_index);
if (this_tag == JV_CONSTANT_Fieldref)
_Jv_VerifyFieldSignature
((_Jv_Utf8Const*)pool_data[type_index]);
else
_Jv_VerifyMethodSignature
((_Jv_Utf8Const*)pool_data[type_index]);
_Jv_Utf8Const* name = (_Jv_Utf8Const*)pool_data[name_index];
if (this_tag != JV_CONSTANT_Fieldref
&& ( _Jv_equalUtf8Consts (name, clinit_name)
|| _Jv_equalUtf8Consts (name, init_name)))
/* ignore */;
else
_Jv_VerifyIdentifier ((_Jv_Utf8Const*)pool_data[name_index]);
}
_Jv_storeIndexes (&pool_data[index], class_index, nat_index);
pool_tags[index] = this_tag;
}
break;
case JV_CONSTANT_NameAndType:
{
_Jv_ushort name_index = get2u (this_data);
_Jv_ushort type_index = get2u (this_data+2);
check_tag (name_index, JV_CONSTANT_Utf8);
prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
check_tag (type_index, JV_CONSTANT_Utf8);
prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
_Jv_storeIndexes (&pool_data[index], name_index, type_index);
pool_tags[index] = JV_CONSTANT_NameAndType;
}
break;
case JV_CONSTANT_Float:
{
jfloat f = int_bits_to_float ((jint) get4 (this_data));
_Jv_storeFloat (&pool_data[index], f);
pool_tags[index] = JV_CONSTANT_Float;
}
break;
case JV_CONSTANT_Integer:
{
int i = get4 (this_data);
_Jv_storeInt (&pool_data[index], i);
pool_tags[index] = JV_CONSTANT_Integer;
}
break;
case JV_CONSTANT_Double:
{
jdouble d = long_bits_to_double ((jlong) get8 (this_data));
_Jv_storeDouble (&pool_data[index], d);
pool_tags[index] = JV_CONSTANT_Double;
}
break;
case JV_CONSTANT_Long:
{
jlong i = get8 (this_data);
_Jv_storeLong (&pool_data[index], i);
pool_tags[index] = JV_CONSTANT_Long;
}
break;
default:
throw_class_format_error ("erroneous constant pool tag");
}
}
void
_Jv_ClassReader::handleClassBegin
(int access_flags, int this_class, int super_class)
{
unsigned char *pool_tags = (unsigned char*) def->constants.tags;
void **pool_data = (void**) def->constants.data;
check_tag (this_class, JV_CONSTANT_Class);
_Jv_Utf8Const *loadedName = (_Jv_Utf8Const*)pool_data[this_class];
// was ClassLoader.defineClass called with an expected class name?
if (def->name == 0)
{
jclass orig = _Jv_FindClassInCache (loadedName, def->loader);
if (orig == 0)
{
def->name = loadedName;
}
else
{
jstring msg = JvNewStringUTF ("anonymous "
"class data denotes "
"existing class ");
msg = msg->concat (orig->getName ());
throw_no_class_def_found_error (msg);
}
}
// assert that the loaded class has the expected name, 5.3.5
else if (! _Jv_equalUtf8Consts (loadedName, def->name))
{
jstring msg = JvNewStringUTF ("loaded class ");
msg = msg->concat (def->getName ());
msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
jstring klass_name = _Jv_NewStringUTF (loadedName->data);
msg = msg->concat (klass_name);
throw_no_class_def_found_error (msg);
}
def->accflags = access_flags;
pool_data[this_class] = (void*)def;
pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
if (super_class == 0)
{
// interfaces have java.lang.Object as super.
if (access_flags & INTERFACE)
{
def->superclass = (jclass)&ClassObject;
}
// FIXME: Consider this carefully!
else if (!_Jv_equalUtf8Consts (def->name, ClassObject.name))
{
throw_no_class_def_found_error ("loading java.lang.Object");
}
}
// In the pre-loading state, it can be looked up in the
// cache only by this thread! This allows the super-class
// to include references to this class.
def->state = JV_STATE_PRELOADING;
_Jv_RegisterClass (def);
if (super_class != 0)
{
// load the super class
check_tag (super_class, JV_CONSTANT_Class);
_Jv_Utf8Const* super_name =
(_Jv_Utf8Const*)pool_data[super_class];
// load the super class using our defining loader
jclass the_super = _Jv_FindClass (super_name,
def->loader);
// This will establish that we are allowed to be a subclass,
// and check for class circularity error
checkExtends (def, the_super);
def->superclass = the_super;
pool_data[super_class] = (void*) the_super;
pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
}
// now we've come past the circularity problem, we can
// now say that we're loading...
def->state = JV_STATE_LOADING;
def->notifyAll ();
}
///// implements the checks described in sect. 5.3.5.3
void
_Jv_ClassReader::checkExtends (jclass sub, jclass super)
{
// having an interface or a final class as a superclass is no good
if ((super->accflags & (INTERFACE | FINAL)) != 0)
{
throw_incompatible_class_change_error (sub->getName ());
}
// if the super class is not public, we need to check some more
if ((super->accflags & PUBLIC) == 0)
{
// With package scope, the classes must have the same
// class loader.
if ( sub->loader != super->loader
|| !_Jv_ClassNameSamePackage (sub->name, super->name))
{
throw_incompatible_class_change_error (sub->getName ());
}
}
for (; super != 0; super = super->superclass)
{
if (super == sub)
throw_class_circularity_error (sub->getName ());
}
}
void _Jv_ClassReader::handleInterfacesBegin (int count)
{
def->interfaces = (jclass*) _Jv_AllocBytesChecked (count*sizeof (jclass));
def->interface_count = count;
}
void _Jv_ClassReader::handleInterface (int if_number, int offset)
{
void ** pool_data = def->constants.data;
unsigned char * pool_tags = (unsigned char*) def->constants.tags;
jclass the_interface;
if (pool_tags[offset] == JV_CONSTANT_Class)
{
_Jv_Utf8Const* name = (_Jv_Utf8Const*) pool_data[offset];
the_interface = _Jv_FindClass (name, def->loader);
}
else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
{
the_interface = (jclass)pool_data[offset];
}
else
{
throw_no_class_def_found_error ("erroneous constant pool tag");
}
// checks the validity of the_interface, and that we are in fact
// allowed to implement that interface.
checkImplements (def, the_interface);
pool_data[offset] = (void*)the_interface;
pool_tags[offset] = JV_CONSTANT_ResolvedClass;
def->interfaces[if_number] = the_interface;
}
void
_Jv_ClassReader::checkImplements (jclass sub, jclass super)
{
// well, it *must* be an interface
if ((super->accflags & INTERFACE) == 0)
{
throw_incompatible_class_change_error (sub->getName ());
}
// if it has package scope, it must also be defined by the
// same loader.
if ((super->accflags & PUBLIC) == 0)
{
if ( sub->loader != super->loader
|| !_Jv_ClassNameSamePackage (sub->name, super->name))
{
throw_incompatible_class_change_error (sub->getName ());
}
}
// FIXME: add interface circularity check here
if (sub == super)
{
throw_class_circularity_error (sub->getName ());
}
}
void _Jv_ClassReader::handleFieldsBegin (int count)
{
def->fields = (_Jv_Field*)
_Jv_AllocBytesChecked (count * sizeof (_Jv_Field));
def->field_count = count;
def->field_initializers = (_Jv_ushort*)
_Jv_AllocBytesChecked (count * sizeof (_Jv_ushort));
for (int i = 0; i < count; i++)
def->field_initializers[i] = (_Jv_ushort) 0;
}
void _Jv_ClassReader::handleField (int field_no,
int flags,
int name,
int desc)
{
void **const pool_data = def->constants.data;
_Jv_Field *field = &def->fields[field_no];
_Jv_Utf8Const *field_name = (_Jv_Utf8Const*) pool_data[name];
#ifndef COMPACT_FIELDS
field->name = field_name;
#else
field->nameIndex = name;
#endif
if (verify)
_Jv_VerifyIdentifier (field_name);
// ignore flags we don't know about.
field->flags = flags & ALL_FLAGS;
if (verify)
{
if (field->flags & (SYNCHRONIZED|NATIVE|INTERFACE|ABSTRACT))
throw_class_format_error ("erroneous field access flags");
if (1 < ( ((field->flags & PUBLIC) ? 1 : 0)
+((field->flags & PRIVATE) ? 1 : 0)
+((field->flags & PROTECTED) ? 1 : 0)))
throw_class_format_error ("erroneous field access flags");
}
_Jv_Utf8Const* sig = (_Jv_Utf8Const*) pool_data[desc];
if (verify)
_Jv_VerifyFieldSignature (sig);
// field->type is really a jclass, but while it is still
// unresolved we keep an _Jv_Utf8Const* instead.
field->type = (jclass) sig;
field->flags |= _Jv_FIELD_UNRESOLVED_FLAG;
field->u.boffset = 0;
}
void _Jv_ClassReader::handleConstantValueAttribute (int field_index,
int value)
{
_Jv_Field *field = &def->fields[field_index];
if ((field->flags & (STATIC|FINAL|PRIVATE)) == 0)
{
// Ignore, as per vmspec #4.7.2
return;
}
// do not allow multiple constant fields!
if (field->flags & _Jv_FIELD_CONSTANT_VALUE)
throw_class_format_error ("field has multiple ConstantValue attributes");
field->flags |= _Jv_FIELD_CONSTANT_VALUE;
def->field_initializers[field_index] = value;
/* type check the initializer */
if (value <= 0 || value >= pool_count)
throw_class_format_error ("erroneous ConstantValue attribute");
/* FIXME: do the rest */
}
void _Jv_ClassReader::handleFieldsEnd ()
{
// We need to reorganize the fields so that the static ones are first,
// to conform to GCJ class layout.
int low = 0;
int high = def->field_count-1;
_Jv_Field *fields = def->fields;
_Jv_ushort *inits = def->field_initializers;
// this is kind of a raw version of quicksort.
while (low < high)
{
// go forward on low, while it's a static
while (low < high && (fields[low].flags & STATIC) != 0)
low++;
// go backwards on high, while it's a non-static
while (low < high && (fields[high].flags & STATIC) == 0)
high--;
if (low==high)
break;
_Jv_Field tmp = fields[low];
_Jv_ushort itmp = inits[low];
fields[low] = fields[high];
inits[low] = inits[high];
fields[high] = tmp;
inits[high] = itmp;
high -= 1;
low += 1;
}
if ((fields[low].flags & STATIC) != 0)
low += 1;
def->static_field_count = low;
}
void _Jv_ClassReader::handleMethodsBegin (int count)
{
def->methods = (_Jv_Method*)
_Jv_AllocBytesChecked (sizeof (_Jv_Method)*count);
def->interpreted_methods = (_Jv_InterpMethod**)
_Jv_AllocBytesChecked (sizeof (_Jv_InterpMethod*) * count);
for (int i = 0; i < count; i++)
def->interpreted_methods[i] = 0;
def->method_count = count;
}
void _Jv_ClassReader::handleMethod
(int mth_index, int accflags, int name, int desc)
{
void **const pool_data = def->constants.data;
_Jv_Method *method = &def->methods[mth_index];
check_tag (name, JV_CONSTANT_Utf8);
prepare_pool_entry (name, JV_CONSTANT_Utf8);
method->name = (_Jv_Utf8Const*)pool_data[name];
check_tag (desc, JV_CONSTANT_Utf8);
prepare_pool_entry (desc, JV_CONSTANT_Utf8);
method->signature = (_Jv_Utf8Const*)pool_data[desc];
// ignore unknown flags
method->accflags = accflags & ALL_FLAGS;
// intialize...
method->ncode = 0;
if (verify)
{
if (_Jv_equalUtf8Consts (method->name, clinit_name)
|| _Jv_equalUtf8Consts (method->name, init_name))
/* ignore */;
else
_Jv_VerifyIdentifier (method->name);
_Jv_VerifyMethodSignature (method->signature);
if (method->accflags & (VOLATILE|TRANSIENT|INTERFACE))
throw_class_format_error ("erroneous method access flags");
if (1 < ( ((method->accflags & PUBLIC) ? 1 : 0)
+((method->accflags & PRIVATE) ? 1 : 0)
+((method->accflags & PROTECTED) ? 1 : 0)))
throw_class_format_error ("erroneous method access flags");
}
}
void _Jv_ClassReader::handleCodeAttribute
(int method_index, int max_stack, int max_locals,
int code_start, int code_length, int exc_table_length)
{
int size = _Jv_InterpMethod::size (exc_table_length, code_length);
_Jv_InterpMethod *method =
(_Jv_InterpMethod*) (_Jv_AllocBytesChecked (size));
method->max_stack = max_stack;
method->max_locals = max_locals;
method->code_length = code_length;
method->exc_count = exc_table_length;
method->defining_class = def;
method->self = &def->methods[method_index];
// grab the byte code!
memcpy ((void*) method->bytecode (),
(void*) (bytes+code_start),
code_length);
def->interpreted_methods[method_index] = method;
/* that's all we do for now */
}
void _Jv_ClassReader::handleExceptionTableEntry
(int method_index, int exc_index,
int start_pc, int end_pc, int handler_pc, int catch_type)
{
_Jv_InterpMethod *method = def->interpreted_methods[method_index];
_Jv_InterpException *exc = method->exceptions ();
exc[exc_index].start_pc = start_pc;
exc[exc_index].end_pc = end_pc;
exc[exc_index].handler_pc = handler_pc;
exc[exc_index].handler_type = catch_type;
}
void _Jv_ClassReader::handleMethodsEnd ()
{
for (int i = 0; i < def->method_count; i++)
{
_Jv_Method *method = &def->methods[i];
if (method->accflags & (NATIVE|ABSTRACT))
{
if (def->interpreted_methods[i] != 0)
throw_class_format_error ("code provided "
"for abstract or native method");
}
else
{
if (def->interpreted_methods[i] == 0)
throw_class_format_error ("abstract or native method "
"with no code");
}
}
}
/** This section takes care of verifying integrity of identifiers,
signatures, field ddescriptors, and class names */
#define UTF8_PEEK(PTR, LIMIT) \
({ unsigned char* xxkeep = (PTR); \
int xxch = UTF8_GET(PTR,LIMIT); \
PTR = xxkeep; xxch; })
/* verify one element of a type descriptor or signature */
static unsigned char*
_Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
{
if (ptr >= limit)
return 0;
int ch = UTF8_GET (ptr, limit);
switch (ch)
{
case 'V':
if (! void_ok) return 0;
case 'S': case 'B': case 'I': case 'J':
case 'Z': case 'C': case 'F': case 'D':
break;
case 'L':
{
unsigned char *start = ptr, *end;
do {
if (ptr > limit)
return 0;
end = ptr;
if ((ch = UTF8_GET (ptr, limit)) == -1)
return 0;
} while (ch != ';');
_Jv_VerifyClassName (start, (unsigned short) (end-start));
}
break;
case '[':
return _Jv_VerifyOne (ptr, limit, false);
break;
default:
return 0;
}
return ptr;
}
/** verification and loading procedures **/
void
_Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
{
unsigned char* ptr = (unsigned char*) sig->data;
unsigned char* limit = ptr + sig->length;
ptr = _Jv_VerifyOne (ptr, limit, false);
if (ptr != limit)
throw_class_format_error ("erroneous type descriptor");
}
void
_Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
{
unsigned char* ptr = (unsigned char*) sig->data;
unsigned char* limit = ptr + sig->length;
if (ptr == limit)
throw_class_format_error ("erroneous type descriptor");
if (UTF8_GET(ptr,limit) != '(')
throw_class_format_error ("erroneous type descriptor");
while (ptr && UTF8_PEEK (ptr, limit) != ')')
ptr = _Jv_VerifyOne (ptr, limit, false);
if (UTF8_GET (ptr, limit) != ')')
throw_class_format_error ("erroneous type descriptor");
// get the return type
ptr = _Jv_VerifyOne (ptr, limit, true);
if (ptr != limit)
throw_class_format_error ("erroneous type descriptor");
return;
}
/* we try to avoid calling the Character methods all the time,
in fact, they will only be called for non-standard things */
static __inline__ int
is_identifier_start (int c)
{
unsigned int ch = (unsigned)c;
if ((ch - 0x41U) < 29U) /* A ... Z */
return 1;
if ((ch - 0x61U) < 29U) /* a ... z */
return 1;
if (ch == 0x5FU) /* _ */
return 1;
return character->isJavaIdentifierStart ((jchar) ch);
}
static __inline__ int
is_identifier_part (int c)
{
unsigned int ch = (unsigned)c;
if ((ch - 0x41U) < 29U) /* A ... Z */
return 1;
if ((ch - 0x61U) < 29U) /* a ... z */
return 1;
if ((ch - 0x30) < 10U) /* 0 .. 9 */
return 1;
if (ch == 0x5FU || ch == 0x24U) /* _ $ */
return 1;
return character->isJavaIdentifierStart ((jchar) ch);
}
void
_Jv_VerifyIdentifier (_Jv_Utf8Const* name)
{
unsigned char *ptr = (unsigned char*) name->data;
unsigned char *limit = ptr + name->length;
int ch;
if ((ch = UTF8_GET (ptr, limit))==-1
|| ! is_identifier_start (ch))
throw_class_format_error ("erroneous identifier");
while (ptr != limit)
{
if ((ch = UTF8_GET (ptr, limit))==-1
|| ! is_identifier_part (ch))
throw_class_format_error ("erroneous identifier");
}
}
void
_Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
{
unsigned char *limit = ptr+length;
int ch;
next_level:
do {
if ((ch = UTF8_GET (ptr, limit))==-1)
throw_class_format_error ("erroneous class name");
if (! is_identifier_start (ch))
throw_class_format_error ("erroneous class name");
do {
if (ptr == limit)
return;
else if ((ch = UTF8_GET (ptr, limit))==-1)
throw_class_format_error ("erroneous class name");
else if (ch == '.')
goto next_level;
else if (! is_identifier_part (ch))
throw_class_format_error ("erroneous class name");
} while (true);
} while (true);
}
void
_Jv_VerifyClassName (_Jv_Utf8Const *name)
{
_Jv_VerifyClassName ((unsigned char*)&name->data[0],
(_Jv_ushort) name->length);
}
/** returns true, if name1 and name2 represents classes in the same
package. */
bool
_Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
{
unsigned char* ptr1 = (unsigned char*) name1->data;
unsigned char* limit1 = ptr1 + name1->length;
unsigned char* last1 = ptr1;
// scan name1, and find the last occurrence of '.'
while (ptr1 < limit1) {
int ch1 = UTF8_GET (ptr1, limit1);
if (ch1 == '.')
last1 = ptr1;
else if (ch1 == -1)
return false;
}
// now the length of name1's package name is len
int len = last1 - (unsigned char*) name1->data;
// if this is longer than name2, then we're off
if (len > name2->length)
return false;
// then compare the first len bytes for equality
if (memcmp ((void*) name1->data, (void*) name2->data, len) == 0)
{
// check that there are no .'s after position len in name2
unsigned char* ptr2 = (unsigned char*) name2->data + len;
unsigned char* limit2 =
(unsigned char*) name2->data + name2->length;
while (ptr2 < limit2)
{
int ch2 = UTF8_GET (ptr2, limit2);
if (ch2 == -1 || ch2 == '.')
return false;
}
return true;
}
return false;
}
/** Here we define the exceptions that can be thrown */
static void
throw_no_class_def_found_error (jstring msg)
{
if (msg == 0)
JvThrow (new java::lang::NoClassDefFoundError);
else
JvThrow (new java::lang::NoClassDefFoundError (msg));
}
static void
throw_no_class_def_found_error (char *msg)
{
throw_no_class_def_found_error (JvNewStringLatin1 (msg));
}
static void
throw_class_format_error (jstring msg)
{
if (msg == 0)
JvThrow (new java::lang::ClassFormatError);
else
JvThrow (new java::lang::ClassFormatError (msg));
}
static void
throw_class_format_error (char *msg)
{
throw_class_format_error (JvNewStringLatin1 (msg));
}
static void
throw_internal_error (char *msg)
{
JvThrow
(new java::lang::InternalError (JvNewStringLatin1 (msg)));
}
static jfloat int_bits_to_float (jint value)
{
return java::lang::Float::intBitsToFloat (value);
}
static jdouble long_bits_to_double (jlong value)
{
return java::lang::Double::longBitsToDouble (value);
}
static void throw_incompatible_class_change_error (jstring msg)
{
JvThrow (new java::lang::IncompatibleClassChangeError (msg));
}
static void throw_class_circularity_error (jstring msg)
{
JvThrow (new java::lang::ClassCircularityError (msg));
}
#endif /* INTERPRETER */
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
#include <jvm.h>
#include <cni.h>
#include <stdio.h>
#include <java/lang/System.h>
#include <java/util/Properties.h>
int main (int argc, const char **argv)
{
if (argc < 2)
{
printf ("usage: %s <class name> args\n", argv[0]);
exit (1);
}
JvRunMain (0, argc, argv);
}
// MethodInvocation.java - wrapper used by the interpreter.
// (the native method is implemented in interpret.cc)
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
package gnu.gcj.runtime;
import gnu.gcj.RawData;
final class MethodInvocation {
private static Throwable continue0 (RawData meth, RawData inv)
{
try {
continue1 (meth, inv);
} catch (Throwable ex) {
return ex;
}
return null;
}
private static native void continue1 (RawData meth, RawData inv);
}
// CacheEntry.java -- directory cache
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
package gnu.gcj.util.path;
import java.util.*;
import java.util.zip.*;
import java.io.*;
import java.net.*;
final class CacheEntry {
String dir;
String[] files;
long time;
CacheEntry (String d)
{
dir = d;
files = new File(dir).list();
time = System.currentTimeMillis ();
}
void touch ()
{
time = System.currentTimeMillis ();
}
final long EXPIRATION_TIME_MS = 1000;
boolean is_old () {
return (System.currentTimeMillis () - time) > EXPIRATION_TIME_MS;
}
public int hashCode () { return dir.hashCode(); }
boolean contains (String file) {
if (files == null)
return false;
int index = file.lastIndexOf(SearchPath.file_seperator_char);
String f;
if (index == -1)
f = file;
else
f = file.substring (index+1);
for (int i = 0; i < files.length; i++)
{
if (f.equals (files[i])) return true;
}
return false;
}
}
// DirectoryPathEntry.java -- search path element for directories
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
package gnu.gcj.util.path;
import java.util.*;
import java.util.zip.*;
import java.io.*;
import java.net.*;
final class DirectoryPathEntry extends PathEntry
{
final File dir;
final String base_canon;
public String toString () { return base_canon; }
DirectoryPathEntry (File f)
throws java.io.IOException
{
if (!f.isAbsolute ())
throw new IllegalArgumentException ();
dir = f;
base_canon = dir.getCanonicalPath ();
}
/*
* We maintain a cache of files, so that we
* can avoid many calls to stat(), which are
* very expensive.
*
* seen_cache contains (as keys) the directories
* which we have visited so far. The values are
* instances of CacheEntry, containing a time stamp,
* and a list of files in that directory.
*
*/
private Hashtable seen_cache = new Hashtable ();
private boolean in_cache (File f)
{
String rel_dir = f.getParent ();
CacheEntry ent;
if (rel_dir == null)
throw new IllegalArgumentException ();
ent = (CacheEntry) seen_cache.get (rel_dir);
if (ent == null)
{
ent = new CacheEntry (rel_dir);
seen_cache.put (rel_dir, ent);
}
if (ent.contains (f.getPath ()))
{
return true;
}
if ( ent.is_old () )
{
if (f.exists ())
{
seen_cache.remove (rel_dir);
return true;
}
else
{
ent.touch ();
}
}
return false;
}
URL getURL (String file) {
try {
File f = new File((new File (dir, file).getCanonicalPath ()));
if (! f.getCanonicalPath ().startsWith (base_canon))
throw new IllegalArgumentException (file);
if (in_cache (f))
return new URL ("file", "", f.getPath ());
else
return null;
} catch (IOException x) {
return null;
}
}
InputStream getStream (String file) {
try {
File f = new File((new File (dir, file)).getCanonicalPath ());
if (! f.getCanonicalPath ().startsWith (base_canon))
throw new IllegalArgumentException (file);
if (in_cache (f))
return new FileInputStream (f);
else
return null;
} catch (IOException x) {
return null;
}
}
byte[] getBytes (String file) {
File f = new File (dir, file);
try {
if (in_cache (f))
return readbytes (new FileInputStream (f),
(int) f.length ());
else
return null;
} catch (IOException x) {
return null;
}
}
}
// PathEntry.java -- abstract element of search paths
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
package gnu.gcj.util.path;
import java.util.*;
import java.util.zip.*;
import java.io.*;
import java.net.*;
abstract class PathEntry {
abstract URL getURL (String file);
abstract InputStream getStream (String file);
abstract byte[] getBytes (String file);
/**
* Utility routine like InputStream.read(byte[], 0, len), but will
* read fully, even if all the data is not available at once.
*/
protected static byte[] readbytes (InputStream is, int length)
{
try {
byte[] data = new byte[length];
int read;
int off = 0;
while (off != length)
{
read = is.read (data, off, (int) (length-off));
if (read == -1)
return null;
off += read;
}
return data;
} catch (IOException x) {
return null;
}
}
}
// SearchPath.java -- generic search path utility
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
package gnu.gcj.util.path;
import java.util.*;
import java.util.zip.*;
import java.io.*;
import java.net.*;
final public class SearchPath {
final static String path_seperator
= System.getProperty ("path.separator");
final static char path_seperator_char
= path_seperator.charAt (0);
final static String file_seperator
= System.getProperty ("file.separator");
final static char file_seperator_char
= file_seperator.charAt (0);
private Vector path;
/**
* Constructs a SearchPath object, given a system path.
* The system path is expected to be seperated by the string
* defined by the <code>path.seperator</code> property.
* (<code>":"</code> on unix, <code>;</code> on Windows, etc.).
* The path may contain names of directories, or names of
* .zip or .jar files. Elements that are neither of these
* are ignored.
* @param sys_path the search path
*/
SearchPath (String sys_path)
{
StringTokenizer st = new StringTokenizer (sys_path, path_seperator);
init (st);
}
/**
* Constructs a SearchPath object, given a Vector of
* <code>String</code>, <code>File</code> or <code>URL</code>
* objects.
* The path may contain names of directories, or names of
* .zip or .jar files. Elements that are neither of these
* are ignored.
* @param p the vector of search path elements
*/
SearchPath (Vector p)
{
init (p.elements ());
}
public URL getURL (String element)
{
URL result;
Enumeration e = path.elements ();
while (e.hasMoreElements ())
{
PathEntry ent = (PathEntry) e.nextElement ();
result = ent.getURL (element);
if (result != null)
{
return result;
}
}
return null;
}
public InputStream getStream (String element)
{
InputStream result;
Enumeration e = path.elements ();
while (e.hasMoreElements ())
{
PathEntry ent = (PathEntry) e.nextElement ();
result = ent.getStream (element);
if (result != null)
{
return result;
}
}
return null;
}
public byte[] getBytes (String element)
{
byte[] result;
Enumeration e = path.elements ();
while (e.hasMoreElements ())
{
PathEntry ent = (PathEntry) e.nextElement ();
result = ent.getBytes (element);
if (result != null)
{
System.out.println ("loading " + ent
+ "(" + element + ")");
return result;
}
}
return null;
}
private void init (Enumeration st)
{
path = new Vector ();
while (st.hasMoreElements ())
{
Object e = st.nextElement ();
String elem;
File efile;
if (e instanceof URL)
{
path.addElement (new URLPathEntry ((URL) e));
continue;
}
if (e instanceof File)
{
efile = (File) e;
elem = efile.getPath ();
}
else if (e instanceof String)
{
elem = (String) e;
efile = new File (elem);
}
else
throw new IllegalArgumentException ();
// make sure it is absolute, so we won't get
// trouble if the cwd is changed...
if (! efile.isAbsolute ())
efile = new File (efile.getAbsolutePath ());
if (efile.isDirectory ())
{
try {
path.addElement(new DirectoryPathEntry (efile));
} catch (IOException x) {
/* ignore for now */
}
}
else if (efile.isFile ())
{
int ext = elem.lastIndexOf ('.');
if (ext == -1)
continue;
if (!elem.substring(ext+1).equalsIgnoreCase("zip"))
continue;
ZipPathEntry zpe = null;
try {
zpe = new ZipPathEntry (efile);
} catch (ZipException zx) {
System.err.println ("SearchPath::ZipException");
zpe = null;
} catch (MalformedURLException mx) {
System.err.println ("SearchPath::URLException");
zpe = null;
} catch (IOException iox) {
System.err.println ("SearchPath::IOException");
zpe = null;
}
if (zpe != null) path.addElement (zpe);
}
}
}
}
// URLPathEntry.java -- search path element for URL's
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
package gnu.gcj.util.path;
import java.util.*;
import java.util.zip.*;
import java.io.*;
import java.net.*;
final class URLPathEntry extends PathEntry {
final URL base;
URLPathEntry (URL f) {
base = f;
}
public String toString () { return base.toString (); }
URL getURL (String file) {
try {
URL res = new URL (base, file);
InputStream is = res.openStream (); // exc if not found
is.close ();
return res;
} catch (java.io.IOException x) {
return null;
}
}
InputStream getStream (String file) {
try {
URL res = new URL (base, file);
return res.openStream ();
} catch (java.io.IOException x) {
return null;
}
}
byte[] getBytes (String file) {
try {
URL res = new URL (base, file);
URLConnection conn = res.openConnection ();
int len = conn.getContentLength ();
if (len == -1) return null;
return readbytes (conn.getInputStream (), len);
} catch (java.io.IOException x) {
return null;
}
}
}
// ZipPathEntry.java -- search path element for directories
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
package gnu.gcj.util.path;
import java.util.*;
import java.util.zip.*;
import java.io.*;
import java.net.*;
final class ZipPathEntry extends PathEntry {
final ZipFile zip;
final URL file;
public String toString () { return zip.getName (); }
ZipPathEntry (File f)
throws MalformedURLException, ZipException, IOException
{
file = new URL ("file", "", f.getPath ());
zip = new ZipFile (f);
zip.readDirectory ();
}
/*
The url for a zip-file resource is,
<code>file:///path/file.zip#name</code>
Then, it is URLConnection's problem to handle that.
*/
URL getURL (String f) {
ZipEntry ent = zip.getEntry (f);
try {
if (ent != null)
return new URL (file, "#"+f);
else
return null;
} catch (IOException x) {
return null;
}
}
InputStream getStream (String f) {
ZipEntry ent = zip.getEntry (f);
try {
if (ent != null)
return zip.getInputStream (ent);
else
return null;
} catch (IOException x) {
return null;
}
}
byte[] getBytes (String f) {
ZipEntry ent = zip.getEntry (f);
try {
if (ent != null)
return readbytes (zip.getInputStream (ent),
(int) ent.getSize ());
else
return null;
} catch (IOException x) {
return null;
}
}
}
...@@ -106,6 +106,9 @@ ...@@ -106,6 +106,9 @@
#undef HAVE_GETHOSTBYNAME_R #undef HAVE_GETHOSTBYNAME_R
#undef HAVE_GETHOSTBYADDR_R #undef HAVE_GETHOSTBYADDR_R
/* Define if you want a bytecode interpreter. */
#undef INTERPRETER
/* Define if you have the access function. */ /* Define if you have the access function. */
#undef HAVE_ACCESS #undef HAVE_ACCESS
......
// java-cpool.h - Constant pool parsing header. -*- c++ -*-
/* Copyright (C) 1999 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. */
#ifndef __JAVA_CPOOL_H__
#define __JAVA_CPOOL_H__
#include <javaprims.h>
// we rename these, to avoid polluting the name space
#define JV_CONSTANT_Undefined (0L)
#define JV_CONSTANT_Utf8 (1L)
#define JV_CONSTANT_Unicode (2L)
#define JV_CONSTANT_Integer (3L)
#define JV_CONSTANT_Float (4L)
#define JV_CONSTANT_Long (5L)
#define JV_CONSTANT_Double (6L)
#define JV_CONSTANT_Class (7L)
#define JV_CONSTANT_String (8L)
#define JV_CONSTANT_Fieldref (9L)
#define JV_CONSTANT_Methodref (10L)
#define JV_CONSTANT_InterfaceMethodref (11L)
#define JV_CONSTANT_NameAndType (12L)
#define JV_CONSTANT_ResolvedFlag (16L)
#define JV_CONSTANT_ResolvedString (16L | 8L)
#define JV_CONSTANT_ResolvedClass (16L | 7L)
/* We use the following two operations uniformly for all put/get operations
* in the runtime system (constant pool & stack), to assure that we keep
* everything in the same format. The idea is, that these should be inlined
* away, into just a simple store (for small data types, and a pair of stores
* if double or long has alignment greater than void *. On an 64-bit
* architecture, all operations should be simple stores; on a 32-bit
* architecture it depends on the alignment requirement for the specific
* type. */
template <class T>
static inline void _Jv_put (void *dst, T value)
{
#if 0
if (sizeof (T) == 8 && __alignof__ (T) > __alignof__ (void*))
{
jint *v_dst = (jint*)(dst);
jint *v_src = (jint*)&value;
v_dst[0] = v_src[0];
v_dst[1] = v_src[1];
}
else
#endif
{
*((T*) (dst)) = value;
}
}
template <class T>
static inline T _Jv_get (void *src)
{
#if 0
if (sizeof (T) == 8 && __alignof__ (T) > __alignof__ (void*))
{
T value;
jint *v_dst = (jint*)&value;
jint *v_src = (jint*)src;
v_dst[0] = v_src[0];
v_dst[1] = v_src[1];
return value;
}
else
#endif
{
return *((T*) (src));
}
}
/** needed to keep the CONSTANT_XXXRef & CONSTANT_NameAndType entries */
extern inline void
_Jv_storeIndexes (void **data,
_Jv_ushort index0,
_Jv_ushort index1)
{
// accomodate 64bit machines...
if (sizeof (void*) == (2 * sizeof (jint)))
{
((jint*)data)[0] = index0;
((jint*)data)[1] = index0;
}
else
{
_Jv_put<jint>(data, ((jint)index0 << 16) | (jint)index1);
}
}
extern inline void
_Jv_loadIndexes (const void **data,
_Jv_ushort& index0,
_Jv_ushort& index1)
{
if (sizeof (void*) == (2*sizeof (jint)))
{
index0 = ((jint*)data)[0];
index0 = ((jint*)data)[1];
}
else
{
jint udata = _Jv_get<jint>(data);
_Jv_uint uindex0 = ((udata >> 16) & 0xffff);
_Jv_uint uindex1 = udata & 0xffff;
index0 = uindex0;
index1 = uindex1;
}
}
extern inline void
_Jv_storeFloat (void **data, jfloat f)
{
_Jv_put<jfloat>(data, f);
}
extern inline jfloat
_Jv_loadFloat (void **data)
{
return _Jv_get<jfloat>(data);
}
extern inline void
_Jv_storeInt (void **data, jint i)
{
_Jv_put<jint>(data, i);
}
extern inline jint
_Jv_loadInt (void **data)
{
return _Jv_get<jint>(data);
}
extern inline void
_Jv_storeLong (void **data, jlong l)
{
return _Jv_put<jlong>(data, l);
}
extern inline jlong
_Jv_loadLong (void **data)
{
return _Jv_get<jlong>(data);
}
extern inline void
_Jv_storeDouble (void **data, jdouble d)
{
_Jv_put<jdouble>(data, d);
}
extern inline jdouble
_Jv_loadDouble (void **data)
{
return _Jv_get<jdouble> (data);
}
#endif /* __JAVA_CPOOL_H__ */
...@@ -53,7 +53,18 @@ struct _Jv_Field ...@@ -53,7 +53,18 @@ struct _Jv_Field
jfieldID getNextInstanceField () { return this + 1; } jfieldID getNextInstanceField () { return this + 1; }
jboolean isRef () { return ! isResolved () || ! type->isPrimitive (); } jboolean isRef ()
{
if (!isResolved ())
{
char first = ((_Jv_Utf8Const*)type)->data[0];
return first == '[' || first == 'L';
}
else
{
return ! type->isPrimitive ();
}
}
// FIXME - may need to mask off internal flags. // FIXME - may need to mask off internal flags.
int getModifiers() { return flags; } int getModifiers() { return flags; }
......
// java-insns.h - Instruction encodings. This is -*- c++ -*-
/* Copyright (C) 1999 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. */
static const int op_nop = 0x00;
static const int op_aconst_null = 0x01;
static const int op_iconst_m1 = 0x02;
static const int op_iconst_0 = 0x03;
static const int op_iconst_1 = 0x04;
static const int op_iconst_2 = 0x05;
static const int op_iconst_3 = 0x06;
static const int op_iconst_4 = 0x07;
static const int op_iconst_5 = 0x08;
static const int op_lconst_0 = 0x09;
static const int op_lconst_1 = 0x0a;
static const int op_fconst_0 = 0x0b;
static const int op_fconst_1 = 0x0c;
static const int op_fconst_2 = 0x0d;
static const int op_dconst_0 = 0x0e;
static const int op_dconst_1 = 0x0f;
static const int op_bipush = 0x10;
static const int op_sipush = 0x11;
static const int op_ldc = 0x12;
static const int op_ldc_w = 0x13;
static const int op_ldc2_w = 0x14;
static const int op_iload = 0x15;
static const int op_lload = 0x16;
static const int op_fload = 0x17;
static const int op_dload = 0x18;
static const int op_aload = 0x19;
static const int op_iload_0 = 0x1a;
static const int op_iload_1 = 0x1b;
static const int op_iload_2 = 0x1c;
static const int op_iload_3 = 0x1d;
static const int op_lload_0 = 0x1e;
static const int op_lload_1 = 0x1f;
static const int op_lload_2 = 0x20;
static const int op_lload_3 = 0x21;
static const int op_fload_0 = 0x22;
static const int op_fload_1 = 0x23;
static const int op_fload_2 = 0x24;
static const int op_fload_3 = 0x25;
static const int op_dload_0 = 0x26;
static const int op_dload_1 = 0x27;
static const int op_dload_2 = 0x28;
static const int op_dload_3 = 0x29;
static const int op_aload_0 = 0x2a;
static const int op_aload_1 = 0x2b;
static const int op_aload_2 = 0x2c;
static const int op_aload_3 = 0x2d;
static const int op_iaload = 0x2e;
static const int op_laload = 0x2f;
static const int op_faload = 0x30;
static const int op_daload = 0x31;
static const int op_aaload = 0x32;
static const int op_baload = 0x33;
static const int op_caload = 0x34;
static const int op_saload = 0x35;
static const int op_istore = 0x36;
static const int op_lstore = 0x37;
static const int op_fstore = 0x38;
static const int op_dstore = 0x39;
static const int op_astore = 0x3a;
static const int op_istore_0 = 0x3b;
static const int op_istore_1 = 0x3c;
static const int op_istore_2 = 0x3d;
static const int op_istore_3 = 0x3e;
static const int op_lstore_0 = 0x3f;
static const int op_lstore_1 = 0x40;
static const int op_lstore_2 = 0x41;
static const int op_lstore_3 = 0x42;
static const int op_fstore_0 = 0x43;
static const int op_fstore_1 = 0x44;
static const int op_fstore_2 = 0x45;
static const int op_fstore_3 = 0x46;
static const int op_dstore_0 = 0x47;
static const int op_dstore_1 = 0x48;
static const int op_dstore_2 = 0x49;
static const int op_dstore_3 = 0x4a;
static const int op_astore_0 = 0x4b;
static const int op_astore_1 = 0x4c;
static const int op_astore_2 = 0x4d;
static const int op_astore_3 = 0x4e;
static const int op_iastore = 0x4f;
static const int op_lastore = 0x50;
static const int op_fastore = 0x51;
static const int op_dastore = 0x52;
static const int op_aastore = 0x53;
static const int op_bastore = 0x54;
static const int op_castore = 0x55;
static const int op_sastore = 0x56;
static const int op_pop = 0x57;
static const int op_pop2 = 0x58;
static const int op_dup = 0x59;
static const int op_dup_x1 = 0x5a;
static const int op_dup_x2 = 0x5b;
static const int op_dup2 = 0x5c;
static const int op_dup2_x1 = 0x5d;
static const int op_dup2_x2 = 0x5e;
static const int op_swap = 0x5f;
static const int op_iadd = 0x60;
static const int op_ladd = 0x61;
static const int op_fadd = 0x62;
static const int op_dadd = 0x63;
static const int op_isub = 0x64;
static const int op_lsub = 0x65;
static const int op_fsub = 0x66;
static const int op_dsub = 0x67;
static const int op_imul = 0x68;
static const int op_lmul = 0x69;
static const int op_fmul = 0x6a;
static const int op_dmul = 0x6b;
static const int op_idiv = 0x6c;
static const int op_ldiv = 0x6d;
static const int op_fdiv = 0x6e;
static const int op_ddiv = 0x6f;
static const int op_irem = 0x70;
static const int op_lrem = 0x71;
static const int op_frem = 0x72;
static const int op_drem = 0x73;
static const int op_ineg = 0x74;
static const int op_lneg = 0x75;
static const int op_fneg = 0x76;
static const int op_dneg = 0x77;
static const int op_ishl = 0x78;
static const int op_lshl = 0x79;
static const int op_ishr = 0x7a;
static const int op_lshr = 0x7b;
static const int op_iushr = 0x7c;
static const int op_lushr = 0x7d;
static const int op_iand = 0x7e;
static const int op_land = 0x7f;
static const int op_ior = 0x80;
static const int op_lor = 0x81;
static const int op_ixor = 0x82;
static const int op_lxor = 0x83;
static const int op_iinc = 0x84;
static const int op_i2l = 0x85;
static const int op_i2f = 0x86;
static const int op_i2d = 0x87;
static const int op_l2i = 0x88;
static const int op_l2f = 0x89;
static const int op_l2d = 0x8a;
static const int op_f2i = 0x8b;
static const int op_f2l = 0x8c;
static const int op_f2d = 0x8d;
static const int op_d2i = 0x8e;
static const int op_d2l = 0x8f;
static const int op_d2f = 0x90;
static const int op_i2b = 0x91;
static const int op_i2c = 0x92;
static const int op_i2s = 0x93;
static const int op_lcmp = 0x94;
static const int op_fcmpl = 0x95;
static const int op_fcmpg = 0x96;
static const int op_dcmpl = 0x97;
static const int op_dcmpg = 0x98;
static const int op_ifeq = 0x99;
static const int op_ifne = 0x9a;
static const int op_iflt = 0x9b;
static const int op_ifge = 0x9c;
static const int op_ifgt = 0x9d;
static const int op_ifle = 0x9e;
static const int op_if_icmpeq = 0x9f;
static const int op_if_icmpne = 0xa0;
static const int op_if_icmplt = 0xa1;
static const int op_if_icmpge = 0xa2;
static const int op_if_icmpgt = 0xa3;
static const int op_if_icmple = 0xa4;
static const int op_if_acmpeq = 0xa5;
static const int op_if_acmpne = 0xa6;
static const int op_goto = 0xa7;
static const int op_jsr = 0xa8;
static const int op_ret = 0xa9;
static const int op_tableswitch = 0xaa;
static const int op_lookupswitch = 0xab;
static const int op_ireturn = 0xac;
static const int op_lreturn = 0xad;
static const int op_freturn = 0xae;
static const int op_dreturn = 0xaf;
static const int op_areturn = 0xb0;
static const int op_return = 0xb1;
static const int op_getstatic = 0xb2;
static const int op_putstatic = 0xb3;
static const int op_getfield = 0xb4;
static const int op_putfield = 0xb5;
static const int op_invokevirtual = 0xb6;
static const int op_invokespecial = 0xb7;
static const int op_invokestatic = 0xb8;
static const int op_invokeinterface = 0xb9;
static const int op_xxxunusedxxx1 = 0xba;
static const int op_new = 0xbb;
static const int op_newarray = 0xbc;
static const int op_anewarray = 0xbd;
static const int op_arraylength = 0xbe;
static const int op_athrow = 0xbf;
static const int op_checkcast = 0xc0;
static const int op_instanceof = 0xc1;
static const int op_monitorenter = 0xc2;
static const int op_monitorexit = 0xc3;
static const int op_wide = 0xc4;
static const int op_multianewarray = 0xc5;
static const int op_ifnull = 0xc6;
static const int op_ifnonnull = 0xc7;
static const int op_goto_w = 0xc8;
static const int op_jsr_w = 0xc9;
// new opcodes
static const int op_putfield_1 = 0xca;
static const int op_putfield_2 = 0xcb;
static const int op_putfield_4 = 0xcd;
static const int op_putfield_8 = 0xce;
static const int op_putfield_a = 0xcf;
static const int op_putstatic_1 = 0xd0;
static const int op_putstatic_2 = 0xd1;
static const int op_putstatic_4 = 0xd2;
static const int op_putstatic_8 = 0xd3;
static const int op_putstatic_a = 0xd4;
static const int op_getfield_1 = 0xd5;
static const int op_getfield_2s = 0xd6;
static const int op_getfield_2u = 0xd7;
static const int op_getfield_4 = 0xd8;
static const int op_getfield_8 = 0xd9;
static const int op_getfield_a = 0xda;
static const int op_getstatic_1 = 0xdb;
static const int op_getstatic_2s = 0xdc;
static const int op_getstatic_2u = 0xdd;
static const int op_getstatic_4 = 0xde;
static const int op_getstatic_8 = 0xdf;
static const int op_getstatic_a = 0xe0;
static const int op_invokefinal = 0xe1;
static const int op_invokevtable = 0xe2;
// java-interp.h - Header file for the bytecode interpreter. -*- c++ -*-
/* Copyright (C) 1999 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. */
#ifndef __JAVA_INTERP_H__
#define __JAVA_INTERP_H__
#include <config.h>
#include <jvm.h>
#include <java-cpool.h>
#ifdef INTERPRETER
#pragma interface
#include <java/lang/Class.h>
#include <java/lang/ClassLoader.h>
#include <gnu/gcj/runtime/MethodInvocation.h>
extern "C" {
#include <ffi.h>
}
extern inline jboolean
_Jv_IsInterpretedClass (jclass c)
{
return (c->loader != 0);
}
struct _Jv_ResolvedMethod;
void _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig);
void _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig);
void _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length);
void _Jv_VerifyClassName (_Jv_Utf8Const *name);
void _Jv_VerifyIdentifier (_Jv_Utf8Const *);
bool _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2);
void _Jv_DefineClass (jclass, jbyteArray, jint, jint);
void _Jv_ResolveField (_Jv_Field *, java::lang::ClassLoader*);
void _Jv_InitField (jobject, jclass, int);
void * _Jv_AllocMethodInvocation (jsize size);
/* FIXME: this should really be defined in some more generic place */
#define ROUND(V, A) (((((unsigned) (V))-1) | ((A)-1))+1)
/* the interpreter is written in C++, primarily because it makes it easy for
* the entire thing to be "friend" with class Class. */
class _Jv_InterpClass;
class _Jv_InterpMethod;
class _Jv_InterpMethodInvocation;
class _Jv_InterpException {
int start_pc;
int end_pc;
int handler_pc;
int handler_type;
friend class _Jv_ClassReader;
friend class _Jv_InterpMethod;
};
class _Jv_InterpMethod {
_Jv_ushort max_stack;
_Jv_ushort max_locals;
int code_length;
_Jv_ushort exc_count;
_Jv_ushort args_raw_size;
_Jv_InterpClass *defining_class;
_Jv_Method *self;
unsigned char* bytecode ()
{
return
((unsigned char*)this)
+ ROUND((sizeof (_Jv_InterpMethod)
+ exc_count*sizeof (_Jv_InterpException)), 4);
}
_Jv_InterpException * exceptions ()
{
return (_Jv_InterpException*) (this+1);
}
static size_t size (int exc_count, int code_length)
{
return
ROUND ((sizeof (_Jv_InterpMethod)
+ (exc_count * sizeof (_Jv_InterpException))), 4)
+ code_length;
}
// return the method's invocation pointer (a stub).
void *ncode ();
void continue1 (_Jv_InterpMethodInvocation *inv);
static void run_normal (ffi_cif*, void*, void**, void*);
static void run_synch_object (ffi_cif*, void*, void**, void*);
static void run_synch_class (ffi_cif*, void*, void**, void*);
inline jobject run (ffi_cif*, void*, void**,
_Jv_InterpMethodInvocation*);
bool find_exception (jobject ex,
_Jv_InterpMethodInvocation *inv);
public:
static void dump_object(jobject o);
friend class _Jv_ClassReader;
friend class _Jv_InterpMethodInvocation;
friend class gnu::gcj::runtime::MethodInvocation;
friend void _Jv_PrepareClass(jclass);
friend void _Jv_callInterpretedMethod (ffi_cif*,
void*,
void **,
void*);
};
class _Jv_InterpMethodInvocation {
_Jv_InterpMethod *running;
void **sp;
unsigned char *pc;
void* state[0];
void** stack_base () { return &state[0]; }
void** local_base () { return &state[running->max_stack]; }
friend class _Jv_InterpMethod;
};
class _Jv_InterpClass : public java::lang::Class
{
_Jv_InterpMethod **interpreted_methods;
_Jv_ushort *field_initializers;
friend class _Jv_ClassReader;
friend class _Jv_InterpMethod;
friend void _Jv_PrepareClass(jclass);
friend void _Jv_InitField (jobject, jclass, int);
friend void* _Jv_MarkObj (void *, void *, void *, void *);
};
struct _Jv_ResolvedMethod {
jint stack_item_count;
jint vtable_index;
jclass klass;
_Jv_Method* method;
// a resolved method holds the cif in-line, so that _Jv_MarkObj just needs
// to mark the resolved method to hold on to the cif. Some memory could be
// saved by keeping a cache of cif's, since many will be the same.
ffi_cif cif;
ffi_type * arg_types[0];
};
#endif /* INTERPRETER */
#endif /* __JAVA_INTERP_H__ */
...@@ -162,6 +162,7 @@ extern "Java" ...@@ -162,6 +162,7 @@ extern "Java"
class VerifyError; class VerifyError;
class VirtualMachineError; class VirtualMachineError;
class Void; class Void;
class VMClassLoader;
namespace reflect namespace reflect
{ {
class AccessibleObject; class AccessibleObject;
......
...@@ -40,6 +40,8 @@ extern int _Jv_strLengthUtf8(char* str, int len); ...@@ -40,6 +40,8 @@ extern int _Jv_strLengthUtf8(char* str, int len);
typedef struct _Jv_Utf8Const Utf8Const; typedef struct _Jv_Utf8Const Utf8Const;
_Jv_Utf8Const *_Jv_makeUtf8Const (char *s, int len); _Jv_Utf8Const *_Jv_makeUtf8Const (char *s, int len);
_Jv_Utf8Const *_Jv_makeUtf8TypeConst (char* s, int len);
_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);
...@@ -91,6 +93,8 @@ extern "C" void *_Jv_LookupInterfaceMethod (jclass klass, Utf8Const *name, ...@@ -91,6 +93,8 @@ extern "C" void *_Jv_LookupInterfaceMethod (jclass klass, Utf8Const *name,
extern "C" void _Jv_CheckArrayStore (jobject array, jobject obj); extern "C" void _Jv_CheckArrayStore (jobject array, jobject obj);
extern "C" void _Jv_RegisterClass (jclass klass); extern "C" void _Jv_RegisterClass (jclass klass);
extern "C" void _Jv_RegisterClasses (jclass *classes); extern "C" void _Jv_RegisterClasses (jclass *classes);
extern void _Jv_UnregisterClass (_Jv_Utf8Const*, java::lang::ClassLoader*);
extern jclass _Jv_FindClass (_Jv_Utf8Const *name, 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 *,
......
// interpret.cc - Code for the interpreter
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
/* define this to get instruction timings. */
/* #define TIME_MAINLOOP */
#include <config.h>
#pragma implementation "java-interp.h"
#include <cni.h>
#include <jvm.h>
#include <java-field.h>
#include <java-cpool.h>
#include <java-interp.h>
#include <java/lang/fdlibm.h>
#include <java/lang/System.h>
#include <java/lang/String.h>
#include <java/lang/Integer.h>
#include <java/lang/StringBuffer.h>
#include <java/io/PrintStream.h>
#include <java/lang/Class.h>
#include <java/lang/reflect/Modifier.h>
#include <java/lang/ClassCastException.h>
#include <java/lang/VirtualMachineError.h>
#include <java/lang/InternalError.h>
#include <java/lang/NullPointerException.h>
#include <java/lang/ArithmeticException.h>
#include <java/lang/IncompatibleClassChangeError.h>
#include <java-insns.h>
#include <java-signal.h>
#ifdef TIME_MAINLOOP
#include <sys/time.h>
#include <stdio.h>
#endif
#ifndef INTERPRETER
#include <gnu/gcj/runtime/MethodInvocation.h>
/* this is the exception handler hack, for the interpreter */
void
gnu::gcj::runtime::MethodInvocation::continue1 (gnu::gcj::RawData *,
gnu::gcj::RawData *)
{
JvFail ("no interpreter");
}
#else
#define ClassError _CL_Q34java4lang5Error
extern java::lang::Class ClassError;
static const int PUBLIC = 0x001;
static const int PRIVATE = 0x002;
static const int PROTECTED = 0x004;
static const int STATIC = 0x008;
static const int FINAL = 0x010;
static const int SYNCHRONIZED = 0x020;
static const int VOLATILE = 0x040;
static const int TRANSIENT = 0x080;
static const int NATIVE = 0x100;
static const int INTERFACE = 0x200;
static const int ABSTRACT = 0x400;
static const int ALL_FLAGS = 0x7FF;
static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
static void throw_internal_error (char *msg)
__attribute__ ((__noreturn__));
static void throw_incompatible_class_change_error (jstring msg)
__attribute__ ((__noreturn__));
#if !HANDLE_SEGV
static void throw_null_pointer_exception ()
__attribute__ ((__noreturn__));
#endif
#if !HANDLE_FPE
static void throw_arithmetic_exception ()
__attribute__ ((__noreturn__));
#endif
static inline void dupx (void **&sp, int n, int x)
{
// first "slide" n+x elements n to the right
int top = n-1;
for (int i = 0; i < n+x; i++)
{
sp[(top-i)] = sp[(top-i)-n];
}
// next, copy the n top elements, n+x down
for (int i = 0; i < n; i++)
{
sp[top-(n+x)-i] = sp[top-i];
}
// the net effect
sp += n;
};
#define PUSHA(V) \
({ jobject __v=(V); *(jobject*)sp++ = __v; })
#define PUSHI(V) \
({ jint __v=(V); *(jint*)sp++ = __v; })
#define PUSHF(V) \
({ jfloat __v=(V); *(jfloat*)sp++ = __v; })
#define PUSHL(V) \
({ jlong __v=(V); memcpy ((void*)sp, (void*)&__v, 8); sp+=2; })
#define PUSHD(V) \
({ jdouble __v=(V); memcpy ((void*)sp, (void*)&__v, 8); sp+=2; })
#define POPA() (*(jobject*)--sp)
#define POPI() (*(jint*)--sp)
#define POPF() (*(jfloat*)--sp)
#define POPL() ({ jlong __r; sp-=2; memcpy ((void*)&__r, sp, 8); __r; })
#define POPD() ({ jdouble __r; sp-=2; memcpy ((void*)&__r, sp, 8); __r; })
#define LOADA(I) *sp++ = locals[I]
#define LOADI(I) *sp++ = locals[I]
#define LOADF(I) *sp++ = locals[I]
#define LOADL(I) ({ memcpy (sp, locals+(I), 8); sp+=2; })
#define LOADD(I) ({ memcpy (sp, locals+(I), 8); sp+=2; })
#define STOREA(I) locals[I] = *--sp
#define STOREI(I) locals[I] = *--sp
#define STOREF(I) locals[I] = *--sp
#define STOREL(I) ({ sp-=2; memcpy (locals+(I), sp, 8); })
#define STORED(I) ({ sp-=2; memcpy (locals+(I), sp, 8); })
#define PEEKI(I) (*(jint*) (locals+(I)))
#define PEEKA(I) (*(jobject*) (locals+(I)))
#define POKEI(I,V) (*(jint*) (locals+(I)) = (V))
#define BINOPI(OP) { \
jint value2 = POPI(); \
jint value1 = POPI(); \
PUSHI(value1 OP value2); \
}
#define BINOPF(OP) { \
jfloat value2 = POPF(); \
jfloat value1 = POPF(); \
PUSHF(value1 OP value2); \
}
#define BINOPL(OP) { \
jlong value2 = POPL(); \
jlong value1 = POPL(); \
PUSHL(value1 OP value2); \
}
#define BINOPD(OP) { \
jdouble value2 = POPD(); \
jdouble value1 = POPD(); \
PUSHD(value1 OP value2); \
}
static inline jint get1s(unsigned char* loc) {
return *(signed char*)loc;
}
static inline jint get1u(unsigned char* loc) {
return *loc;
}
static inline jint get2s(unsigned char* loc) {
return (((jint)*(signed char*)loc) << 8) | ((jint)*(loc+1));
}
static inline jint get2u(unsigned char* loc) {
return (((jint)(*loc)) << 8) | ((jint)*(loc+1));
}
static jint get4(unsigned char* loc) {
return (((jint)(loc[0])) << 24)
| (((jint)(loc[1])) << 16)
| (((jint)(loc[2])) << 8)
| (((jint)(loc[3])) << 0);
}
#if HANDLE_SEGV
#define NULLCHECK(X)
#else
#define NULLCHECK(X) \
do { if ((X)==NULL) throw_null_pointer_exception (); } while (0)
#endif
#if HANDLE_FPE
#define ZEROCHECK(X)
#else
#define ZEROCHECK(X) \
do { if ((X) == 0) throw_arithmetic_exception (); } while (0)
#endif
// this method starts the actual running of the method. It is inlined
// in three different variants in the static methods run_normal,
// run_sync_object and run_sync_class (see below). Those static methods
// are installed directly in the stub for this method (by
// _Jv_InterpMethod::ncode, in resolve.cc).
inline jobject
_Jv_InterpMethod::run (ffi_cif* cif,
void *retp,
void**args,
_Jv_InterpMethodInvocation *inv)
{
inv->running = this;
inv->pc = bytecode ();
inv->sp = inv->stack_base ();
void **locals = inv->local_base ();
/* Go straight at it! the ffi raw format matches the internal
stack representation exactly!
*/
memcpy ((void*) locals, (void*) args, args_raw_size);
next_segment:
/* this will call the method _Jv_InterpMethod::continue0, see below */
jobject ex =
gnu::gcj::runtime::MethodInvocation::continue0
((gnu::gcj::RawData *)this, (gnu::gcj::RawData *)inv);
if (ex == 0) // no exception...
{
/* define sp locally, so the POP? macros will pick it up */
void **sp = (void**)inv->sp;
int rtype = cif->rtype->type;
if (rtype == FFI_TYPE_POINTER)
{
jobject r = POPA();
*(jobject*) retp = r;
return 0;
}
else if (rtype == FFI_TYPE_SINT32)
{
jint r = POPI();
*(jint*)retp = r;
return 0;
}
else if (rtype == FFI_TYPE_VOID)
{
return 0;
}
else switch (rtype)
{
case FFI_TYPE_FLOAT:
{
jfloat r = POPF();
*(jfloat*)retp = r;
return 0;
}
case FFI_TYPE_DOUBLE:
{
jdouble r = POPD();
*(jdouble*)retp = r;
return 0;
}
case FFI_TYPE_UINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT8:
case FFI_TYPE_SINT16:
{
jint r = POPI();
*(jint*)retp = r;
return 0;
}
case FFI_TYPE_SINT64:
{
jlong r = POPL();
*(jlong*)retp = r;
return 0;
}
default:
throw_internal_error ("unknown return type");
}
}
/** handle an exception */
if ( find_exception (ex, inv) )
goto next_segment;
java::lang::System::out->println
(_Jv_NewStringUTF (self->name->data));
return ex;
}
bool _Jv_InterpMethod::find_exception (jobject ex,
_Jv_InterpMethodInvocation *inv)
{
int logical_pc = inv->pc - bytecode ();
_Jv_InterpException *exc = exceptions ();
jclass exc_class = ex->getClass ();
for (int i = 0; i < exc_count; i++)
{
if (exc[i].start_pc <= logical_pc && logical_pc < exc[i].end_pc)
{
jclass handler;
if (exc[i].handler_type != 0)
handler = (jclass)
_Jv_ResolvePoolEntry (defining_class,
exc[i].handler_type);
else
handler = NULL;
if (handler==NULL || handler->isAssignableFrom (exc_class))
{
inv->pc = bytecode () + exc[i].handler_pc;
inv->sp = inv->stack_base (); // reset stack
*(jobject*) (inv->sp ++) = ex;
return true;
}
}
}
return false;
}
void _Jv_InterpMethod::run_normal (ffi_cif* cif,
void* ret,
void** args,
void* __this)
{
_Jv_InterpMethod* _this = (_Jv_InterpMethod*)__this;
// we do the alloca of the method invocation here, to allow the method
// "run" ro be inlined. Otherwise gcc will ignore the inline directive.
int storage_size = _this->max_stack+_this->max_locals;
_Jv_InterpMethodInvocation* inv = (_Jv_InterpMethodInvocation*)
alloca (sizeof (_Jv_InterpMethodInvocation)
+ storage_size * sizeof (void*));
jobject ex = _this->run (cif, ret, args, inv);
if (ex != 0) _Jv_Throw (ex);
}
void _Jv_InterpMethod::run_synch_object (ffi_cif* cif,
void* ret,
void** args,
void* __this)
{
_Jv_InterpMethod* _this = (_Jv_InterpMethod*)__this;
jobject rcv = (jobject)args[0];
int storage_size = _this->max_stack+_this->max_locals;
_Jv_InterpMethodInvocation* inv = (_Jv_InterpMethodInvocation*)
alloca (sizeof (_Jv_InterpMethodInvocation)
+ storage_size * sizeof (void*));
_Jv_MonitorEnter (rcv);
jobject ex = _this->run (cif, ret, args, inv);
_Jv_MonitorExit (rcv);
if (ex != 0) _Jv_Throw (ex);
}
void _Jv_InterpMethod::run_synch_class (ffi_cif* cif,
void* ret,
void** args,
void* __this)
{
_Jv_InterpMethod* _this = (_Jv_InterpMethod*)__this;
jclass sync = _this->defining_class;
int storage_size = _this->max_stack+_this->max_locals;
_Jv_InterpMethodInvocation* inv = (_Jv_InterpMethodInvocation*)
alloca (sizeof (_Jv_InterpMethodInvocation)
+ storage_size * sizeof (void*));
_Jv_MonitorEnter (sync);
jobject ex = _this->run (cif, ret, args, inv);
_Jv_MonitorExit (sync);
if (ex != 0) _Jv_Throw (ex);
}
/* this is the exception handler hack, for the interpreter */
void
gnu::gcj::runtime::MethodInvocation::continue1 (gnu::gcj::RawData *meth,
gnu::gcj::RawData *inv)
{
_Jv_InterpMethod *meth0 = (_Jv_InterpMethod*)meth;
_Jv_InterpMethodInvocation *inv0 = (_Jv_InterpMethodInvocation*)inv;
meth0->continue1 (inv0);
}
/*
This proceeds execution, as designated in "inv". If an exception
happens, then it is simply thrown, and handled in Java. Thus, the pc
needs to be stored in the invocation at all times, so we can figure
out which handler (if any) to invoke.
One design issue, which I have not completely considered, is if it
should be possible to have interpreted classes linked in! Seldom used
(or non-critical) classes could reasonably be interpreted.
*/
#ifdef TIME_MAINLOOP
static jlong insn_time [256] = { 0 };
static jlong insn_count[256] = { 0 };
static void
dump_time ()
{
double total_all = 0;
for (int i = 0; i < 256; i++)
{
total_all += insn_time[i];
}
for (int i = 0; i < 256; i++)
{
jlong total = insn_time[i];
jlong count = insn_count[i];
if (count == 0) continue;
jlong amount = total/count;
printf ("in 0x%02x: %7Li %7Li %7Li %2.1f%%\n", i,
(long long)count, (long long)total, (long long)amount,
(float) (100.0*(double)total/total_all)
);
}
}
#endif
void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
{
/* for some reason, which I do not understand, the compiler on x86
* allocates almost 4k stack space for this function! Even though
* there are many local variables, they are all nicely contained
* within a block scope, except for the few declared right below
* here. What's going on?? It could well be, that there in fact is
* on the order of 1000 local variables, including all those inlined
* and expanded from macros... Compiling with -O0, it allocates a
* "modest" 300 bytes of stack space. Among all those options of
* gcc, why isn't there a -fpack-stack, allowing reuse of stack
* locations? */
void** sp = inv->sp;
unsigned char *pc = inv->pc;
void** locals = inv->local_base ();
int opcode;
jclass defining_class = this->defining_class;
void **pool_data = defining_class->constants.data;
/* these two are used in the invokeXXX instructions */
void (*fun)(...);
_Jv_ResolvedMethod* rmeth;
#ifdef TIME_MAINLOOP
struct timeval tv;
int last_opcode;
jlong last_time;
static jlong time_warp = 0;
#define USEC(TV) \
((jlong) (TV).tv_sec * 1000000LL + (jlong)(TV).tv_usec)
if (time_warp == 0)
{
struct timeval tv2;
gettimeofday (&tv, 0);
for (int i = 0; i < 100; i++)
gettimeofday (&tv2, 0);
jlong then = USEC(tv);
jlong now = USEC(tv2);
time_warp = (now - then) / 100;
if (time_warp == 0)
time_warp = 1;
}
#define TIME_SUSPEND do { \
gettimeofday (&tv, 0); \
jlong now = USEC(tv); \
insn_time[last_opcode] += (now - last_time) - time_warp; \
} while(0)
#define TIME_RESUME do { \
gettimeofday (&tv, 0); \
last_time = USEC(tv); \
} while(0)
last_opcode = 0;
gettimeofday (&tv, 0);
last_time = (jlong)tv.tv_sec * 1000000LL + (jlong)tv.tv_usec;
#else
#define TIME_SUSPEND
#define TIME_RESUME
#endif
next_insn:
inv->pc = pc;
#ifdef TIME_MAINLOOP
gettimeofday (&tv, 0);
jlong now = USEC(tv);
insn_time[last_opcode] += (now - last_time) - time_warp;
last_time = now;
last_opcode = *pc;
insn_count[last_opcode] += 1;
#endif
opcode = *pc++;
/* we special-case the single opcode aload_0 -- it makes
up 10% of the time spent in the main loop. */
switch (opcode)
{
case op_aload_0: // 0x2a
LOADA(0);
goto next_insn;
case op_iload: // 0x15
LOADI (get1u (pc++));
goto next_insn;
case op_getfield_4: // 0xd8
{
jobject obj = POPA();
NULLCHECK(obj);
jint field_offset = get2u (pc); pc += 2;
PUSHI (*(jint*) ((char*)obj + field_offset));
}
goto next_insn;
case op_iload_1: // 0x1b
LOADI (1);
goto next_insn;
case op_getfield_a: // 0xda
{
jobject obj = POPA();
NULLCHECK(obj);
jint field_offset = get2u (pc); pc += 2;
PUSHA(*(jobject*) ((char*)obj + field_offset));
}
goto next_insn;
case op_invokevirtual: // 0xb6
{
int index = get2u (pc); pc += 2;
/* _Jv_ResolvePoolEntry returns immediately if the value already
* is resolved. If we want to clutter up the code here to gain
* a little performance, then we can check the corresponding bit
* JV_CONSTANT_ResolvedFlag in the tag directly. For now, I
* don't think it is worth it. */
rmeth = (_Jv_ResolvedMethod*)
_Jv_ResolvePoolEntry (defining_class, index);
sp -= rmeth->stack_item_count;
NULLCHECK(sp[0]);
if (rmeth->vtable_index == -1)
{
// final methods do not appear in the vtable,
// if it does not appear in the superclass.
fun = (void (*) (...)) rmeth->method->ncode;
}
else
{
jobject rcv = (jobject)sp[0];
_Jv_VTable *table = *(_Jv_VTable**)rcv;
fun = (void (*) (...))table->method[rmeth->vtable_index];
}
}
goto perform_invoke;
perform_invoke:
{
/* here goes the magic again... */
ffi_cif *cif = &rmeth->cif;
void **raw = sp;
jdouble rvalue;
TIME_SUSPEND;
ffi_raw_call (cif, fun, (void*)&rvalue, (ffi_raw*) raw);
TIME_RESUME;
int rtype = cif->rtype->type;
/* the likelyhood of object, int, or void return is very high,
* so those are checked before the switch */
if (rtype == FFI_TYPE_POINTER)
{
PUSHA (*(jobject*)&rvalue);
}
else if (rtype == FFI_TYPE_SINT32)
{
PUSHI (*(jint*)&rvalue);
}
else if (rtype == FFI_TYPE_VOID)
{
/* skip */
}
else switch (rtype)
{
case FFI_TYPE_SINT8:
{
jbyte value = (*(jint*)&rvalue) & 0xff;
PUSHI (value);
}
break;
case FFI_TYPE_SINT16:
{
jshort value = (*(jint*)&rvalue) & 0xffff;
PUSHI (value);
}
break;
case FFI_TYPE_UINT16:
{
jint value = (*(jint*)&rvalue) & 0xffff;
PUSHI (value);
}
break;
case FFI_TYPE_FLOAT:
PUSHF (*(jfloat*)&rvalue);
break;
case FFI_TYPE_DOUBLE:
PUSHD (rvalue);
break;
case FFI_TYPE_SINT64:
PUSHL (*(jlong*)&rvalue);
break;
default:
throw_internal_error ("unknown return type in invokeXXX");
}
}
goto next_insn;
case op_nop:
goto next_insn;
case op_aconst_null:
PUSHA (NULL);
goto next_insn;
case op_iconst_m1:
case op_iconst_0:
case op_iconst_1:
case op_iconst_2:
case op_iconst_3:
case op_iconst_4:
case op_iconst_5:
PUSHI (opcode-op_iconst_0);
goto next_insn;
case op_lconst_0:
case op_lconst_1:
PUSHL ((jlong) (opcode-op_lconst_0));
goto next_insn;
case op_fconst_0:
case op_fconst_1:
case op_fconst_2:
PUSHF ((jfloat) (opcode-op_fconst_0));
goto next_insn;
case op_dconst_0:
case op_dconst_1:
PUSHD ((jdouble) (opcode-op_dconst_0));
goto next_insn;
case op_bipush:
PUSHI (get1s(pc++));
goto next_insn;
case op_sipush:
PUSHI (get2s(pc)); pc += 2;
goto next_insn;
case op_ldc:
{
int index = get1u (pc++);
PUSHA((jobject) pool_data[index]);
}
goto next_insn;
case op_ldc_w:
{
int index = get2u (pc); pc += 2;
PUSHA((jobject) pool_data[index]);
}
goto next_insn;
case op_ldc2_w:
{
int index = get2u (pc); pc += 2;
memcpy (sp, &pool_data[index], 8);
sp += 2;
}
goto next_insn;
case op_lload:
LOADL (get1u (pc++));
goto next_insn;
case op_fload:
LOADF (get1u (pc++));
goto next_insn;
case op_dload:
LOADD (get1u (pc++));
goto next_insn;
case op_aload:
LOADA (get1u (pc++));
goto next_insn;
case op_iload_0:
LOADI (0);
goto next_insn;
case op_iload_2:
LOADI (2);
goto next_insn;
case op_iload_3:
LOADI (3);
goto next_insn;
case op_lload_0:
case op_lload_1:
case op_lload_2:
case op_lload_3:
LOADL (opcode-op_lload_0);
goto next_insn;
case op_fload_0:
case op_fload_1:
case op_fload_2:
case op_fload_3:
LOADF (opcode-op_fload_0);
goto next_insn;
case op_dload_0:
case op_dload_1:
case op_dload_2:
case op_dload_3:
LOADD (opcode-op_dload_0);
goto next_insn;
case op_aload_1:
LOADA(1);
goto next_insn;
case op_aload_2:
LOADA(2);
goto next_insn;
case op_aload_3:
LOADA(3);
goto next_insn;
case op_iaload:
{
jint index = POPI();
jintArray arr = (jintArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
PUSHI( elements(arr)[index] );
}
goto next_insn;
case op_laload:
{
jint index = POPI();
jlongArray arr = (jlongArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
PUSHL( elements(arr)[index] );
}
goto next_insn;
case op_faload:
{
jint index = POPI();
jfloatArray arr = (jfloatArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
PUSHF( elements(arr)[index] );
}
goto next_insn;
case op_daload:
{
jint index = POPI();
jdoubleArray arr = (jdoubleArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
PUSHD( elements(arr)[index] );
}
goto next_insn;
case op_aaload:
{
jint index = POPI();
jobjectArray arr = (jobjectArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
PUSHA( elements(arr)[index] );
}
goto next_insn;
case op_baload:
{
jint index = POPI();
jbyteArray arr = (jbyteArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
PUSHI( elements(arr)[index] );
}
goto next_insn;
case op_caload:
{
jint index = POPI();
jcharArray arr = (jcharArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
PUSHI( elements(arr)[index] );
}
goto next_insn;
case op_saload:
{
jint index = POPI();
jshortArray arr = (jshortArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
PUSHI( elements(arr)[index] );
}
goto next_insn;
case op_istore:
STOREI (get1u (pc++));
goto next_insn;
case op_lstore:
STOREL (get1u (pc++));
goto next_insn;
case op_fstore:
STOREF (get1u (pc++));
goto next_insn;
case op_dstore:
STORED (get1u (pc++));
goto next_insn;
case op_astore:
STOREI (get1u (pc++));
goto next_insn;
case op_istore_0:
case op_istore_1:
case op_istore_2:
case op_istore_3:
STOREI (opcode-op_istore_0);
goto next_insn;
case op_lstore_0:
case op_lstore_1:
case op_lstore_2:
case op_lstore_3:
STOREL (opcode-op_lstore_0);
goto next_insn;
case op_fstore_0:
case op_fstore_1:
case op_fstore_2:
case op_fstore_3:
STOREF (opcode-op_fstore_0);
goto next_insn;
case op_dstore_0:
case op_dstore_1:
case op_dstore_2:
case op_dstore_3:
STORED (opcode-op_dstore_0);
goto next_insn;
case op_astore_0:
case op_astore_1:
case op_astore_2:
case op_astore_3:
STOREA (opcode-op_astore_0);
goto next_insn;
case op_iastore:
{
jint value = POPI();
jint index = POPI();
jintArray arr = (jintArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
elements(arr)[index] = value;
}
goto next_insn;
case op_lastore:
{
jlong value = POPL();
jint index = POPI();
jlongArray arr = (jlongArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
elements(arr)[index] = value;
}
goto next_insn;
case op_fastore:
{
jfloat value = POPF();
jint index = POPI();
jfloatArray arr = (jfloatArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
elements(arr)[index] = value;
}
goto next_insn;
case op_dastore:
{
jdouble value = POPD();
jint index = POPI();
jdoubleArray arr = (jdoubleArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
elements(arr)[index] = value;
}
goto next_insn;
case op_aastore:
{
jobject value = POPA();
jint index = POPI();
jobjectArray arr = (jobjectArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
_Jv_CheckArrayStore (arr, value);
elements(arr)[index] = value;
}
goto next_insn;
case op_bastore:
{
jbyte value = (jbyte) POPI();
jint index = POPI();
jbyteArray arr = (jbyteArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
elements(arr)[index] = value;
}
goto next_insn;
case op_castore:
{
jchar value = (jchar) POPI();
jint index = POPI();
jcharArray arr = (jcharArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
elements(arr)[index] = value;
}
goto next_insn;
case op_sastore:
{
jshort value = (jshort) POPI();
jint index = POPI();
jshortArray arr = (jshortArray) POPA();
NULLCHECK (arr);
if (index < 0 || index >= arr->length)
{
TIME_SUSPEND;
_Jv_ThrowBadArrayIndex (index);
}
elements(arr)[index] = value;
}
goto next_insn;
case op_pop:
sp -= 1;
goto next_insn;
case op_pop2:
sp -= 2;
goto next_insn;
case op_dup:
sp[0] = sp[-1];
sp += 1;
goto next_insn;
case op_dup_x1:
dupx (sp, 1, 1);
goto next_insn;
case op_dup_x2:
dupx (sp, 1, 2);
goto next_insn;
case op_dup2:
sp[0] = sp[-2];
sp[1] = sp[-1];
sp += 2;
goto next_insn;
case op_dup2_x1:
dupx (sp, 2, 1);
goto next_insn;
case op_dup2_x2:
dupx (sp, 2, 2);
goto next_insn;
case op_swap:
{
jobject tmp1 = POPA();
jobject tmp2 = POPA();
PUSHA (tmp1);
PUSHA (tmp2);
}
goto next_insn;
case op_iadd:
BINOPI(+);
goto next_insn;
case op_ladd:
BINOPL(+);
goto next_insn;
case op_fadd:
BINOPF(+);
goto next_insn;
case op_dadd:
BINOPD(+);
goto next_insn;
case op_isub:
BINOPI(-);
goto next_insn;
case op_lsub:
BINOPL(-);
goto next_insn;
case op_fsub:
BINOPF(-);
goto next_insn;
case op_dsub:
BINOPD(-);
goto next_insn;
case op_imul:
BINOPI(*);
goto next_insn;
case op_lmul:
BINOPL(*);
goto next_insn;
case op_fmul:
BINOPF(*);
goto next_insn;
case op_dmul:
BINOPD(*);
goto next_insn;
case op_idiv:
{
jint value2 = POPI();
jint value1 = POPI();
ZEROCHECK (value2);
jint res = value1 / value2;
PUSHI (res);
}
goto next_insn;
case op_ldiv:
{
jlong value2 = POPL();
jlong value1 = POPL();
ZEROCHECK (value2);
jlong res = value1 / value2;
PUSHL (res);
}
goto next_insn;
case op_fdiv:
{
jfloat value2 = POPF();
jfloat value1 = POPF();
ZEROCHECK (value2);
jfloat res = value1 / value2;
PUSHF (res);
}
goto next_insn;
case op_ddiv:
{
jdouble value2 = POPD();
jdouble value1 = POPD();
ZEROCHECK (value2);
jdouble res = value1 / value2;
PUSHD (res);
}
goto next_insn;
case op_irem:
{
jint value2 = POPI();
jint value1 = POPI();
ZEROCHECK (value2);
jint res = value1 % value2;
PUSHI (res);
}
goto next_insn;
case op_lrem:
{
jlong value2 = POPL();
jlong value1 = POPL();
ZEROCHECK (value2);
jlong res = value1 % value2;
PUSHL (res);
}
goto next_insn;
case op_frem:
{
jfloat value2 = POPF();
jfloat value1 = POPF();
ZEROCHECK (value2);
jfloat res = __ieee754_fmod (value1, value2);
PUSHF (res);
}
goto next_insn;
case op_drem:
{
jdouble value2 = POPD();
jdouble value1 = POPD();
ZEROCHECK (value2);
jdouble res = __ieee754_fmod (value1, value2);
PUSHD (res);
}
goto next_insn;
case op_ineg:
*(jint*) (sp-1) *= -1;
goto next_insn;
case op_lneg:
*(jlong*) (sp-1) *= -1;
goto next_insn;
case op_fneg:
*(jfloat*) (sp-1) *= -1;
goto next_insn;
case op_dneg:
*(jdouble*) (sp-1) *= -1;
goto next_insn;
case op_ishl:
{
jint shift = (POPI() & 0x1f);
jint value = POPI();
PUSHI (value << shift);
}
goto next_insn;
case op_lshl:
{
jint shift = (POPI() & 0x3f);
jlong value = POPL();
PUSHL (value << shift);
}
goto next_insn;
case op_ishr:
{
jint shift = (POPI() & 0x1f);
jint value = POPI();
PUSHI (value >> shift);
}
goto next_insn;
case op_lshr:
{
jint shift = (POPI() & 0x3f);
jlong value = POPL();
PUSHL (value >> shift);
}
goto next_insn;
case op_iushr:
{
jint shift = (POPI() & 0x1f);
unsigned long value = POPI();
PUSHI ((jint) (value >> shift));
}
goto next_insn;
case op_lushr:
{
jint shift = (POPI() & 0x3f);
UINT64 value = (UINT64) POPL();
PUSHL ((value >> shift));
}
goto next_insn;
case op_iand:
BINOPI (&);
goto next_insn;
case op_land:
BINOPL (&);
goto next_insn;
case op_ior:
BINOPI (|);
goto next_insn;
case op_lor:
BINOPL (|);
goto next_insn;
case op_ixor:
BINOPI (^);
goto next_insn;
case op_lxor:
BINOPL (^);
goto next_insn;
case op_iinc:
{
jint index = get1u (pc++);
jint amount = get1s (pc++);
*(jint*) (locals + index) += amount;
}
goto next_insn;
case op_i2l:
PUSHL ((jlong)POPI ());
goto next_insn;
case op_i2f:
PUSHF ((jfloat)POPI ());
goto next_insn;
case op_i2d:
PUSHD ((jdouble)POPI ());
goto next_insn;
case op_l2i:
PUSHI ((jint)POPL ());
goto next_insn;
case op_l2f:
PUSHF ((jfloat)POPL ());
goto next_insn;
case op_l2d:
PUSHD ((jdouble)POPL ());
goto next_insn;
case op_f2i:
PUSHI ((jint)POPF ());
goto next_insn;
case op_f2l:
PUSHL ((jlong)POPF ());
goto next_insn;
case op_f2d:
PUSHD ((jdouble)POPF ());
goto next_insn;
case op_d2i:
PUSHI ((jint)POPD ());
goto next_insn;
case op_d2l:
PUSHL ((jlong)POPD ());
goto next_insn;
case op_d2f:
PUSHF ((jfloat)POPD ());
goto next_insn;
case op_i2b:
PUSHI ((jbyte)POPI ());
goto next_insn;
case op_i2c:
PUSHI ((jchar)POPI ());
goto next_insn;
case op_i2s:
PUSHI ((jshort)POPI ());
goto next_insn;
case op_lcmp:
{
jlong value2 = POPL ();
jlong value1 = POPL ();
if (value1 > value2)
{ PUSHI (1); }
else if (value1 == value2)
{ PUSHI (0); }
else
{ PUSHI (-1); }
}
goto next_insn;
case op_fcmpl:
case op_fcmpg:
{
jfloat value2 = POPF ();
jfloat value1 = POPF ();
if (value1 > value2)
PUSHI (1);
else if (value1 == value2)
PUSHI (0);
else if (value1 < value2)
PUSHI (-1);
else if (opcode == op_fcmpg)
PUSHI (1);
else
PUSHI (-1);
}
goto next_insn;
case op_dcmpl:
case op_dcmpg:
{
jdouble value2 = POPD ();
jdouble value1 = POPD ();
if (value1 > value2)
PUSHI (1);
else if (value1 == value2)
PUSHI (0);
else if (value1 < value2)
PUSHI (-1);
else if (opcode == op_dcmpg)
PUSHI (1);
else
PUSHI (-1);
}
goto next_insn;
case op_ifeq:
{
jint offset = get2s (pc);
if (POPI() == 0)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_ifne:
{
jint offset = get2s (pc);
if (POPI() != 0)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_iflt:
{
jint offset = get2s (pc);
if (POPI() < 0)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_ifge:
{
jint offset = get2s (pc);
if (POPI() >= 0)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_ifgt:
{
jint offset = get2s (pc);
if (POPI() > 0)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_ifle:
{
jint offset = get2s (pc);
if (POPI() <= 0)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_if_icmpeq:
{
jint offset = get2s (pc);
jint value2 = POPI();
jint value1 = POPI();
if (value1 == value2)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_if_icmpne:
{
jint offset = get2s (pc);
jint value2 = POPI();
jint value1 = POPI();
if (value1 != value2)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_if_icmplt:
{
jint offset = get2s (pc);
jint value2 = POPI();
jint value1 = POPI();
if (value1 < value2)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_if_icmpge:
{
jint offset = get2s (pc);
jint value2 = POPI();
jint value1 = POPI();
if (value1 >= value2)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_if_icmpgt:
{
jint offset = get2s (pc);
jint value2 = POPI();
jint value1 = POPI();
if (value1 > value2)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_if_icmple:
{
jint offset = get2s (pc);
jint value2 = POPI();
jint value1 = POPI();
if (value1 <= value2)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_if_acmpeq:
{
jint offset = get2s (pc);
jobject value2 = POPA();
jobject value1 = POPA();
if (value1 == value2)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_if_acmpne:
{
jint offset = get2s (pc);
jobject value2 = POPA();
jobject value1 = POPA();
if (value1 != value2)
pc = pc-1+offset;
else
pc = pc+2;
}
goto next_insn;
case op_goto:
{
jint offset = get2s (pc);
pc = pc-1+offset;
}
goto next_insn;
case op_jsr:
{
unsigned char *base_pc = pc-1;
jint offset = get2s (pc); pc += 2;
PUSHA ((jobject)pc);
pc = base_pc+offset;
}
goto next_insn;
case op_ret:
{
jint index = get1u (pc);
pc = (unsigned char*) PEEKA (index);
}
goto next_insn;
case op_tableswitch:
{
unsigned char *base_pc = pc-1;
int index = POPI();
unsigned char* base = bytecode ();
while ((pc-base) % 4 != 0)
pc++;
jint def = get4 (pc);
jint low = get4 (pc+4);
jint high = get4 (pc+8);
if (index < low || index > high)
pc = base_pc + def;
else
pc = base_pc + get4 (pc+4*(index-low+3));
}
goto next_insn;
case op_lookupswitch:
{
unsigned char *base_pc = pc-1;
int index = POPI();
unsigned char* base = bytecode ();
while ((pc-base) % 4 != 0)
pc++;
jint def = get4 (pc);
jint npairs = get4 (pc+4);
int max = npairs-1;
int min = 0;
// simple binary search...
while (min < max)
{
int half = (min+max)/2;
int match = get4 (pc+ 4*(2 + 2*half));
if (index == match)
min = max = half;
else if (index < match)
max = half-1;
else
min = half+1;
}
if (index == get4 (pc+ 4*(2 + 2*min)))
pc = base_pc + get4 (pc+ 4*(2 + 2*min + 1));
else
pc = base_pc + def;
}
goto next_insn;
/* on return, just save the sp and return to caller */
case op_ireturn:
case op_lreturn:
case op_freturn:
case op_dreturn:
case op_areturn:
case op_return:
inv->sp = sp;
TIME_SUSPEND;
return;
case op_getstatic:
{
unsigned char *base_pc = pc-1;
jint fieldref_index = get2u (pc); pc += 2;
_Jv_ResolvePoolEntry (defining_class, fieldref_index);
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
if ((field->flags & STATIC) == 0)
throw_incompatible_class_change_error
(JvNewStringLatin1 ("field no longer static"));
jclass type = field->type;
if (type->isPrimitive ())
{
switch (type->size_in_bytes)
{
case 1:
*base_pc = op_getstatic_1;
break;
case 2:
if (type == JvPrimClass (char))
*base_pc = op_getstatic_2u;
else
*base_pc = op_getstatic_2s;
break;
case 4:
*base_pc = op_getstatic_4;
break;
case 8:
*base_pc = op_getstatic_8;
break;
}
}
else
{
*base_pc = op_getstatic_a;
}
pc = base_pc;
}
goto next_insn;
case op_getfield:
{
unsigned char *base_pc = pc-1;
jint fieldref_index = get2u (pc); pc += 2;
_Jv_ResolvePoolEntry (defining_class, fieldref_index);
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
if ((field->flags & STATIC) != 0)
throw_incompatible_class_change_error
(JvNewStringLatin1 ("field is static"));
jclass type = field->type;
if (type->isPrimitive ())
{
switch (type->size_in_bytes)
{
case 1:
*base_pc = op_getfield_1;
break;
case 2:
if (type == JvPrimClass (char))
*base_pc = op_getfield_2u;
else
*base_pc = op_getfield_2s;
break;
case 4:
*base_pc = op_getfield_4;
break;
case 8:
*base_pc = op_getfield_8;
break;
}
}
else
{
*base_pc = op_getfield_a;
}
if (field->u.boffset > 0xffff)
JvThrow (new java::lang::VirtualMachineError);
base_pc[1] = (field->u.boffset>>8) & 0xff;
base_pc[2] = field->u.boffset & 0xff;
pc = base_pc;
}
goto next_insn;
case op_putstatic:
{
unsigned char* base_pc = pc-1;
jint fieldref_index = get2u (pc); pc += 2;
_Jv_ResolvePoolEntry (defining_class, fieldref_index);
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
jclass type = field->type;
// ResolvePoolEntry cannot check this
if ((field->flags & STATIC) == 0)
throw_incompatible_class_change_error
(JvNewStringLatin1 ("field no longer static"));
/* if this is patented, then maybe we could install
a function in the constant pool, to do the right thing */
if (type->isPrimitive ())
{
switch (type->size_in_bytes)
{
case 1:
*base_pc = op_putstatic_1;
break;
case 2:
*base_pc = op_putstatic_2;
break;
case 4:
*base_pc = op_putstatic_4;
break;
case 8:
*base_pc = op_putstatic_8;
break;
}
}
else
{
*base_pc = op_putstatic_a;
}
// do the instruction again!
pc = base_pc;
}
goto next_insn;
case op_putfield:
{
unsigned char* base_pc = pc-1;
jint fieldref_index = get2u (pc); pc += 2;
_Jv_ResolvePoolEntry (defining_class, fieldref_index);
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
jclass type = field->type;
if ((field->flags & STATIC) != 0)
throw_incompatible_class_change_error
(JvNewStringLatin1 ("field is static"));
if (type->isPrimitive ())
{
switch (type->size_in_bytes)
{
case 1:
*base_pc = op_putfield_1;
break;
case 2:
*base_pc = op_putfield_2;
break;
case 4:
*base_pc = op_putfield_4;
break;
case 8:
*base_pc = op_putfield_8;
break;
}
}
else
{
*base_pc = op_putfield_a;
}
if (field->u.boffset > 0xffff)
JvThrow (new java::lang::VirtualMachineError);
base_pc[1] = (field->u.boffset>>8) & 0xff;
base_pc[2] = field->u.boffset & 0xff;
// do the instruction again!
pc = base_pc;
}
goto next_insn;
case op_getfield_1:
{
jobject obj = POPA();
NULLCHECK(obj);
jint field_offset = get2u (pc); pc += 2;
PUSHI (*(jbyte*) ((char*)obj + field_offset));
}
goto next_insn;
case op_getfield_2s:
{
jobject obj = POPA();
NULLCHECK(obj);
jint field_offset = get2u (pc); pc += 2;
PUSHI (*(jshort*) ((char*)obj + field_offset));
}
goto next_insn;
case op_getfield_2u:
{
jobject obj = POPA();
NULLCHECK(obj);
jint field_offset = get2u (pc); pc += 2;
PUSHI (*(jchar*) ((char*)obj + field_offset));
}
goto next_insn;
case op_getfield_8:
{
jobject obj = POPA();
NULLCHECK(obj);
jint field_offset = get2u (pc); pc += 2;
PUSHL(*(jlong*) ((char*)obj + field_offset));
}
goto next_insn;
case op_getstatic_1:
{
jint fieldref_index = get2u (pc); pc += 2;
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
PUSHI (*(jbyte*) (field->u.addr));
}
goto next_insn;
case op_getstatic_2s:
{
jint fieldref_index = get2u (pc); pc += 2;
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
PUSHI(*(jshort*) (field->u.addr));
}
goto next_insn;
case op_getstatic_2u:
{
jint fieldref_index = get2u (pc); pc += 2;
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
PUSHI(*(jchar*) (field->u.addr));
}
goto next_insn;
case op_getstatic_4:
{
jint fieldref_index = get2u (pc); pc += 2;
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
PUSHI(*(jint*) (field->u.addr));
}
goto next_insn;
case op_getstatic_8:
{
jint fieldref_index = get2u (pc); pc += 2;
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
PUSHL(*(jlong*) (field->u.addr));
}
goto next_insn;
case op_getstatic_a:
{
jint fieldref_index = get2u (pc); pc += 2;
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
PUSHA(*(jobject*) (field->u.addr));
}
goto next_insn;
case op_putfield_1:
{
jint value = POPI();
jobject obj = POPA();
NULLCHECK(obj);
jint field_offset = get2u (pc); pc += 2;
*(jbyte*) ((char*)obj + field_offset) = value;
}
goto next_insn;
case op_putfield_2:
{
jint value = POPI();
jobject obj = POPA();
NULLCHECK(obj);
jint field_offset = get2u (pc); pc += 2;
*(jchar*) ((char*)obj + field_offset) = value;
}
goto next_insn;
case op_putfield_4:
{
jint value = POPI();
jobject obj = POPA();
NULLCHECK(obj);
jint field_offset = get2u (pc); pc += 2;
*(jint*) ((char*)obj + field_offset) = value;
}
goto next_insn;
case op_putfield_8:
{
jlong value = POPL();
jobject obj = POPA();
NULLCHECK(obj);
jint field_offset = get2u (pc); pc += 2;
*(jlong*) ((char*)obj + field_offset) = value;
}
goto next_insn;
case op_putfield_a:
{
jobject value = POPA();
jobject obj = POPA();
NULLCHECK(obj);
jint field_offset = get2u (pc); pc += 2;
*(jobject*) ((char*)obj + field_offset) = value;
}
goto next_insn;
case op_putstatic_1:
{
jint value = POPI();
jint fieldref_index = get2u (pc); pc += 2;
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
*(jbyte*) (field->u.addr) = value;
}
goto next_insn;
case op_putstatic_2:
{
jint value = POPI();
jint fieldref_index = get2u (pc); pc += 2;
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
*(jchar*) (field->u.addr) = value;
}
goto next_insn;
case op_putstatic_4:
{
jint value = POPI();
jint fieldref_index = get2u (pc); pc += 2;
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
*(jint*) (field->u.addr) = value;
}
goto next_insn;
case op_putstatic_8:
{
jlong value = POPL();
jint fieldref_index = get2u (pc); pc += 2;
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
*(jlong*) (field->u.addr) = value;
}
goto next_insn;
case op_putstatic_a:
{
jobject value = POPA();
jint fieldref_index = get2u (pc); pc += 2;
_Jv_Field *field = (_Jv_Field*) pool_data[fieldref_index];
*(jobject*) (field->u.addr) = value;
}
goto next_insn;
case op_invokespecial:
{
int index = get2u (pc); pc += 2;
rmeth = (_Jv_ResolvedMethod*)
_Jv_ResolvePoolEntry (defining_class, index);
sp -= rmeth->stack_item_count;
NULLCHECK(sp[0]);
fun = (void (*) (...))rmeth->method->ncode;
}
goto perform_invoke;
case op_invokestatic:
{
int index = get2u (pc); pc += 2;
rmeth = (_Jv_ResolvedMethod*)
_Jv_ResolvePoolEntry (defining_class, index);
sp -= rmeth->stack_item_count;
_Jv_InitClass (rmeth->klass);
fun = (void (*) (...))rmeth->method->ncode;
}
goto perform_invoke;
case op_invokeinterface:
{
int index = get2u (pc); pc += 2;
// invokeinterface has two unused bytes...
pc += 2;
rmeth = (_Jv_ResolvedMethod*)
_Jv_ResolvePoolEntry (defining_class, index);
sp -= rmeth->stack_item_count;
NULLCHECK(sp[0]);
jobject rcv = (jobject)sp[0];
fun = (void (*) (...))
_Jv_LookupInterfaceMethod (rcv->getClass (),
rmeth->method->name,
rmeth->method->signature);
}
goto perform_invoke;
case op_new:
{
int index = get2u (pc); pc += 2;
jclass klass = (jclass) _Jv_ResolvePoolEntry (defining_class,
index);
_Jv_InitClass (klass);
jobject res = _Jv_AllocObject (klass, klass->size_in_bytes);
PUSHA (res);
}
goto next_insn;
case op_newarray:
{
int atype = get1u (pc++);
int size = POPI();
jobject result = _Jv_NewArray (atype, size);
PUSHA (result);
}
goto next_insn;
case op_anewarray:
{
int index = get2u (pc); pc += 2;
jclass klass = (jclass) _Jv_ResolvePoolEntry (defining_class, index);
int size = POPI();
_Jv_InitClass (klass);
jobject result = _Jv_NewObjectArray (size, klass, 0);
PUSHA (result);
}
goto next_insn;
case op_arraylength:
{
__JArray *arr = (__JArray*)POPA();
PUSHI (arr->length);
}
goto next_insn;
case op_athrow:
{
jobject value = POPA();
TIME_SUSPEND;
JvThrow (value);
}
goto next_insn;
case op_checkcast:
{
jobject value = POPA();
jint index = get2u (pc); pc += 2;
jclass to = (jclass)_Jv_ResolvePoolEntry (defining_class,
index);
if (value != NULL && ! to->isInstance (value))
{
TIME_SUSPEND;
JvThrow (new java::lang::ClassCastException
(to->getName()));
}
PUSHA (value);
}
goto next_insn;
case op_instanceof:
{
jobject value = POPA();
jint index = get2u (pc); pc += 2;
jclass to = (jclass)_Jv_ResolvePoolEntry (defining_class,
index);
PUSHI (to->isInstance (value));
}
goto next_insn;
case op_monitorenter:
{
jobject value = POPA();
NULLCHECK(value);
_Jv_MonitorEnter (value);
}
goto next_insn;
case op_monitorexit:
{
jobject value = POPA();
NULLCHECK(value);
_Jv_MonitorExit (value);
}
goto next_insn;
case op_ifnull:
{
unsigned char* base_pc = pc-1;
jint offset = get2s (pc); pc += 2;
jobject val = POPA();
if (val == NULL)
pc = base_pc+offset;
}
goto next_insn;
case op_ifnonnull:
{
unsigned char* base_pc = pc-1;
jint offset = get2s (pc); pc += 2;
jobject val = POPA();
if (val != NULL)
pc = base_pc+offset;
}
goto next_insn;
case op_wide:
{
jint the_mod_op = get1u (pc++);
jint wide = get2u (pc); pc += 2;
switch (the_mod_op)
{
case op_istore:
STOREI (wide);
goto next_insn;
case op_fstore:
STOREF (wide);
goto next_insn;
case op_astore:
STOREA (wide);
goto next_insn;
case op_lload:
LOADL (wide);
goto next_insn;
case op_dload:
LOADD (wide);
goto next_insn;
case op_iload:
LOADI (wide);
goto next_insn;
case op_aload:
LOADA (wide);
goto next_insn;
case op_lstore:
STOREL (wide);
goto next_insn;
case op_dstore:
STORED (wide);
goto next_insn;
case op_ret:
pc = (unsigned char*) PEEKA (wide);
goto next_insn;
case op_iinc:
{
jint amount = get2s (pc); pc += 2;
jint value = PEEKI (wide);
POKEI (wide, value+amount);
}
goto next_insn;
default:
throw_internal_error ("illegal bytecode modified by wide");
}
}
case op_multianewarray:
{
int kind_index = get2u (pc); pc += 2;
int dim = get1u (pc); pc += 1;
jclass type = (jclass) _Jv_ResolvePoolEntry (defining_class,
kind_index);
_Jv_InitClass (type);
jint *sizes = (jint*) alloca (sizeof (jint)*dim);
for (int i = dim - 1; i >= 0; i--)
{
sizes[i] = POPI ();
}
jobject res = _Jv_NewMultiArray (type,dim, sizes);
PUSHA (res);
}
goto next_insn;
case op_goto_w:
{
unsigned char* base_pc = pc-1;
int offset = get4 (pc); pc += 4;
pc = base_pc+offset;
}
goto next_insn;
case op_jsr_w:
{
unsigned char* base_pc = pc-1;
int offset = get4 (pc); pc += 4;
PUSHA((jobject)pc);
pc = base_pc+offset;
}
goto next_insn;
default:
throw_internal_error ("opcode not implemented");
}
goto next_insn;
}
static void
throw_internal_error (char *msg)
{
JvThrow (new java::lang::InternalError (JvNewStringLatin1 (msg)));
}
static void
throw_incompatible_class_change_error (jstring msg)
{
JvThrow (new java::lang::IncompatibleClassChangeError (msg));
}
#if !HANDLE_SEGV
static java::lang::NullPointerException *null_pointer_exc;
static void
throw_null_pointer_exception ()
{
if (null_pointer_exc == NULL)
null_pointer_exc = new java::lang::NullPointerException;
JvThrow (null_pointer_exc);
}
#endif
#if !HANDLE_FPE
static java::lang::ArithmeticException *arithmetic_exc;
static void
throw_arithmetic_exception ()
{
if (arithmetic_exc == NULL)
arithmetic_exc = new java::lang::ArithmeticException
(JvNewStringLatin1 ("/ by zero"));
JvThrow (arithmetic_exc);
}
#endif
void
jvdump(jobject o)
{
_Jv_InterpMethod::dump_object(o);
}
/* FIXME: This is not finished! */
void
_Jv_InterpMethod::dump_object(jobject o)
{
java::io::PrintStream *out = java::lang::System::out;
if (o == NULL)
{
out->println (JvNewStringLatin1 ("<null>"));
return;
}
jclass klass = o->getClass ();
out->print (klass->getName ());
out->print (JvNewStringLatin1 ("@0x"));
out->print (java::lang::Integer::toHexString ((jint)o));
out->print (JvNewStringLatin1 ("{"));
#if 0
while (klass && klass != &ObjectClass)
{
_Jv_Field *fields = klass->fields;
int max = klass->field_count;
for (int i = 0; i < max; ++i)
{
out->print (_Jv_NewStringUTF (field->name->data));
out->print (JvNewStringLatin1 ("="));
if (JvFieldIsRef (field))
{
if (field->flags & STATIC)
out->print (JvGetSt)
}
field = field->getNextInstanceField ();
if (i+1 < max && klass->getSuperclass () != null)
out->print (JvNewStringLatin1 ("; "));
}
klass = klass->getSuperclass();
}
#endif
out->print (JvNewStringLatin1 ("}\n"));
}
#endif // INTERPRETER
...@@ -21,25 +21,30 @@ details. */ ...@@ -21,25 +21,30 @@ details. */
extern "C" void _Jv_InitClass (jclass klass); extern "C" void _Jv_InitClass (jclass klass);
extern "C" void _Jv_RegisterClasses (jclass *classes); extern "C" void _Jv_RegisterClasses (jclass *classes);
// These are the possible values for the `state' field of the class
// structure. Note that ordering is important here; in particular
// `resolved' must come between `nothing' and the other states.
// Whenever the state changes, one should notify all waiters of this
// class.
#define JV_STATE_NOTING 0 // set by compiler
#define JV_STATE_PRELOADING 1 // can do _Jv_FindClass
#define JV_STATE_LOADING 3 // has super installed
#define JV_STATE_LOADED 5 // is complete
#define JV_STATE_COMPILED 6 // this was a compiled class
#define JV_STATE_PREPARED 7 // layout & static init done
#define JV_STATE_LINKED 9 // strings interned
#define JV_STATE_IN_PROGRESS 10 // <clinit> running
#define JV_STATE_DONE 12 //
#define JV_STATE_ERROR 14 // must be last
struct _Jv_Field; struct _Jv_Field;
struct _Jv_VTable; struct _Jv_VTable;
#define CONSTANT_Class 7
#define CONSTANT_Fieldref 9
#define CONSTANT_Methodref 10
#define CONSTANT_InterfaceMethodref 11
#define CONSTANT_String 8
#define CONSTANT_Integer 3
#define CONSTANT_Float 4
#define CONSTANT_Long 5
#define CONSTANT_Double 6
#define CONSTANT_NameAndType 12
#define CONSTANT_Utf8 1
#define CONSTANT_Unicode 2
#define CONSTANT_ResolvedFlag 16
#define CONSTANT_ResolvedString (CONSTANT_String+CONSTANT_ResolvedFlag)
#define CONSTANT_ResolvedClass (CONSTANT_Class+CONSTANT_ResolvedFlag)
struct _Jv_Constants struct _Jv_Constants
{ {
jint size; jint size;
...@@ -134,9 +139,11 @@ public: ...@@ -134,9 +139,11 @@ public:
return size_in_bytes; return size_in_bytes;
} }
// finalization
void finalize ();
private: private:
void checkMemberAccess (jint flags); void checkMemberAccess (jint flags);
void resolveConstants (void);
// Various functions to handle class initialization. // Various functions to handle class initialization.
java::lang::Throwable *hackTrampoline (jint, java::lang::Throwable *); java::lang::Throwable *hackTrampoline (jint, java::lang::Throwable *);
...@@ -147,12 +154,6 @@ private: ...@@ -147,12 +154,6 @@ private:
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 void _Jv_InitClass (jclass klass); friend void _Jv_InitClass (jclass klass);
friend void _Jv_RegisterClasses (jclass *classes);
friend jclass _Jv_FindClassInCache (_Jv_Utf8Const *name,
java::lang::ClassLoader *loader);
friend jclass _Jv_FindArrayClass (jclass element);
friend jclass _Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
java::lang::ClassLoader *loader);
friend jfieldID JvGetFirstInstanceField (jclass); friend jfieldID JvGetFirstInstanceField (jclass);
friend jint JvNumInstanceFields (jclass); friend jint JvNumInstanceFields (jclass);
...@@ -165,6 +166,41 @@ private: ...@@ -165,6 +166,41 @@ private:
friend class _Jv_PrimClass; friend class _Jv_PrimClass;
// Friends classes and functions to implement the ClassLoader
friend class java::lang::ClassLoader;
friend void _Jv_WaitForState (jclass, int);
friend void _Jv_RegisterClasses (jclass *classes);
friend void _Jv_RegisterInitiatingLoader (jclass,java::lang::ClassLoader*);
friend void _Jv_UnregisterClass (jclass);
friend jclass _Jv_FindClass (_Jv_Utf8Const *name,
java::lang::ClassLoader *loader);
friend jclass _Jv_FindClassInCache (_Jv_Utf8Const *name,
java::lang::ClassLoader *loader);
friend jclass _Jv_FindArrayClass (jclass element,
java::lang::ClassLoader *loader);
friend jclass _Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
java::lang::ClassLoader *loader);
friend void _Jv_InternClassStrings (jclass);
#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);
friend void* _Jv_ResolvePoolEntry (jclass, int);
friend void _Jv_PrepareClass (jclass);
friend class _Jv_ClassReader;
friend class _Jv_InterpClass;
friend class _Jv_InterpMethod;
friend class _Jv_InterpMethodInvocation;
#endif
#ifdef JV_MARKOBJ_DECL #ifdef JV_MARKOBJ_DECL
friend JV_MARKOBJ_DECL; friend JV_MARKOBJ_DECL;
#endif #endif
......
...@@ -152,4 +152,7 @@ public final class Class implements Serializable ...@@ -152,4 +152,7 @@ public final class Class implements Serializable
// Initialize the class. // Initialize the class.
private native void initializeClass (); private native void initializeClass ();
// finalization
protected native void finalize ();
} }
...@@ -9,86 +9,394 @@ Libgcj License. Please consult the file "LIBGCJ_LICENSE" for ...@@ -9,86 +9,394 @@ Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */ details. */
package java.lang; package java.lang;
import java.io.InputStream; import java.io.InputStream;
import java.util.Hashtable; import java.net.URL;
import java.net.URLConnection;
import java.util.Stack;
/** /**
* @author Tom Tromey <tromey@cygnus.com> * The class <code>ClassLoader</code> is intended to be subclassed by
* @date October 28, 1998 * applications in order to describe new ways of loading classes,
* such as over the network.
*
* @author Kresten Krab Thorup
*/ */
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* Status: Just a stub; not useful at all. * Status: Just a stub; not useful at all.
*/ */
public abstract class ClassLoader public abstract class ClassLoader {
{
protected ClassLoader ()
{
cache = new Hashtable ();
}
protected final Class defineClass (String className, byte[] bytecode, static private ClassLoader system;
int offset, int length)
{ private static native ClassLoader getVMClassLoader0 ();
throw new ClassFormatError ("defineClass unimplemented");
}
protected final Class defineClass (byte[] bytecodes, static public ClassLoader getSystemClassLoader () {
int offset, int length) if (system == null)
{ system = getVMClassLoader0 ();
return defineClass (null, bytecodes, offset, length); return system;
} }
protected final Class findLoadedClass (String className) /**
{ * Creates a <code>ClassLoader</code>. The only thing this
return (Class) cache.get(className); * constructor does, is to call
} * <code>checkCreateClassLoader</code> on the current
* security manager.
* @exception java.lang.SecurityException if not allowed
*/
protected ClassLoader()
{
SecurityManager security = System.getSecurityManager ();
if (security != null)
security.checkCreateClassLoader ();
}
protected final Class findSystemClass (String className) /**
throws ClassNotFoundException * Loads and link the class by the given name.
{ * @param name the name of the class.
Class c = system.findLoadedClass(className); * @return the class loaded.
system.resolveClass(c); * @see ClassLoader#loadClass(String,boolean)
return c; * @exception java.lang.ClassNotFoundException
} */
public Class loadClass(String name)
throws java.lang.ClassNotFoundException, java.lang.LinkageError
{
return loadClass (name, true);
}
// FIXME: Needs URL. /**
// public URL getResource (String resName); * Loads the class by the given name.
* As per java 1.1, this has been deprecated. Use
* <code>loadClass(String)</code>
* instead.
* @param name the name of the class.
* @param link if the class should be linked.
* @return the class loaded.
* @exception java.lang.ClassNotFoundException
* @deprecated
*/
protected abstract Class loadClass(String name, boolean link)
throws java.lang.ClassNotFoundException, java.lang.LinkageError;
public InputStream getResourceAsStream (String resName) /**
{ * Defines a class, given the class-data. According to the JVM, this
return null; * method should not be used; instead use the variant of this method
} * in which the name of the class being defined is specified
* explicitly.
* <P>
* If the name of the class, as specified (implicitly) in the class
* data, denotes a class which has already been loaded by this class
* loader, an instance of
* <code>java.lang.ClassNotFoundException</code> will be thrown.
*
* @param data bytes in class file format.
* @param off offset to start interpreting data.
* @param len length of data in class file.
* @return the class defined.
* @exception java.lang.ClassNotFoundException
* @exception java.lang.LinkageError
* @see ClassLoader#defineClass(String,byte[],int,int) */
protected final Class defineClass(byte[] data, int off, int len)
throws java.lang.ClassNotFoundException, java.lang.LinkageError
{
return defineClass (null, data, off, len);
}
// FIXME: Needs URL. /**
// public static final URL getSystemResource (String resName); * Defines a class, given the class-data. This is preferable
* over <code>defineClass(byte[],off,len)</code> since it is more
* secure. If the expected name does not match that of the class
* file, <code>ClassNotFoundException</code> is thrown. If
* <code>name</code> denotes the name of an already loaded class, a
* <code>LinkageError</code> is thrown.
* <p>
*
* FIXME: How do we assure that the class-file data is not being
* modified, simultaneously with the class loader running!? If this
* was done in some very clever way, it might break security.
* Right now I am thinking that defineclass should make sure never to
* read an element of this array more than once, and that that would
* assure the ``immutable'' appearance. It is still to be determined
* if this is in fact how defineClass operates.
*
* @param name the expected name.
* @param data bytes in class file format.
* @param off offset to start interpreting data.
* @param len length of data in class file.
* @return the class defined.
* @exception java.lang.ClassNotFoundException
* @exception java.lang.LinkageError
*/
protected final synchronized Class defineClass(String name,
byte[] data,
int off,
int len)
throws java.lang.ClassNotFoundException, java.lang.LinkageError
{
if (data==null || data.length < off+len || off<0 || len<0)
throw new ClassFormatError ("arguments to defineClass "
+ "are meaningless");
public static final InputStream getSystemResourceAsStream (String resName) // as per 5.3.5.1
{ if (name != null && findLoadedClass (name) != null)
return null; throw new java.lang.LinkageError ("class "
} + name
+ " already loaded");
protected abstract Class loadClass (String className, boolean resolve) try {
throws ClassNotFoundException; // Since we're calling into native code here,
public Class loadClass (String name) throws ClassNotFoundException // we better make sure that any generated
{ // exception is to spec!
return loadClass (name, true);
} return defineClass0 (name, data, off, len);
} catch (java.lang.LinkageError x) {
throw x; // rethrow
} catch (java.lang.ClassNotFoundException x) {
throw x; // rethrow
} catch (java.lang.VirtualMachineError x) {
throw x; // rethrow
} catch (java.lang.Throwable x) {
// This should never happen, or we are beyond spec.
throw new InternalError ("Unexpected exception "
+ "while defining class "
+ name + ": "
+ x.toString ());
}
}
/** This is the entry point of defineClass into the native code */
private native Class defineClass0 (String name,
byte[] data,
int off,
int len)
throws java.lang.ClassNotFoundException, java.lang.LinkageError;
protected final void resolveClass (Class c)
{
// Nothing for now.
}
protected final void setSigners (Class cl, Object[] signers) /** This is called by defineClass0, once the "raw" and uninitialized
{ * class object has been created, and handles exceptions generated
// Nothing for now. * while actually defining the class (_Jv_DefineClass). defineClass0
* holds the lock on the new class object, so it needs to capture
* these exceptions. */
private static Throwable defineClass1 (Class klass, byte[] data,
int offset, int length)
{
try {
defineClass2 (klass, data, offset, length);
} catch (Throwable x) {
return x;
} }
return null;
}
/** This is just a wrapper for _Jv_DefineClass */
private static native void defineClass2 (Class klass, byte[] data,
int offset, int length)
throws Throwable;
/**
* Link the given class. This will bring the class to a state where
* the class initializer can be run. Linking involves the following
* steps:
* <UL>
* <LI> Prepare (allocate and internalize) the constant strings that
* are used in this class.
* <LI> Allocate storage for static fields, and define the layout
* of instance fields.
* <LI> Perform static initialization of ``static final'' int,
* long, float, double and String fields for which there is a
* compile-time constant initializer.
* <LI> Create the internal representation of the ``vtable''.
* </UL>
* For <code>gcj</code>-compiled classes, only the first step is
* performed. The compiler will have done the rest already.
* <P>
* This is called by the system automatically,
* as part of class initialization; there is no reason to ever call
* this method directly.
* <P>
* For historical reasons, this method has a name which is easily
* misunderstood. Java classes are never ``resolved''. Classes are
* linked; whereas method and field references are resolved.
* <P>
* FIXME: The JDK documentation declares this method
* <code>final</code>, we declare it <code>static</code> -- any
* objections? This allows us to call it directly from native code
* with less hassle.
*
* @param clazz the class to link.
* @exception java.lang.LinkageError
*/
protected static void resolveClass(Class clazz)
throws java.lang.LinkageError
{
synchronized (clazz)
{
try {
linkClass0 (clazz);
} catch (Throwable x) {
markClassErrorState0 (clazz);
if (x instanceof Error)
throw (Error)x;
else
throw new java.lang.InternalError
("unexpected exception during linking: " + x);
}
}
}
/** Internal method. Calls _Jv_PrepareClass and
* _Jv_InternClassStrings. This is only called from resolveClass. */
private static native void linkClass0(Class clazz)
throws java.lang.LinkageError;
/** Internal method. Marks the given clazz to be in an erroneous
* state, and calls notifyAll() on the class object. This should only
* be called when the caller has the lock on the class object. */
private static native void markClassErrorState0(Class clazz);
/**
* Returns a class found in a system-specific way, typically
* via the <code>java.class.path</code> system property.
*
* @param name the class to resolve.
* @return the class loaded.
* @exception java.lang.LinkageError
* @exception java.lang.ClassNotFoundException
*/
protected native static Class findSystemClass(String name)
throws java.lang.ClassNotFoundException, java.lang.LinkageError;
/*
* Does currently nothing.
*/
protected final void setSigners(Class claz, Object[] signers) {
/* claz.setSigners (signers); */
}
/*
* If a class named <code>name</code> was previously loaded using
* this <code>ClassLoader</code>, then it is returned. Otherwise
* it returns <code>null</code>.
* @param name class to find.
* @return the class loaded, or null.
*/
protected native Class findLoadedClass(String name);
// Class cache. public static final InputStream getSystemResourceAsStream(String name) {
private Hashtable cache; return system.getResourceAsStream (name);
}
// The system class loader. FIXME: should have an actual value public static final URL getSystemResource(String name) {
private static final ClassLoader system = null; return system.getResource (name);
}
public static final byte[] getSystemResourceAsBytes(String name) {
return system.getResourceAsBytes (name);
}
/**
* Return an InputStream representing the resource name.
* This is essentially like
* <code>getResource(name).openStream()</code>, except
* it masks out any IOException and returns null on failure.
* @param name resource to load
* @return an InputStream, or null
* @see java.lang.ClassLoader#getResource(String)
* @see java.lang.ClassLoader#getResourceAsBytes(String)
* @see java.io.InputStream
*/
public InputStream getResourceAsStream(String name)
{
try {
URL res = getResource (name);
if (res == null) return null;
return res.openStream ();
} catch (java.io.IOException x) {
return null;
}
}
/**
* Return a byte array <code>byte[]</code> representing the
* resouce <code>name</code>. This only works for resources
* that have a known <code>content-length</code>, and
* it will block while loading the resource. Returns null
* for error conditions.<p>
* Since it is synchroneous, this is only convenient for
* resources that are "readily" available. System resources
* can conveniently be loaded this way, and the runtime
* system uses this to load class files. <p>
* To find the class data for a given class, use
* something like the following:
* <ul><code>
* String res = clazz.getName().replace ('.', '/')) + ".class";<br>
* byte[] data = getResourceAsBytes (res);
* </code></ul>
* @param name resource to load
* @return a byte array, or null
* @see java.lang.ClassLoader#getResource(String)
* @see java.lang.ClassLoader#getResourceAsStream(String)
*/
public byte[] getResourceAsBytes(String name) {
try {
URL res = getResource (name);
if (res == null) return null;
URLConnection conn = res.openConnection ();
int len = conn.getContentLength ();
if (len == -1) return null;
return readbytes (conn.getInputStream (), len);
} catch (java.io.IOException x) {
return null;
}
}
/**
* Return an java.io.URL representing the resouce <code>name</code>.
* @param name resource to load
* @return a URL, or null if there is no such resource.
* @see java.lang.ClassLoader#getResourceAsBytes(String)
* @see java.lang.ClassLoader#getResourceAsStream(String)
* @see java.io.URL
*/
public URL getResource(String name) {
return null;
}
/**
* Utility routine to read a resource fully, even if the given
* InputStream only provides partial results.
*/
private static byte[] readbytes (InputStream is, int length)
{
try {
byte[] data = new byte[length];
int read;
int off = 0;
while (off != length)
{
read = is.read (data, off, (int) (length-off));
if (read == -1)
return null;
off += read;
}
return data;
} catch (java.io.IOException x) {
return null;
}
}
} }
...@@ -19,12 +19,30 @@ package java.lang; ...@@ -19,12 +19,30 @@ package java.lang;
final class FirstThread extends Thread final class FirstThread extends Thread
{ {
public native void run (); public native void run0 ();
public void run ()
{
try {
run0 ();
} catch (Throwable ex) {
System.err.println ("uncaught exception at top level");
ex.printStackTrace ();
}
}
public FirstThread (ThreadGroup g, Class k, Object o) public FirstThread (ThreadGroup g, Class k, Object o)
{ {
super (g, null, "main"); super (g, null, "main");
klass = k; klass = k;
klass_name = null;
args = o;
}
public FirstThread (ThreadGroup g, String class_name, Object o)
{
super (g, null, "main");
klass = null;
klass_name = class_name;
args = o; args = o;
} }
...@@ -36,5 +54,6 @@ final class FirstThread extends Thread ...@@ -36,5 +54,6 @@ final class FirstThread extends Thread
// Private data. // Private data.
private Class klass; private Class klass;
private String klass_name;
private Object args; private Object args;
} }
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
package java.lang;
import java.io.*;
import java.net.URL;
import gnu.gcj.util.path.SearchPath;
final class VMClassLoader extends java.lang.ClassLoader
{
private SearchPath path;
private final String path_seperator;
private final String file_seperator;
private final char file_seperator_char;
private VMClassLoader () {
path_seperator = System.getProperty ("path.separator", ":");
file_seperator = System.getProperty ("file.separator", "/");
file_seperator_char = file_seperator.charAt (0);
String class_path = System.getProperty ("java.class.path", ".");
path = new SearchPath (class_path);
}
protected Class loadClass(String name,
boolean resolve)
throws java.lang.ClassNotFoundException, java.lang.LinkageError
{
return loadClassInternal (name, resolve, false);
}
/** I'm a little in doubt here, if this method is
actually supposed to throw a LinkageError, or not.
The spec, 20.14.3, is a little unclear. It says:
`` The general contract of loadClass is that, given the name
of a class, it either returns the Class object for the class
or throws a ClassNotFoundException.''
However, by making LinkageError a checked exception,
i.e., mention it directly in the throws clause,
we'll force caller to consider that case as well.
**/
protected Class loadClassInternal(String name,
boolean resolve,
boolean fromBootLoader)
throws java.lang.ClassNotFoundException, java.lang.LinkageError
{
Class clazz;
/** TODO: call _Jv_VerifyClassName **/
if ( (name.indexOf ('/') != -1)
|| (name.charAt (0) == '.')
|| (name.indexOf (file_seperator) != -1)
|| (name.indexOf ("..") != -1))
{
throw new IllegalArgumentException (name);
}
// already loaded?
clazz = findLoadedClass (name);
// we need access to the boot class loader here
if (clazz == null && !fromBootLoader)
clazz = findBootClass (name);
if (clazz == null)
{
StringBuffer res = new StringBuffer ();
// here we do actually replace .'s with /'s because
// we're going to find something in the file system.
res.append (name.replace ('.', file_seperator_char));
res.append (".class");
byte[] data = getResourceAsBytes (res.toString ());
if (data == null)
throw new ClassNotFoundException (name);
clazz = defineClass (name, data, 0, data.length);
}
if (resolve && clazz != null)
resolveClass (clazz);
return clazz;
}
private native Class findBootClass (String name);
public InputStream getResourceAsStream(String name)
{
return path.getStream (name);
}
public URL getResource(String name)
{
return path.getURL (name);
}
public byte[] getResourceAsBytes(String name)
{
return path.getBytes (name);
}
}
...@@ -20,6 +20,11 @@ package java.lang; ...@@ -20,6 +20,11 @@ package java.lang;
* Status: Believed complete and correct. * Status: Believed complete and correct.
*/ */
/* FIXME: We should consider adding some special error message when this
* exception is thrown, or maybe if it being caught at top-level. Such
* a message would direct the user to send a bug report to
* gcj-bugs@cygnus.com, or something like that. --KKT */
public abstract class VirtualMachineError extends Error public abstract class VirtualMachineError extends Error
{ {
public VirtualMachineError () public VirtualMachineError ()
......
...@@ -39,6 +39,8 @@ details. */ ...@@ -39,6 +39,8 @@ details. */
#include <java/lang/System.h> #include <java/lang/System.h>
#include <java/lang/SecurityManager.h> #include <java/lang/SecurityManager.h>
#include <java-cpool.h>
#define CloneableClass _CL_Q34java4lang9Cloneable #define CloneableClass _CL_Q34java4lang9Cloneable
...@@ -59,28 +61,6 @@ static _Jv_Utf8Const *void_signature = _Jv_makeUtf8Const ("()V", 3); ...@@ -59,28 +61,6 @@ static _Jv_Utf8Const *void_signature = _Jv_makeUtf8Const ("()V", 3);
static _Jv_Utf8Const *clinit_name = _Jv_makeUtf8Const ("<clinit>", 8); static _Jv_Utf8Const *clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6); static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
// These are the possible values for the `state' field. They more or
// less follow the section numbers in the Java Language Spec. Right
// now we don't bother to represent other interesting states, e.g. the
// states a class might inhabit before it is prepared. Note that
// ordering is important here; in particular `resolved' must come
// between `nothing' and the other states.
#define STATE_NOTHING 0
#define STATE_RESOLVED 1
#define STATE_IN_PROGRESS 6
#define STATE_DONE 9
#define STATE_ERROR 10
// Size of local hash table.
#define HASH_LEN 256
// Hash function for Utf8Consts.
#define HASH_UTF(Utf) (((Utf)->hash) % HASH_LEN)
// This is the table we use to keep track of loaded classes. See Spec
// section 12.2.
static jclass loaded_classes[HASH_LEN];
jclass jclass
...@@ -111,6 +91,9 @@ java::lang::Class::forName (jstring className) ...@@ -111,6 +91,9 @@ java::lang::Class::forName (jstring className)
#endif #endif
if (! klass) if (! klass)
JvThrow (new java::lang::ClassNotFoundException (className)); JvThrow (new java::lang::ClassNotFoundException (className));
_Jv_InitClass (klass);
return klass; return klass;
} }
...@@ -380,33 +363,13 @@ java::lang::Class::newInstance (void) ...@@ -380,33 +363,13 @@ java::lang::Class::newInstance (void)
return r; return r;
} }
// Initialize the constants.
void void
java::lang::Class::resolveConstants (void) java::lang::Class::finalize (void)
{ {
for (int i = 0; i < constants.size; ++i) #ifdef INTERPRETER
{ JvAssert (_Jv_IsInterpretedClass (this));
if (constants.tags[i] == CONSTANT_String) _Jv_UnregisterClass (this);
{ #endif
jstring str;
str = _Jv_NewStringUtf8Const ((_Jv_Utf8Const *) constants.data[i]);
constants.data[i] = (void *) str;
constants.tags[i] = CONSTANT_ResolvedString;
}
else if (constants.tags[i] == CONSTANT_Class)
{
_Jv_Utf8Const *name = (_Jv_Utf8Const *) constants.data[i];
jclass klass = _Jv_FindClassFromSignature (name->data, loader);
if (! klass)
{
jstring str = _Jv_NewStringUtf8Const (name);
JvThrow (new java::lang::ClassNotFoundException (str));
}
constants.data[i] = (void *) klass;
constants.tags[i] = CONSTANT_ResolvedClass;
}
}
} }
// FIXME. // FIXME.
...@@ -424,38 +387,52 @@ void ...@@ -424,38 +387,52 @@ void
java::lang::Class::initializeClass (void) java::lang::Class::initializeClass (void)
{ {
// Short-circuit to avoid needless locking. // Short-circuit to avoid needless locking.
if (state == STATE_DONE) if (state == JV_STATE_DONE)
return; return;
// Step 1. // do this before we enter the monitor below, since this can cause
_Jv_MonitorEnter (this); // exceptions. Here we assume, that reading "state" is an atomic
// operation, I pressume that is true? --Kresten
if (state < JV_STATE_LINKED)
{
#ifdef INTERPRETER
if (_Jv_IsInterpretedClass (this))
{
java::lang::ClassLoader::resolveClass (this);
// FIXME: This should actually be handled by calling into the class // Step 1.
// loader. For now we put it here. _Jv_MonitorEnter (this);
if (state < STATE_RESOLVED) }
else
#endif
{
// Step 1.
_Jv_MonitorEnter (this);
_Jv_InternClassStrings (this);
}
}
else
{ {
// We set the state before calling resolveConstants to avoid // Step 1.
// infinite recursion when processing String or Class. _Jv_MonitorEnter (this);
state = STATE_RESOLVED;
resolveConstants ();
} }
// Step 2. // Step 2.
java::lang::Thread *self = java::lang::Thread::currentThread(); java::lang::Thread *self = java::lang::Thread::currentThread();
// FIXME: `self' can be null at startup. Hence this nasty trick. // FIXME: `self' can be null at startup. Hence this nasty trick.
self = (java::lang::Thread *) ((long) self | 1); self = (java::lang::Thread *) ((long) self | 1);
while (state == STATE_IN_PROGRESS && thread && thread != self) while (state == JV_STATE_IN_PROGRESS && thread && thread != self)
wait (); wait ();
// Steps 3 & 4. // Steps 3 & 4.
if (state == STATE_DONE || state == STATE_IN_PROGRESS || thread == self) if (state == JV_STATE_DONE || state == JV_STATE_IN_PROGRESS || thread == self)
{ {
_Jv_MonitorExit (this); _Jv_MonitorExit (this);
return; return;
} }
// Step 5. // Step 5.
if (state == STATE_ERROR) if (state == JV_STATE_ERROR)
{ {
_Jv_MonitorExit (this); _Jv_MonitorExit (this);
JvThrow (new java::lang::NoClassDefFoundError); JvThrow (new java::lang::NoClassDefFoundError);
...@@ -463,7 +440,7 @@ java::lang::Class::initializeClass (void) ...@@ -463,7 +440,7 @@ java::lang::Class::initializeClass (void)
// Step 6. // Step 6.
thread = self; thread = self;
state = STATE_IN_PROGRESS; state = JV_STATE_IN_PROGRESS;
_Jv_MonitorExit (this); _Jv_MonitorExit (this);
// Step 7. // Step 7.
...@@ -477,7 +454,7 @@ java::lang::Class::initializeClass (void) ...@@ -477,7 +454,7 @@ java::lang::Class::initializeClass (void)
{ {
// Caught an exception. // Caught an exception.
_Jv_MonitorEnter (this); _Jv_MonitorEnter (this);
state = STATE_ERROR; state = JV_STATE_ERROR;
notify (); notify ();
_Jv_MonitorExit (this); _Jv_MonitorExit (this);
JvThrow (except); JvThrow (except);
...@@ -492,7 +469,7 @@ java::lang::Class::initializeClass (void) ...@@ -492,7 +469,7 @@ java::lang::Class::initializeClass (void)
if (! except) if (! except)
{ {
_Jv_MonitorEnter (this); _Jv_MonitorEnter (this);
state = STATE_DONE; state = JV_STATE_DONE;
} }
else else
{ {
...@@ -503,7 +480,7 @@ java::lang::Class::initializeClass (void) ...@@ -503,7 +480,7 @@ java::lang::Class::initializeClass (void)
except = hackTrampoline(2, except); except = hackTrampoline(2, except);
} }
_Jv_MonitorEnter (this); _Jv_MonitorEnter (this);
state = STATE_ERROR; state = JV_STATE_ERROR;
} }
notify (); notify ();
_Jv_MonitorExit (this); _Jv_MonitorExit (this);
...@@ -530,6 +507,64 @@ _Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name, ...@@ -530,6 +507,64 @@ _Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
return NULL; return NULL;
} }
#define MCACHE_SIZE 1013
struct _Jv_mcache {
jclass klass;
_Jv_Method *method;
};
static _Jv_mcache method_cache[MCACHE_SIZE];
static int method_cache_count;
static void*
_Jv_FindMethodInCache (jclass klass,
_Jv_Utf8Const *name,
_Jv_Utf8Const *signature)
{
for (int index = name->hash % MCACHE_SIZE;
method_cache[index].klass != NULL;
index = (index+1) % MCACHE_SIZE)
{
_Jv_mcache *mc = (method_cache+index);
_Jv_Method *m = mc->method;
if (mc->klass == klass
&& m != NULL // thread safe check
&& _Jv_equalUtf8Consts (m->name, name)
&& _Jv_equalUtf8Consts (m->signature, signature))
{
return mc->method->ncode;
}
}
return NULL;
}
static void
_Jv_AddMethodToCache (jclass klass,
_Jv_Method *method)
{
_Jv_MonitorEnter (&ClassClass);
if (method_cache_count > MCACHE_SIZE*2/3)
{
for (int i = 0; i < MCACHE_SIZE; i++)
method_cache[i].klass = 0;
}
for (int index = method->name->hash % MCACHE_SIZE;
method_cache[index].klass != NULL;
index = (index+1) % MCACHE_SIZE)
{
method_cache[index].method = method;
method_cache[index].klass = klass;
}
method_cache_count += 1;
_Jv_MonitorExit (&ClassClass);
}
void * void *
_Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name, _Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
_Jv_Utf8Const *signature) _Jv_Utf8Const *signature)
...@@ -539,6 +574,14 @@ _Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name, ...@@ -539,6 +574,14 @@ _Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
// call a method of a class until the class is linked. But this // call a method of a class until the class is linked. But this
// captures the general idea. // captures the general idea.
// klass->getClassLoader()->resolveClass(klass); // 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;
for (; klass; klass = klass->getSuperclass()) for (; klass; klass = klass->getSuperclass())
{ {
...@@ -553,6 +596,8 @@ _Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name, ...@@ -553,6 +596,8 @@ _Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
if (! java::lang::reflect::Modifier::isPublic(meth->accflags)) if (! java::lang::reflect::Modifier::isPublic(meth->accflags))
JvThrow (new java::lang::IllegalAccessError); JvThrow (new java::lang::IllegalAccessError);
_Jv_AddMethodToCache (klass, meth);
return meth->ncode; return meth->ncode;
} }
JvThrow (new java::lang::IncompatibleClassChangeError); JvThrow (new java::lang::IncompatibleClassChangeError);
...@@ -565,219 +610,6 @@ _Jv_InitClass (jclass klass) ...@@ -565,219 +610,6 @@ _Jv_InitClass (jclass klass)
klass->initializeClass(); klass->initializeClass();
} }
// This function is called many times during startup, before main() is
// run. We do our runtime initialization here the very first time we
// are called. At that point in time we know for certain we are
// running single-threaded, so we don't need to lock when modifying
// `init'. CLASSES is NULL-terminated.
void
_Jv_RegisterClasses (jclass *classes)
{
static bool init = false;
if (! init)
{
init = true;
_Jv_InitThreads ();
_Jv_InitGC ();
_Jv_InitializeSyncMutex ();
}
JvSynchronize sync (&ClassClass);
for (; *classes; ++classes)
{
jclass klass = *classes;
jint hash = HASH_UTF (klass->name);
klass->next = loaded_classes[hash];
loaded_classes[hash] = klass;
}
}
void
_Jv_RegisterClass (jclass klass)
{
jclass classes[2];
classes[0] = klass;
classes[1] = NULL;
_Jv_RegisterClasses (classes);
}
jclass
_Jv_FindClassInCache (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
{
JvSynchronize sync (&ClassClass);
jint hash = HASH_UTF (name);
jclass klass;
for (klass = loaded_classes[hash]; klass; klass = klass->next)
{
if (loader == klass->loader && _Jv_equalUtf8Consts (name, klass->name))
break;
}
return klass;
}
#if 0
jclass
_Jv_FindClassInCache (jstring name, java::lang::ClassLoader *loader)
{
JvSynchronize sync (&ClassClass);
jint hash = name->hashCode();
jclass klass = loaded_classes[(_Jv_ushort) hash % HASH_LEN];
for ( ; klass; klass = klass->next)
{
if (loader == klass->loader
&& _Jv_equalUtf8Consts (klass->name, name, hash))
break;
}
return klass;
}
#endif
jclass
_Jv_FindClass (_Jv_Utf8Const* name, java::lang::ClassLoader *loader)
{
jclass klass = _Jv_FindClassInCache (name, loader);
if (loader && ! klass)
{
klass = loader->loadClass(_Jv_NewStringUtf8Const (name));
if (klass)
_Jv_RegisterClass (klass);
}
return klass;
}
#if 0
jclass
_Jv_FindClass (jstring name, java::lang::ClassLoader *loader)
{
jclass klass = _Jv_FindClassInCache (name, loader);
if (loader && ! klass)
{
klass = loader->loadClass(name);
if (klass)
_Jv_RegisterClass (klass);
}
return klass;
}
#endif
jclass
_Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
java::lang::ClassLoader *loader)
{
jclass ret = (jclass) JvAllocObject (&ClassClass);
ret->next = NULL;
ret->name = name;
ret->accflags = 0;
ret->superclass = superclass;
ret->constants.size = 0;
ret->constants.tags = NULL;
ret->constants.data = NULL;
ret->methods = NULL;
ret->method_count = 0;
ret->vtable_method_count = 0;
ret->fields = NULL;
ret->size_in_bytes = 0;
ret->field_count = 0;
ret->static_field_count = 0;
ret->vtable = NULL;
ret->interfaces = NULL;
ret->loader = loader;
ret->interface_count = 0;
ret->state = 0;
ret->thread = NULL;
_Jv_RegisterClass (ret);
return ret;
}
jclass
_Jv_FindArrayClass (jclass element)
{
_Jv_Utf8Const *array_name;
int len;
if (element->isPrimitive())
{
// For primitive types the array is cached in the class.
jclass ret = (jclass) element->methods;
if (ret)
return ret;
len = 3;
}
else
len = element->name->length + 5;
{
char signature[len];
int index = 0;
signature[index++] = '[';
// Compute name of array class to see if we've already cached it.
if (element->isPrimitive())
{
signature[index++] = (char) element->method_count;
}
else
{
size_t length = element->name->length;
const char *const name = element->name->data;
if (name[0] != '[')
signature[index++] = 'L';
memcpy (&signature[index], name, length);
index += length;
if (name[0] != '[')
signature[index++] = ';';
}
array_name = _Jv_makeUtf8Const (signature, index);
}
jclass array_class = _Jv_FindClassInCache (array_name, element->loader);
if (! array_class)
{
// Create new array class.
array_class = _Jv_NewClass (array_name, &ObjectClass, element->loader);
// Note that `vtable_method_count' doesn't include the initial
// NULL slot.
int dm_count = ObjectClass.vtable_method_count + 1;
// Create a new vtable by copying Object's vtable (except the
// class pointer, of course). Note that we allocate this as
// unscanned memory -- the vtables are handled specially by the
// GC.
int size = (sizeof (_Jv_VTable) +
((dm_count - 1) * sizeof (void *)));
_Jv_VTable *vtable = (_Jv_VTable *) _Jv_AllocBytes (size);
vtable->clas = array_class;
memcpy (vtable->method, ObjectClass.vtable->method,
dm_count * sizeof (void *));
array_class->vtable = vtable;
array_class->vtable_method_count = ObjectClass.vtable_method_count;
// Stash the pointer to the element type.
array_class->methods = (_Jv_Method *) element;
// Register our interfaces.
// FIXME: for JDK 1.2 we need Serializable.
static jclass interfaces[] = { &CloneableClass };
array_class->interfaces = interfaces;
array_class->interface_count = 1;
// FIXME: initialize other Class instance variables,
// e.g. `fields'.
array_class->state = STATE_DONE;
}
// For primitive types, point back at this array.
if (element->isPrimitive())
element->methods = (_Jv_Method *) array_class;
return array_class;
}
jboolean jboolean
_Jv_IsInstanceOf(jobject obj, jclass cl) _Jv_IsInstanceOf(jobject obj, jclass cl)
{ {
......
// natClassLoader.cc - Implementation of java.lang.ClassLoader native methods.
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <cni.h>
#include <jvm.h>
#include <java/lang/Character.h>
#include <java/lang/Thread.h>
#include <java/lang/ClassLoader.h>
#include <java/lang/VMClassLoader.h>
#include <java/lang/InternalError.h>
#include <java/lang/LinkageError.h>
#include <java/lang/ClassFormatError.h>
#include <java/lang/NoClassDefFoundError.h>
#include <java/lang/ClassNotFoundException.h>
#include <java/lang/ClassCircularityError.h>
#include <java/lang/IncompatibleClassChangeError.h>
#include <java/lang/reflect/Modifier.h>
#include <java-interp.h>
#define CloneableClass _CL_Q34java4lang9Cloneable
extern java::lang::Class CloneableClass;
#define ObjectClass _CL_Q34java4lang6Object
extern java::lang::Class ObjectClass;
#define ClassClass _CL_Q34java4lang5Class
extern java::lang::Class ClassClass;
#define VMClassLoaderClass _CL_Q34java4lang17VMClassLoader
extern java::lang::Class VMClassLoader;
#define ClassLoaderClass _CL_Q34java4lang11ClassLoader
extern java::lang::Class ClassLoaderClass;
/////////// java.lang.ClassLoader native methods ////////////
#ifdef INTERPRETER
java::lang::VMClassLoader *redirect = 0;
#endif
java::lang::ClassLoader*
java::lang::ClassLoader::getVMClassLoader0 ()
{
#ifdef INTERPRETER
if (redirect == 0)
redirect = new java::lang::VMClassLoader;
return redirect;
#else
return 0;
#endif
}
void
java::lang::ClassLoader::defineClass2 (jclass klass, jbyteArray data,
jint offset, jint length)
{
#ifdef INTERPRETER
_Jv_DefineClass (klass, data, offset, length);
#endif
}
java::lang::Class *
java::lang::ClassLoader::defineClass0 (jstring name,
jbyteArray data,
jint offset,
jint length)
{
#ifdef INTERPRETER
jclass klass;
klass = (jclass) JvAllocObject (&ClassClass, sizeof (_Jv_InterpClass));
// synchronize on the class, so that it is not
// attempted initialized until we're done loading.
_Jv_MonitorEnter (klass);
// record which is the defining loader
klass->loader = this;
// register that we are the initiating loader...
if (name != 0)
{
_Jv_Utf8Const * name2 = _Jv_makeUtf8Const (name);
_Jv_VerifyClassName (name2);
klass->name = name2;
}
// this will do the magic. loadInto also operates
// as an exception trampoline for now...
Throwable *ex = defineClass1 (klass, data, offset, length);
if (ex) // we failed to load it
{
klass->state = JV_STATE_ERROR;
klass->notifyAll ();
_Jv_UnregisterClass (klass);
_Jv_MonitorExit (klass);
// FIXME: Here we may want to test that EX does
// indeed represent a valid exception. That is,
// anything but ClassNotFoundException,
// or some kind of Error.
JvThrow (ex);
}
// if everything proceeded sucessfully, we're loaded.
JvAssert (klass->state == JV_STATE_LOADED);
// if an exception is generated, this is initially missed.
// however, we come back here in handleException0 below...
_Jv_MonitorExit (klass);
return klass;
#else // INTERPRETER
return 0;
#endif
}
void
_Jv_WaitForState (jclass klass, int state)
{
if (klass->state >= state)
return;
_Jv_MonitorEnter (klass) ;
if (state == JV_STATE_LINKED)
{
_Jv_MonitorExit (klass);
_Jv_InternClassStrings (klass);
return;
}
java::lang::Thread *self = java::lang::Thread::currentThread();
// this is similar to the strategy for class initialization.
// if we already hold the lock, just leave.
while (klass->state <= state
&& klass->thread
&& klass->thread != self)
klass->wait ();
_Jv_MonitorExit (klass);
if (klass->state == JV_STATE_ERROR)
{
_Jv_Throw (new java::lang::LinkageError ());
}
}
// Finish linking a class. Only called from ClassLoader::resolveClass.
void
java::lang::ClassLoader::linkClass0 (java::lang::Class *klass)
{
if (klass->state >= JV_STATE_LINKED)
return;
#ifdef INTERPRETER
if (_Jv_IsInterpretedClass (klass))
{
_Jv_PrepareClass (klass);
}
#endif
_Jv_InternClassStrings (klass);
}
void
java::lang::ClassLoader::markClassErrorState0 (java::lang::Class *klass)
{
klass->state = JV_STATE_ERROR;
klass->notifyAll ();
}
/** this is the only native method in VMClassLoader, so
we define it here. */
jclass
java::lang::VMClassLoader::findBootClass (jstring name)
{
return _Jv_FindClassInCache (_Jv_makeUtf8Const (name), 0);
}
jclass
java::lang::ClassLoader::findLoadedClass (jstring name)
{
return _Jv_FindClassInCache (_Jv_makeUtf8Const (name), this);
}
jclass
java::lang::ClassLoader::findSystemClass (jstring name)
{
return _Jv_FindClass (_Jv_makeUtf8Const (name), 0);
}
/* This is the final step of linking, internalizing the constant strings
* of a class. This is called for both compiled and interpreted
* classes, and it is *only* called from ClassLoader::linkClass0,
* which is always in a context where the current thread has a lock on
* the class in question. We define it here, and not in resolve.cc, so that
* the entire resolve.cc can be #ifdef'ed away when not using the
* interpreter. */
void
_Jv_InternClassStrings(jclass klass)
{
if (klass->state >= JV_STATE_LINKED)
return;
// short-circuit, so that mutually dependent classes are ok
klass->state = JV_STATE_LINKED;
_Jv_Constants *pool = &klass->constants;
for (int i = 1; i < pool->size; ++i)
{
if (pool->tags[i] == JV_CONSTANT_String)
{
jstring str;
str = _Jv_NewStringUtf8Const ((_Jv_Utf8Const *) pool->data[i]);
pool->data[i] = (void *) str;
pool->tags[i] |= JV_CONSTANT_ResolvedFlag;
}
}
klass->notifyAll ();
}
//
// A single class can have many "initiating" class loaders,
// and a single "defining" class loader. The Defining
// class loader is what is returned from Class.getClassLoader()
// and is used when loading dependent classes during resolution.
// The set of initiating class loaders are used to ensure
// safety of linking, and is maintained in the hash table
// "initiated_classes". A defining classloader is by definition also
// initiating, so we only store classes in this table, if they have more
// than one class loader associated.
//
// Size of local hash table.
#define HASH_LEN 1013
// Hash function for Utf8Consts.
#define HASH_UTF(Utf) (((Utf)->hash) % HASH_LEN)
struct _Jv_LoaderInfo {
_Jv_LoaderInfo *next;
java::lang::Class *klass;
java::lang::ClassLoader *loader;
};
_Jv_LoaderInfo *initiated_classes[HASH_LEN];
jclass loaded_classes[HASH_LEN];
jclass
_Jv_FindClassInCache (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
{
_Jv_MonitorEnter (&ClassClass);
jint hash = HASH_UTF (name);
// first, if LOADER is a defining loader, then it is also initiating
jclass klass;
for (klass = loaded_classes[hash]; klass; klass = klass->next)
{
if (loader == klass->loader && _Jv_equalUtf8Consts (name, klass->name))
break;
}
// otherwise, it may be that the class in question was defined
// by some other loader, but that the loading was initiated by
// the loader in question.
if (!klass)
{
_Jv_LoaderInfo *info;
for (info = initiated_classes[hash]; info; info = info->next)
{
if (loader == info->loader
&& _Jv_equalUtf8Consts (name, info->klass->name))
{
klass = info->klass;
break;
}
}
}
_Jv_MonitorExit (&ClassClass);
return klass;
}
void
_Jv_UnregisterClass (jclass the_class)
{
_Jv_MonitorEnter (&ClassClass);
jint hash = HASH_UTF(the_class->name);
jclass *klass = &(loaded_classes[hash]);
for ( ; *klass; klass = &((*klass)->next))
{
if (*klass == the_class)
{
*klass = (*klass)->next;
break;
}
}
_Jv_LoaderInfo **info = &(initiated_classes[hash]);
for ( ; *info; info = &((*info)->next))
{
while ((*info)->klass == the_class)
{
*info = (*info)->next;
}
}
_Jv_MonitorExit (&ClassClass);
}
void
_Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
{
_Jv_LoaderInfo *info = new _Jv_LoaderInfo; // non-gc alloc!
jint hash = HASH_UTF(klass->name);
_Jv_MonitorEnter (&ClassClass);
info->loader = loader;
info->klass = klass;
info->next = initiated_classes[hash];
initiated_classes[hash] = info;
_Jv_MonitorExit (&ClassClass);
}
// This function is called many times during startup, before main() is
// run. We do our runtime initialization here the very first time we
// are called. At that point in time we know for certain we are
// running single-threaded, so we don't need to lock when modifying
// `init'. CLASSES is NULL-terminated.
void
_Jv_RegisterClasses (jclass *classes)
{
static bool init = false;
if (! init)
{
init = true;
_Jv_InitThreads ();
_Jv_InitGC ();
_Jv_InitializeSyncMutex ();
}
JvSynchronize sync (&ClassClass);
for (; *classes; ++classes)
{
jclass klass = *classes;
jint hash = HASH_UTF (klass->name);
klass->next = loaded_classes[hash];
loaded_classes[hash] = klass;
// registering a compiled class causes
// it to be immediately "prepared".
if (klass->state == JV_STATE_NOTING)
klass->state = JV_STATE_COMPILED;
}
}
void
_Jv_RegisterClass (jclass klass)
{
jclass classes[2];
classes[0] = klass;
classes[1] = NULL;
_Jv_RegisterClasses (classes);
}
#if 0
// NOTE: this one is out of date with the new loader stuff...
jclass
_Jv_FindClassInCache (jstring name, java::lang::ClassLoader *loader)
{
JvSynchronize sync (&ClassClass);
jint hash = name->hashCode();
jclass klass = loaded_classes[(_Jv_ushort) hash % HASH_LEN];
for ( ; klass; klass = klass->next)
{
if (loader == klass->loader
&& _Jv_equal (klass->name, name, hash))
break;
}
_Jv_MonitorExit (&ClassClass);
return klass;
}
#endif
jclass _Jv_FindClass (_Jv_Utf8Const *name,
java::lang::ClassLoader *loader)
{
jclass klass = _Jv_FindClassInCache (name, loader);
#ifdef INTERPRETER
if (! klass)
{
jstring sname = _Jv_NewStringUTF (name->data);
if (loader)
{
// Load using a user-defined loader, jvmspec 5.3.2
klass = loader->loadClass(sname, false);
// if "loader" delegateted the loadClass operation
// to another loader, register explicitly
// that he is also an initiating loader of the
// given class.
if (klass && (klass->getClassLoader () != loader))
_Jv_RegisterInitiatingLoader (klass, 0);
}
else
{
if (redirect == NULL)
{
_Jv_InitClass (&ClassLoaderClass);
java::lang::ClassLoader::getSystemClassLoader ();
}
// Load using the bootstrap loader jmspec 5.3.1
klass = redirect -> loadClassInternal (sname, false, true);
// register that we're an initiating loader
if (klass)
{
_Jv_RegisterInitiatingLoader (klass, 0);
}
}
}
else
{
// we need classes to be in the hash while
// we're loading, so that they can refer to themselves.
_Jv_WaitForState (klass, JV_STATE_LOADED);
}
#endif
return klass;
}
#if 0
// NOTE: this one is out of date with the new class loader stuff...
jclass
_Jv_FindClass (jstring name, java::lang::ClassLoader *loader)
{
jclass klass = _Jv_FindClassInCache (name, loader);
if (! klass)
{
if (loader)
{
klass = loader->loadClass(name);
}
else
{
// jmspec 5.3.1.2
// delegate to the system loader
klass = java::lang::ClassLoader::system.loadClass (sname);
// register that we're an initiating loader
if (klass)
_Jv_RegisterInitiatingLoader (klass, 0);
}
}
else
{
_Jv_WaitForState (klass, JV_STATE_LOADED);
}
return klass;
}
#endif
jclass
_Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
java::lang::ClassLoader *loader)
{
jclass ret = (jclass) JvAllocObject (&ClassClass);
ret->next = NULL;
ret->name = name;
ret->accflags = 0;
ret->superclass = superclass;
ret->constants.size = 0;
ret->constants.tags = NULL;
ret->constants.data = NULL;
ret->methods = NULL;
ret->method_count = 0;
ret->vtable_method_count = 0;
ret->fields = NULL;
ret->size_in_bytes = 0;
ret->field_count = 0;
ret->static_field_count = 0;
ret->vtable = NULL;
ret->interfaces = NULL;
ret->loader = loader;
ret->interface_count = 0;
ret->state = 0;
ret->thread = NULL;
_Jv_RegisterClass (ret);
return ret;
}
jclass
_Jv_FindArrayClass (jclass element, java::lang::ClassLoader *loader)
{
_Jv_Utf8Const *array_name;
int len;
if (element->isPrimitive())
{
// For primitive types the array is cached in the class.
jclass ret = (jclass) element->methods;
if (ret)
return ret;
len = 3;
}
else
len = element->name->length + 5;
{
char signature[len];
int index = 0;
signature[index++] = '[';
// Compute name of array class to see if we've already cached it.
if (element->isPrimitive())
{
signature[index++] = (char) element->method_count;
}
else
{
size_t length = element->name->length;
const char *const name = element->name->data;
if (name[0] != '[')
signature[index++] = 'L';
memcpy (&signature[index], name, length);
index += length;
if (name[0] != '[')
signature[index++] = ';';
}
array_name = _Jv_makeUtf8Const (signature, index);
}
jclass array_class = _Jv_FindClassInCache (array_name, element->loader);
if (! array_class)
{
// Create new array class.
array_class = _Jv_NewClass (array_name, &ObjectClass, element->loader);
// Note that `vtable_method_count' doesn't include the initial
// NULL slot.
int dm_count = ObjectClass.vtable_method_count + 1;
// Create a new vtable by copying Object's vtable (except the
// class pointer, of course). Note that we allocate this as
// unscanned memory -- the vtables are handled specially by the
// GC.
int size = (sizeof (_Jv_VTable) +
((dm_count - 1) * sizeof (void *)));
_Jv_VTable *vtable = (_Jv_VTable *) _Jv_AllocBytes (size);
vtable->clas = array_class;
memcpy (vtable->method, ObjectClass.vtable->method,
dm_count * sizeof (void *));
array_class->vtable = vtable;
array_class->vtable_method_count = ObjectClass.vtable_method_count;
// Stash the pointer to the element type.
array_class->methods = (_Jv_Method *) element;
// Register our interfaces.
// FIXME: for JDK 1.2 we need Serializable.
static jclass interfaces[] = { &CloneableClass };
array_class->interfaces = interfaces;
array_class->interface_count = 1;
// as per vmspec 5.3.3.2
array_class->accflags = element->accflags;
// FIXME: initialize other Class instance variables,
// e.g. `fields'.
// say this class is initialized and ready to go!
array_class->state = JV_STATE_DONE;
// vmspec, section 5.3.3 describes this
if (element->loader != loader)
_Jv_RegisterInitiatingLoader (array_class, loader);
}
// For primitive types, point back at this array.
if (element->isPrimitive())
element->methods = (_Jv_Method *) array_class;
return array_class;
}
...@@ -27,7 +27,7 @@ details. */ ...@@ -27,7 +27,7 @@ details. */
typedef void main_func (jobject); typedef void main_func (jobject);
void void
java::lang::FirstThread::run (void) java::lang::FirstThread::run0 (void)
{ {
Utf8Const* main_signature = _Jv_makeUtf8Const ("([Ljava.lang.String;)V", 22); Utf8Const* main_signature = _Jv_makeUtf8Const ("([Ljava.lang.String;)V", 22);
Utf8Const* main_name = _Jv_makeUtf8Const ("main", 4); Utf8Const* main_name = _Jv_makeUtf8Const ("main", 4);
...@@ -41,6 +41,12 @@ java::lang::FirstThread::run (void) ...@@ -41,6 +41,12 @@ java::lang::FirstThread::run (void)
DIE ("class must be public"); DIE ("class must be public");
#endif #endif
if (klass == NULL)
{
klass = java::lang::Class::forName (klass_name);
if (klass != NULL) _Jv_InitClass (klass);
}
_Jv_Method *meth = _Jv_GetMethodLocal (klass, main_name, main_signature); _Jv_Method *meth = _Jv_GetMethodLocal (klass, main_name, main_signature);
// Some checks from Java Spec section 12.1.4. // Some checks from Java Spec section 12.1.4.
......
...@@ -45,10 +45,11 @@ java::lang::reflect::Array::newInstance (jclass componentType, jintArray dimensi ...@@ -45,10 +45,11 @@ java::lang::reflect::Array::newInstance (jclass componentType, jintArray dimensi
if (ndims == 1) if (ndims == 1)
return newInstance (componentType, dims[0]); return newInstance (componentType, dims[0]);
jclass arrayType = componentType; jclass arrayType = componentType;
for (int i = 0; i < ndims; i++) for (int i = 0; i < ndims; i++) // FIXME 2nd arg should
arrayType = _Jv_FindArrayClass (arrayType); // be "current" loader
return _Jv_NewMultiArray (arrayType, ndims, dims); arrayType = _Jv_FindArrayClass (arrayType, 0);
return _Jv_NewMultiArray (arrayType, ndims, dims);
} }
jint jint
......
...@@ -378,8 +378,10 @@ java::lang::reflect::Method::getType () ...@@ -378,8 +378,10 @@ java::lang::reflect::Method::getType ()
while (*ptr != ';' && ptr[1] != '\0'); while (*ptr != ';' && ptr[1] != '\0');
break; break;
} }
// FIXME: 2'nd argument should be "current loader"
while (--num_arrays >= 0) while (--num_arrays >= 0)
type = _Jv_FindArrayClass (type); type = _Jv_FindArrayClass (type, 0);
*argPtr++ = type; *argPtr++ = type;
} }
parameter_types = args; parameter_types = args;
......
...@@ -354,7 +354,7 @@ java::net::PlainSocketImpl::getOption (jint optID) ...@@ -354,7 +354,7 @@ java::net::PlainSocketImpl::getOption (jint optID)
if (l_val.l_onoff) if (l_val.l_onoff)
return new java::lang::Integer (l_val.l_linger); return new java::lang::Integer (l_val.l_linger);
else else
return new java::lang::Boolean (false); return new java::lang::Boolean ((__java_boolean)false);
#else #else
JvThrow (new java::lang::InternalError ( JvThrow (new java::lang::InternalError (
JvNewStringUTF ("SO_LINGER not supported"))); JvNewStringUTF ("SO_LINGER not supported")));
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# to link with libgcj. # to link with libgcj.
# #
%rename lib liborig %rename lib liborig
*lib: -lgcj -lm @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(liborig) *lib: -lgcj -lm @INTERPSPEC@ @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(liborig)
%rename cc1 cc1orig %rename cc1 cc1orig
*cc1: @DIVIDESPEC@ %(cc1orig) *cc1: @DIVIDESPEC@ %(cc1orig)
...@@ -180,6 +180,24 @@ _Jv_makeUtf8Const (char* s, int len) ...@@ -180,6 +180,24 @@ _Jv_makeUtf8Const (char* s, int len)
return (m); return (m);
} }
_Jv_Utf8Const *
_Jv_makeUtf8Const (jstring string)
{
jint hash = string->hashCode ();
jint len = _Jv_GetStringUTFLength (string);
Utf8Const* m = (Utf8Const*)
_Jv_AllocBytesChecked (sizeof(Utf8Const) + len + 1);
m->hash = hash;
m->length = len;
_Jv_GetStringUTFRegion (string, 0, string->length (), m->data);
m->data[len] = 0;
return m;
}
#ifdef DEBUG #ifdef DEBUG
...@@ -298,7 +316,10 @@ _Jv_NewObjectArray (jsize count, jclass elementClass, jobject init) ...@@ -298,7 +316,10 @@ _Jv_NewObjectArray (jsize count, jclass elementClass, jobject init)
JvThrow (no_memory); JvThrow (no_memory);
size_t size = count * sizeof (jobject) + sizeof (__JArray); size_t size = count * sizeof (jobject) + sizeof (__JArray);
jclass clas = _Jv_FindArrayClass (elementClass);
// FIXME: second argument should be "current loader" //
jclass clas = _Jv_FindArrayClass (elementClass, 0);
jobjectArray obj = (jobjectArray) _Jv_AllocArray (size); jobjectArray obj = (jobjectArray) _Jv_AllocArray (size);
if (! obj) if (! obj)
JvThrow (no_memory); JvThrow (no_memory);
...@@ -338,7 +359,7 @@ _Jv_NewPrimArray (jclass eltype, jint count) ...@@ -338,7 +359,7 @@ _Jv_NewPrimArray (jclass eltype, jint count)
arr->length = count; arr->length = count;
// Note that we assume we are given zeroed memory by the allocator. // Note that we assume we are given zeroed memory by the allocator.
jclass klass = _Jv_FindArrayClass (eltype); jclass klass = _Jv_FindArrayClass (eltype, 0);
// Set the vtbl last to avoid problems if the GC happens during the // Set the vtbl last to avoid problems if the GC happens during the
// window in this function between the allocation and this // window in this function between the allocation and this
// assignment. // assignment.
...@@ -531,9 +552,11 @@ _Jv_FindClassFromSignature (char *sig, java::lang::ClassLoader *loader) ...@@ -531,9 +552,11 @@ _Jv_FindClassFromSignature (char *sig, java::lang::ClassLoader *loader)
; ;
_Jv_Utf8Const *name = _Jv_makeUtf8Const (&sig[1], i - 1); _Jv_Utf8Const *name = _Jv_makeUtf8Const (&sig[1], i - 1);
return _Jv_FindClass (name, loader); return _Jv_FindClass (name, loader);
} }
case '[': case '[':
return _Jv_FindArrayClass (_Jv_FindClassFromSignature (&sig[1], loader)); return _Jv_FindArrayClass (_Jv_FindClassFromSignature (&sig[1], loader),
loader);
} }
JvFail ("couldn't understand class signature"); JvFail ("couldn't understand class signature");
return NULL; // Placate compiler. return NULL; // Placate compiler.
...@@ -588,9 +611,20 @@ JvRunMain (jclass klass, int argc, const char **argv) ...@@ -588,9 +611,20 @@ JvRunMain (jclass klass, int argc, const char **argv)
LTDL_SET_PRELOADED_SYMBOLS (); LTDL_SET_PRELOADED_SYMBOLS ();
#endif #endif
arg_vec = JvConvertArgv (argc - 1, argv + 1); if (klass == NULL)
main_group = new java::lang::ThreadGroup (23); {
main_thread = new java::lang::FirstThread (main_group, klass, arg_vec); arg_vec = JvConvertArgv (argc - 2, argv + 2);
main_group = new java::lang::ThreadGroup (23);
main_thread = new java::lang::FirstThread (main_group,
JvNewStringLatin1 (argv[1]),
arg_vec);
}
else
{
arg_vec = JvConvertArgv (argc - 1, argv + 1);
main_group = new java::lang::ThreadGroup (23);
main_thread = new java::lang::FirstThread (main_group, klass, arg_vec);
}
main_thread->start(); main_thread->start();
_Jv_ThreadWait (); _Jv_ThreadWait ();
...@@ -598,6 +632,7 @@ JvRunMain (jclass klass, int argc, const char **argv) ...@@ -598,6 +632,7 @@ JvRunMain (jclass klass, int argc, const char **argv)
java::lang::Runtime::getRuntime ()->exit (0); java::lang::Runtime::getRuntime ()->exit (0);
} }
void * void *
...@@ -630,7 +665,7 @@ _Jv_divI (jint dividend, jint divisor) ...@@ -630,7 +665,7 @@ _Jv_divI (jint dividend, jint divisor)
if (divisor == 0) if (divisor == 0)
_Jv_Throw (arithexception); _Jv_Throw (arithexception);
if (dividend == 0x80000000L && divisor == -1) if (dividend == (jint) 0x80000000L && divisor == -1)
return dividend; return dividend;
return dividend / divisor; return dividend / divisor;
...@@ -642,7 +677,7 @@ _Jv_remI (jint dividend, jint divisor) ...@@ -642,7 +677,7 @@ _Jv_remI (jint dividend, jint divisor)
if (divisor == 0) if (divisor == 0)
_Jv_Throw (arithexception); _Jv_Throw (arithexception);
if (dividend == 0x80000000L && divisor == -1) if (dividend == (jint) 0x80000000L && divisor == -1)
return 0; return 0;
return dividend % divisor; return dividend % divisor;
...@@ -654,7 +689,7 @@ _Jv_divJ (jlong dividend, jlong divisor) ...@@ -654,7 +689,7 @@ _Jv_divJ (jlong dividend, jlong divisor)
if (divisor == 0) if (divisor == 0)
_Jv_Throw (arithexception); _Jv_Throw (arithexception);
if (dividend == 0x8000000000000000LL && divisor == -1) if (dividend == (jlong) 0x8000000000000000LL && divisor == -1)
return dividend; return dividend;
return dividend / divisor; return dividend / divisor;
...@@ -666,9 +701,15 @@ _Jv_remJ (jlong dividend, jlong divisor) ...@@ -666,9 +701,15 @@ _Jv_remJ (jlong dividend, jlong divisor)
if (divisor == 0) if (divisor == 0)
_Jv_Throw (arithexception); _Jv_Throw (arithexception);
if (dividend == 0x8000000000000000LL && divisor == -1) if (dividend == (jlong) 0x8000000000000000LL && divisor == -1)
return 0; return 0;
return dividend % divisor; return dividend % divisor;
} }
// resolve.cc - Code for linking and resolving classes and pool entries.
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
#include <java-interp.h>
#ifdef INTERPRETER
#include <cni.h>
#include <jvm.h>
#include <string.h>
#include <java-cpool.h>
#include <java/lang/Class.h>
#include <java/lang/String.h>
#include <java/lang/Thread.h>
#include <java/lang/InternalError.h>
#include <java/lang/VirtualMachineError.h>
#include <java/lang/NoSuchFieldError.h>
#include <java/lang/ClassFormatError.h>
#include <java/lang/IllegalAccessError.h>
#include <java/lang/AbstractMethodError.h>
#include <java/lang/ClassNotFoundException.h>
#include <java/lang/IncompatibleClassChangeError.h>
static void throw_internal_error (char *msg)
__attribute__ ((__noreturn__));
static void throw_class_format_error (jstring msg)
__attribute__ ((__noreturn__));
static void throw_class_format_error (char *msg)
__attribute__ ((__noreturn__));
#define StringClass _CL_Q34java4lang6String
extern java::lang::Class StringClass;
#define ClassObject _CL_Q34java4lang6Object
extern java::lang::Class ClassObject;
#define ObjectClass _CL_Q34java4lang6Object
extern java::lang::Class ObjectClass;
static int get_alignment_from_class (jclass);
static _Jv_ResolvedMethod*
_Jv_BuildResolvedMethod (_Jv_Method*,
jclass,
jboolean,
jint);
static const int PUBLIC = 0x001;
static const int PRIVATE = 0x002;
static const int PROTECTED = 0x004;
static const int STATIC = 0x008;
static const int FINAL = 0x010;
static const int SYNCHRONIZED = 0x020;
static const int VOLATILE = 0x040;
static const int TRANSIENT = 0x080;
static const int NATIVE = 0x100;
static const int INTERFACE = 0x200;
static const int ABSTRACT = 0x400;
static const int ALL_FLAGS = 0x7FF;
// We need to know the name of a constructor.
static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
static void throw_incompatible_class_change_error (jstring msg)
{
JvThrow (new java::lang::IncompatibleClassChangeError (msg));
}
void*
_Jv_ResolvePoolEntry (jclass klass, int index)
{
_Jv_Constants *pool = &klass->constants;
if ((pool->tags[index] & JV_CONSTANT_ResolvedFlag) != 0)
return pool->data[index];
switch (pool->tags[index]) {
case JV_CONSTANT_Class:
{
_Jv_Utf8Const *name = (_Jv_Utf8Const *) pool->data[index];
jclass found;
if (name->data[0] == '[')
found = _Jv_FindClassFromSignature (&name->data[0],
klass->loader);
else
found = _Jv_FindClass (name, klass->loader);
if (! found)
{
jstring str = _Jv_NewStringUTF (name->data);
JvThrow (new java::lang::ClassNotFoundException (str));
}
if ((found->accflags & PUBLIC) == PUBLIC
|| (_Jv_ClassNameSamePackage (found->name,
klass->name)))
{
pool->data[index] = (void *) found;
pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
}
else
{
JvThrow (new java::lang::IllegalAccessError (found->getName()));
}
}
break;
case JV_CONSTANT_String:
{
jstring str;
str = _Jv_NewStringUtf8Const ((_Jv_Utf8Const *) pool->data[index]);
pool->data[index] = (void *) str;
pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
}
break;
case JV_CONSTANT_Fieldref:
{
_Jv_ushort class_index, name_and_type_index;
_Jv_loadIndexes ((const void**) &pool->data[index],
class_index,
name_and_type_index);
jclass owner = (jclass) _Jv_ResolvePoolEntry (klass, class_index);
if (owner != klass)
_Jv_InitClass (owner);
_Jv_ushort name_index, type_index;
_Jv_loadIndexes ((const void**) &pool->data[name_and_type_index],
name_index,
type_index);
_Jv_Utf8Const *field_name = (_Jv_Utf8Const*) pool->data[name_index];
_Jv_Utf8Const *field_type_name =
(_Jv_Utf8Const*) pool->data[type_index];
// FIXME: The implementation of this function
// (_Jv_FindClassFromSignature) will generate an instance of
// _Jv_Utf8Const for each call if the field type is a class name
// (Lxx.yy.Z;). This may be too expensive to do for each and
// every fieldref being resolved. For now, we fix the problem by
// only doing it when we have a loader different from the class
// declaring the field.
jclass field_type = 0;
if (owner->loader != klass->loader)
field_type = _Jv_FindClassFromSignature (field_type_name->data,
klass->loader);
_Jv_Field* the_field = 0;
for (jclass cls = owner; cls != 0; cls = cls->getSuperclass ())
{
for (int i = 0; i < cls->field_count; i++)
{
_Jv_Field *field = &cls->fields[i];
if (! _Jv_equalUtf8Consts (field->name, field_name))
continue;
// now, check field access.
if ( (cls == klass)
|| ((field->flags & PUBLIC) != 0)
|| (((field->flags & PROTECTED) != 0)
&& cls->isAssignableFrom (klass))
|| (((field->flags & PRIVATE) == 0)
&& _Jv_ClassNameSamePackage (cls->name,
klass->name)))
{
/* resove the field using the class' own loader
if necessary */
if (!field->isResolved ())
_Jv_ResolveField (field, cls->loader);
if (field_type != 0 && field->type != field_type)
JvThrow
(new java::lang::LinkageError
(JvNewStringLatin1
("field type mismatch with different loaders")));
the_field = field;
goto end_of_field_search;
}
else
{
JvThrow (new java::lang::IllegalAccessError);
}
}
}
end_of_field_search:
if (the_field == 0)
{
jstring msg = JvNewStringLatin1 ("field ");
msg = msg->concat (owner->getName ());
msg = msg->concat (JvNewStringLatin1("."));
msg = msg->concat (_Jv_NewStringUTF (field_name->data));
msg = msg->concat (JvNewStringLatin1(" was not found."));
throw_incompatible_class_change_error (msg);
}
pool->data[index] = (void*)the_field;
pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
}
break;
case JV_CONSTANT_Methodref:
case JV_CONSTANT_InterfaceMethodref:
{
_Jv_ushort class_index, name_and_type_index;
_Jv_loadIndexes ((const void**) &pool->data[index],
class_index,
name_and_type_index);
jclass owner = (jclass) _Jv_ResolvePoolEntry (klass, class_index);
if (owner != klass)
_Jv_InitClass (owner);
_Jv_ushort name_index, type_index;
_Jv_loadIndexes ((const void**) &pool->data[name_and_type_index],
name_index,
type_index);
_Jv_Utf8Const *method_name = (_Jv_Utf8Const*) pool->data[name_index];
_Jv_Utf8Const *method_signature =
(_Jv_Utf8Const*) pool->data[type_index];
int vtable_index = -1;
_Jv_Method *the_method = 0;
jclass found_class = 0;
// we make a loop here, because methods are allowed to be moved to
// a super class, and still be visible.. (binary compatibility).
for (jclass cls = owner; cls != 0; cls = cls->getSuperclass ())
{
for (int i = 0; i < cls->method_count; i++)
{
_Jv_Method *method = &cls->methods[i];
if ( (!_Jv_equalUtf8Consts (method->name,
method_name))
|| (!_Jv_equalUtf8Consts (method->signature,
method_signature)))
continue;
if (cls == klass
|| ((method->accflags & PUBLIC) != 0)
|| (((method->accflags & PROTECTED) != 0)
&& cls->isAssignableFrom (klass))
|| (((method->accflags & PRIVATE) == 0)
&& _Jv_ClassNameSamePackage (cls->name,
klass->name)))
{
// FIXME: if (cls->loader != klass->loader), then we
// must actually check that the types of arguments
// correspond. That is, for each argument type, and
// the return type, doing _Jv_FindClassFromSignature
// with either loader should produce the same result,
// i.e., exactly the same jclass object. JVMS 5.4.3.3
the_method = method;
found_class = cls;
if (pool->tags[index] == JV_CONSTANT_InterfaceMethodref)
vtable_index = -1;
else
vtable_index = _Jv_DetermineVTableIndex
(cls, method_name, method_signature);
if (vtable_index == 0)
throw_incompatible_class_change_error
(JvNewStringLatin1 ("method not found"));
goto end_of_method_search;
}
else
{
JvThrow (new java::lang::IllegalAccessError);
}
}
}
end_of_method_search:
if (the_method == 0)
{
jstring msg = JvNewStringLatin1 ("method ");
msg = msg->concat (owner->getName ());
msg = msg->concat (JvNewStringLatin1("."));
msg = msg->concat (_Jv_NewStringUTF (method_name->data));
msg = msg->concat (JvNewStringLatin1(" was not found."));
JvThrow(new java::lang::NoSuchFieldError (msg));
}
pool->data[index] = (void*)
_Jv_BuildResolvedMethod(the_method,
found_class,
((the_method->accflags & STATIC) != 0),
vtable_index);
pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
}
break;
}
return pool->data[index];
}
void
_Jv_ResolveField (_Jv_Field *field, java::lang::ClassLoader *loader)
{
if (! field->isResolved ())
{
_Jv_Utf8Const *sig = (_Jv_Utf8Const*)field->type;
field->type = _Jv_FindClassFromSignature (sig->data, loader);
field->flags &= ~_Jv_FIELD_UNRESOLVED_FLAG;
}
}
_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.
Returns 0 if this class does not declare the given method.
Returns -1 if the given method does not appear in the vtable.
i.e., it is static, private, final or a constructor.
Otherwise, returns the vtable index. */
int
_Jv_DetermineVTableIndex (jclass klass,
_Jv_Utf8Const *name,
_Jv_Utf8Const *signature)
{
jclass super_class = klass->getSuperclass ();
if (super_class != NULL)
{
int prev = _Jv_DetermineVTableIndex (super_class,
name,
signature);
if (prev != 0)
return prev;
}
/* at this point, we know that the super-class does not declare
* the method. Otherwise, the above call would have found it, and
* determined the result of this function (-1 or some positive
* number).
*/
_Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
/* now, if we do not declare this method, return zero */
if (meth == NULL)
return 0;
/* so now, we know not only that the super class does not declare the
* method, but we do! So, this is a first declaration of the method. */
/* now, the checks for things that are declared in this class, but do
* not go into the vtable. There are three cases.
* 1) the method is static, private or final
* 2) the class itself is final, or
* 3) it is the method <init>
*/
if ( (meth->accflags & (STATIC|PRIVATE|FINAL)) != 0
|| (klass->accflags & FINAL) != 0
|| _Jv_equalUtf8Consts (name, init_name))
return -1;
/* reaching this point, we know for sure, that the method in question
* will be in the vtable. The question is where. */
/* the base offset, is where we will start assigning vtable
* indexes for this class. It is 1 for base classes
* (vtable->method[0] is unused), and for non-base classes it is the
* number of entries in the super class' vtable plus 1. */
int base_offset;
if (super_class == 0)
base_offset = 1;
else
base_offset = super_class->vtable_method_count+1;
/* we will consider methods 0..this_method_index-1. And for each one,
* determine if it is new (i.e., if it appears in the super class),
* and if it should go in the vtable. If so, increment base_offset */
int this_method_index = meth - (&klass->methods[0]);
for (int i = 0; i < this_method_index; i++)
{
_Jv_Method *m = &klass->methods[i];
/* fist some checks for things that surely do not go in the
* vtable */
if ((m->accflags & (STATIC|PRIVATE)) != 0)
continue;
if (_Jv_equalUtf8Consts (m->name, init_name))
continue;
/* Then, we need to know if this method appears in the
superclass. (This is where this function gets expensive) */
_Jv_Method *sm = _Jv_LookupDeclaredMethod (super_class,
m->name,
m->signature);
/* if it was somehow declared in the superclass, skip this */
if (sm != NULL)
continue;
/* but if it is final, and not declared in the super class,
* then we also skip it */
if ((m->accflags & FINAL) != 0)
continue;
/* finally, we can assign the index of this method */
/* m->vtable_index = base_offset */
base_offset += 1;
}
return base_offset;
}
/* this is installed in place of abstract methods */
static void
_Jv_abstractMethodError ()
{
JvThrow (new java::lang::AbstractMethodError);
}
void
_Jv_PrepareClass(jclass klass)
{
/*
* The job of this function is to: 1) assign storage to fields, and 2)
* build the vtable. static fields are assigned real memory, instance
* fields are assigned offsets.
*
* NOTE: we have a contract with the garbage collector here. Static
* reference fields must not be resolved, until after they have storage
* assigned which is the check used by the collector to see if it
* should indirect the static field reference and mark the object
* pointed to.
*
* Most fields are resolved lazily (i.e. have their class-type
* assigned) when they are accessed the first time by calling as part
* of _Jv_ResolveField, which is allways called after _Jv_PrepareClass.
* Static fields with initializers are resolved as part of this
* function, as are fields with primitive types.
*/
if (! _Jv_IsInterpretedClass (klass))
return;
if (klass->state >= JV_STATE_PREPARED)
return;
// make sure super-class is linked. This involves taking a lock on
// the super class, so we use the Java method resolveClass, which will
// unlock it properly, should an exception happen.
java::lang::ClassLoader::resolveClass (klass->superclass);
_Jv_InterpClass *clz = (_Jv_InterpClass*)klass;
/************ PART ONE: OBJECT LAYOUT ***************/
int instance_size;
int static_size;
// java.lang.Object is never interpreted!
instance_size = clz->superclass->size ();
static_size = 0;
for (int i = 0; i < clz->field_count; i++)
{
int field_size;
int field_align;
_Jv_Field *field = &clz->fields[i];
if (! field->isRef ())
{
// it's safe to resolve the field here, since it's
// a primitive class, which does not cause loading to happen.
_Jv_ResolveField (field, clz->loader);
field_size = field->type->size ();
field_align = get_alignment_from_class (field->type);
}
else
{
field_size = sizeof (jobject);
field_align = __alignof__ (jobject);
}
#ifndef COMPACT_FIELDS
field->bsize = field_size;
#endif
if (field->flags & STATIC)
{
/* this computes an offset into a region we'll allocate
shortly, and then add this offset to the start address */
static_size = ROUND (static_size, field_align);
field->u.boffset = static_size;
static_size += field_size;
}
else
{
instance_size = ROUND (instance_size, field_align);
field->u.boffset = instance_size;
instance_size += field_size;
}
}
// set the instance size for the class
clz->size_in_bytes = instance_size;
// allocate static memory
if (static_size != 0)
{
char *static_data = (char*)_Jv_AllocBytesChecked (static_size);
memset (static_data, 0, static_size);
for (int i = 0; i < clz->field_count; i++)
{
_Jv_Field *field = &clz->fields[i];
if ((field->flags & STATIC) != 0)
{
field->u.addr = static_data + field->u.boffset;
if (clz->field_initializers[i] != 0)
{
_Jv_ResolveField (field, clz->loader);
_Jv_InitField (0, clz, i);
}
}
}
// now we don't need the field_initializers anymore, so let the
// collector get rid of it!
clz->field_initializers = 0;
}
/************ PART TWO: VTABLE LAYOUT ***************/
/* preparation: build the vtable stubs (even interfaces can)
have code -- for static constructors. */
for (int i = 0; i < clz->method_count; i++)
{
_Jv_InterpMethod *imeth = clz->interpreted_methods[i];
if (imeth != 0) // it could be abstract or native
{
clz->methods[i].ncode = imeth->ncode ();
}
else
{
if ((clz->methods[i].accflags & NATIVE) != 0)
{
JvThrow
(new java::lang::VirtualMachineError
(JvNewStringLatin1
("the interpreter does not support native methods")));
}
}
}
if (clz->accflags & INTERFACE)
{
clz->state = JV_STATE_PREPARED;
clz->notifyAll ();
return;
}
/* FIXME: native methods for interpreted classes should be handled, I
* dunno exactly how, but it seems that we should try to find them at
* this point, and if we fail, try again after <clinit>, since it
* could have caused additional code to be loaded. Interfaces cannot
* have native methods (not even for static initialization). */
/* Now onto the actual job: vtable layout. First, count how many new
methods we have */
int new_method_count = 0;
jclass super_class = clz->getSuperclass ();
if (super_class == 0)
throw_internal_error ("cannot handle interpreted base classes");
for (int i = 0; i < clz->method_count; i++)
{
_Jv_Method *this_meth = &clz->methods[i];
if ((this_meth->accflags & (STATIC|PRIVATE)) != 0
|| _Jv_equalUtf8Consts (this_meth->name, init_name))
{
/* skip this, it doesn't go in the vtable */
continue;
}
_Jv_Method *orig_meth = _Jv_LookupDeclaredMethod (super_class,
this_meth->name,
this_meth->signature);
if (orig_meth == 0)
{
// new methods that are final, also don't go in the vtable
if ((this_meth->accflags & FINAL) != 0)
continue;
new_method_count += 1;
continue;
}
if ((orig_meth->accflags & (STATIC|PRIVATE|FINAL)) != 0
|| ((orig_meth->accflags & ABSTRACT) == 0
&& (this_meth->accflags & ABSTRACT) != 0
&& (klass->accflags & ABSTRACT) == 0))
{
clz->state = JV_STATE_ERROR;
clz->notifyAll ();
JvThrow (new java::lang::IncompatibleClassChangeError
(clz->getName ()));
}
/* FIXME: At this point, if (loader != super_class->loader), we
* need to "impose class loader constraints" for the types
* involved in the signature of this method */
}
/* determine size */
int vtable_count = (super_class->vtable_method_count) + new_method_count;
clz->vtable_method_count = vtable_count;
/* allocate vtable structure */
_Jv_VTable *vtable = (_Jv_VTable*)
_Jv_AllocBytesChecked (sizeof (_Jv_VTable)
+ (sizeof (void*) * (vtable_count)));
vtable->clas = clz;
/* copy super class' vtable entries (index 0 goes unused). */
memcpy ((void*)&vtable->method[1],
(void*)&super_class->vtable->method[1],
sizeof (void*) * super_class->vtable_method_count);
/* now, install our own vtable entries, reprise... */
for (int i = 0; i < clz->method_count; i++)
{
_Jv_Method *this_meth = &clz->methods[i];
int index = _Jv_DetermineVTableIndex (clz,
this_meth->name,
this_meth->signature);
if (index == 0)
throw_internal_error ("method now found in own class");
if (index != -1)
{
if (index > clz->vtable_method_count+1)
throw_internal_error ("vtable problem...");
if (clz->interpreted_methods[i] == 0)
vtable->method[index] = (void*)&_Jv_abstractMethodError;
else
vtable->method[index] = this_meth->ncode;
}
}
/* finally, assign the vtable! */
clz->vtable = vtable;
/* wooha! we're done. */
clz->state = JV_STATE_PREPARED;
clz->notifyAll ();
}
/** Do static initialization for fields with a constant initializer */
void
_Jv_InitField (jobject obj, jclass klass, int index)
{
if (obj != 0 && klass == 0)
klass = obj->getClass ();
if (!_Jv_IsInterpretedClass (klass))
return;
_Jv_InterpClass *clz = (_Jv_InterpClass*)klass;
_Jv_Field * field = (&clz->fields[0]) + index;
if (index > clz->field_count)
throw_internal_error ("field out of range");
int init = clz->field_initializers[index];
if (init == 0)
return;
_Jv_Constants *pool = &clz->constants;
int tag = pool->tags[init];
if (! field->isResolved ())
throw_internal_error ("initializing unresolved field");
if (obj==0 && ((field->flags & STATIC) == 0))
throw_internal_error ("initializing non-static field with no object");
void *addr = 0;
if ((field->flags & STATIC) != 0)
addr = (void*) field->u.addr;
else
addr = (void*) (((char*)obj) + field->u.boffset);
switch (tag)
{
case JV_CONSTANT_String:
{
_Jv_MonitorEnter (clz);
jstring str;
str = _Jv_NewStringUtf8Const ((_Jv_Utf8Const *) pool->data[init]);
pool->data[init] = (void *) str;
pool->tags[init] = JV_CONSTANT_ResolvedString;
_Jv_MonitorExit (clz);
}
/* fall through */
case JV_CONSTANT_ResolvedString:
if (! (field->type == &StringClass || field->type == &ObjectClass))
throw_class_format_error ("string initialiser to non-string field");
*(jstring*)addr = *(jstring*) (pool->data + init);
break;
case JV_CONSTANT_Integer:
{
int value = *(jint*)(pool->data + init);
if (field->type == JvPrimClass (boolean))
*(jboolean*)addr = (jboolean)value;
else if (field->type == JvPrimClass (byte))
*(jbyte*)addr = (jbyte)value;
else if (field->type == JvPrimClass (char))
*(jchar*)addr = (jchar)value;
else if (field->type == JvPrimClass (short))
*(jshort*)addr = (jshort)value;
else if (field->type == JvPrimClass (int))
*(jint*)addr = (jint)value;
else
throw_class_format_error ("erroneous field initializer");
}
break;
case JV_CONSTANT_Long:
if (field->type != JvPrimClass (long))
throw_class_format_error ("erroneous field initializer");
memcpy (addr, pool->data+init, 8);
break;
case JV_CONSTANT_Float:
if (field->type != JvPrimClass (float))
throw_class_format_error ("erroneous field initializer");
memcpy (addr, pool->data+init, 4);
break;
case JV_CONSTANT_Double:
if (field->type != JvPrimClass (double))
throw_class_format_error ("erroneous field initializer");
memcpy (addr, pool->data+init, 8);
break;
default:
throw_class_format_error ("erroneous field initializer");
}
}
static int
get_alignment_from_class (jclass klass)
{
if (klass == JvPrimClass (byte))
return __alignof__ (jbyte);
else if (klass == JvPrimClass (short))
return __alignof__ (jshort);
else if (klass == JvPrimClass (int))
return __alignof__ (jint);
else if (klass == JvPrimClass (long))
return __alignof__ (jlong);
else if (klass == JvPrimClass (boolean))
return __alignof__ (jboolean);
else if (klass == JvPrimClass (char))
return __alignof__ (jchar);
else if (klass == JvPrimClass (float))
return __alignof__ (jfloat);
else if (klass == JvPrimClass (double))
return __alignof__ (jdouble);
else
return __alignof__ (jobject);
}
inline static unsigned char*
skip_one_type (unsigned char* ptr)
{
int ch = *ptr++;
while (ch == '[')
{
ch = *ptr++;
}
if (ch == 'L')
{
do { ch = *ptr++; } while (ch != ';');
}
return ptr;
}
static ffi_type*
get_ffi_type_from_signature (unsigned char* ptr)
{
switch (*ptr)
{
case 'L':
case '[':
return &ffi_type_pointer;
break;
case 'Z':
case 'B':
return &ffi_type_sint8;
break;
case 'C':
return &ffi_type_uint16;
break;
case 'S':
return &ffi_type_sint16;
break;
case 'I':
return &ffi_type_sint32;
break;
case 'J':
return &ffi_type_sint64;
break;
case 'F':
return &ffi_type_float;
break;
case 'D':
return &ffi_type_double;
break;
case 'V':
return &ffi_type_void;
break;
}
throw_internal_error ("unknown type in signature");
}
/* this function yields the number of actual arguments, that is, if the
* function is non-static, then one is added to the number of elements
* found in the signature */
static int
count_arguments (_Jv_Utf8Const *signature,
jboolean staticp)
{
unsigned char *ptr = (unsigned char*) signature->data;
int arg_count = staticp ? 0 : 1;
/* first, count number of arguments */
// skip '('
ptr++;
// count args
while (*ptr != ')')
{
ptr = skip_one_type (ptr);
arg_count += 1;
}
return arg_count;
}
/* This beast will build a cif, given the signature. Memory for
* the cif itself and for the argument types must be allocated by the
* caller.
*/
static int
init_cif (_Jv_Utf8Const* signature,
int arg_count,
jboolean staticp,
ffi_cif *cif,
ffi_type **arg_types)
{
unsigned char *ptr = (unsigned char*) signature->data;
int arg_index = 0; // arg number
int item_count = 0; // stack-item count
// setup receiver
if (!staticp)
{
arg_types[arg_index++] = &ffi_type_pointer;
item_count += 1;
}
// skip '('
ptr++;
// assign arg types
while (*ptr != ')')
{
arg_types[arg_index++] = get_ffi_type_from_signature (ptr);
if (*ptr == 'J' || *ptr == 'D')
item_count += 2;
else
item_count += 1;
ptr = skip_one_type (ptr);
}
// skip ')'
ptr++;
ffi_type *rtype = get_ffi_type_from_signature (ptr);
ptr = skip_one_type (ptr);
if (ptr != (unsigned char*)signature->data + signature->length)
throw_internal_error ("did not find end of signature");
if (ffi_prep_cif (cif, FFI_DEFAULT_ABI,
arg_count, rtype, arg_types) != FFI_OK)
throw_internal_error ("ffi_prep_cif failed");
return item_count;
}
/* we put this one here, and not in interpret.cc because it
* calls the utility routines count_arguments
* which are static to this module. The following struct defines the
* layout we use for the stubs, it's only used in the ncode method. */
typedef struct {
ffi_raw_closure closure;
ffi_cif cif;
ffi_type *arg_types[0];
} ncode_closure;
typedef void (*ffi_closure_fun) (ffi_cif*,void*,ffi_raw*,void*);
void* _Jv_InterpMethod::ncode ()
{
if (self->ncode != 0)
return self->ncode;
jboolean staticp = (self->accflags & STATIC) != 0;
int arg_count = count_arguments (self->signature, staticp);
ncode_closure *closure =
(ncode_closure*)_Jv_AllocBytesChecked (sizeof (ncode_closure)
+ arg_count * sizeof (ffi_type*));
init_cif (self->signature,
arg_count,
staticp,
&closure->cif,
&closure->arg_types[0]);
ffi_closure_fun fun;
args_raw_size = ffi_raw_size (&closure->cif);
if ((self->accflags & SYNCHRONIZED) != 0)
{
if (staticp)
fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_class;
else
fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_object;
}
else
{
fun = (ffi_closure_fun)&_Jv_InterpMethod::run_normal;
}
ffi_prep_raw_closure (&closure->closure,
&closure->cif,
fun,
(void*)this);
self->ncode = (void*)closure;
return self->ncode;
}
/* A _Jv_ResolvedMethod is what is put in the constant pool for a
* MethodRef or InterfacemethodRef. */
static _Jv_ResolvedMethod*
_Jv_BuildResolvedMethod (_Jv_Method* method,
jclass klass,
jboolean staticp,
jint vtable_index)
{
int arg_count = count_arguments (method->signature, staticp);
_Jv_ResolvedMethod* result = (_Jv_ResolvedMethod*)
_Jv_AllocBytesChecked (sizeof (_Jv_ResolvedMethod)
+ arg_count*sizeof (ffi_type*));
result->stack_item_count
= init_cif (method->signature,
arg_count,
staticp,
&result->cif,
&result->arg_types[0]);
result->vtable_index = vtable_index;
result->method = method;
result->klass = klass;
return result;
}
static void
throw_class_format_error (jstring msg)
{
if (msg == 0)
JvThrow (new java::lang::ClassFormatError);
else
JvThrow (new java::lang::ClassFormatError (msg));
}
static void
throw_class_format_error (char *msg)
{
throw_class_format_error (JvNewStringLatin1 (msg));
}
static void
throw_internal_error (char *msg)
{
JvThrow
(new java::lang::InternalError (JvNewStringLatin1 (msg)));
}
#endif
...@@ -71,6 +71,7 @@ COMPPATH = @COMPPATH@ ...@@ -71,6 +71,7 @@ COMPPATH = @COMPPATH@
CPP = @CPP@ CPP = @CPP@
CXX = @CXX@ CXX = @CXX@
CXXCPP = @CXXCPP@ CXXCPP = @CXXCPP@
DIVIDESPEC = @DIVIDESPEC@
DLLTOOL = @DLLTOOL@ DLLTOOL = @DLLTOOL@
EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@ EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
EXEEXT = @EXEEXT@ EXEEXT = @EXEEXT@
...@@ -79,6 +80,7 @@ GCINCS = @GCINCS@ ...@@ -79,6 +80,7 @@ GCINCS = @GCINCS@
GCLIBS = @GCLIBS@ GCLIBS = @GCLIBS@
GCOBJS = @GCOBJS@ GCOBJS = @GCOBJS@
GCSPEC = @GCSPEC@ GCSPEC = @GCSPEC@
INTERPSPEC = @INTERPSPEC@
LD = @LD@ LD = @LD@
LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@ LIBGCJ_CFLAGS = @LIBGCJ_CFLAGS@
LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@ LIBGCJ_CXXFLAGS = @LIBGCJ_CXXFLAGS@
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment