# Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
# Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
#
-# Last Change: 1998/09/27
+# Last Change: 1998/10/30
#
#
# ATTENTION: This version of the makefile only works with gmake.
THREAD_CFLAGS =
endif
-#CC = gcc
+#CC = cc
#CFLAGS = -g -mieee -Wall $(THREAD_CFLAGS)
#CFLAGS = -mieee -O3 -Wall $(THREAD_CFLAGS)
mm/mm.o: mm/*.[ch] mm/Makefile
cd mm; make mm.o "USE_THREADS=$(USE_THREADS)" "CFLAGS=$(CFLAGS)" "CC=$(CC)"
-asmpart.o: sysdep/asmpart.c
+asmpart.o: sysdep/asmpart.c sysdep/offsets.h
rm -f asmpart.s
$(CC) -E sysdep/asmpart.c > asmpart.s
$(CC) -c -o asmpart.o asmpart.s
##################### generation of NATIVE - header files ######################
-nativetypes.hh nativetable.hh : cacaoh
+sysdep/offsets.h nativetypes.hh nativetable.hh : cacaoh
./cacaoh java.lang.Object \
java.lang.String \
java.lang.Class \
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
/****************************** builtin.c **************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
builtin_descriptor builtin_desc[] = {
{(functionptr) builtin_instanceof, "instanceof"},
{(functionptr) builtin_checkcast, "checkcast"},
- {(functionptr) new_builtin_checkcast, "checkcast"},
- {(functionptr) new_builtin_checkclasscast, "checkclasscast"},
- {(functionptr) new_builtin_checkintercast, "checkintercast"},
{(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
{(functionptr) builtin_checkarraycast, "checkarraycast"},
- {(functionptr) new_builtin_checkarraycast, "checkarraycast"},
- {(functionptr) new_builtin_aastore, "aastore"},
+ {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
+ {(functionptr) asm_builtin_aastore, "aastore"},
{(functionptr) builtin_new, "new"},
{(functionptr) builtin_anewarray, "anewarray"},
{(functionptr) builtin_newarray_array, "newarray_array"},
{(functionptr) builtin_displaymethodstart, "displaymethodstart"},
{(functionptr) builtin_displaymethodstop, "displaymethodstop"},
{(functionptr) builtin_monitorenter, "monitorenter"},
- {(functionptr) new_builtin_monitorenter, "monitorenter"},
+ {(functionptr) asm_builtin_monitorenter, "monitorenter"},
{(functionptr) builtin_monitorexit, "monitorexit"},
- {(functionptr) new_builtin_monitorexit, "monitorexit"},
+ {(functionptr) asm_builtin_monitorexit, "monitorexit"},
{(functionptr) builtin_idiv, "idiv"},
- {(functionptr) new_builtin_idiv, "idiv"},
+ {(functionptr) asm_builtin_idiv, "idiv"},
{(functionptr) builtin_irem, "irem"},
- {(functionptr) new_builtin_irem, "irem"},
+ {(functionptr) asm_builtin_irem, "irem"},
{(functionptr) builtin_ladd, "ladd"},
{(functionptr) builtin_lsub, "lsub"},
{(functionptr) builtin_lmul, "lmul"},
{(functionptr) builtin_ldiv, "ldiv"},
- {(functionptr) new_builtin_ldiv, "ldiv"},
+ {(functionptr) asm_builtin_ldiv, "ldiv"},
{(functionptr) builtin_lrem, "lrem"},
- {(functionptr) new_builtin_lrem, "lrem"},
+ {(functionptr) asm_builtin_lrem, "lrem"},
{(functionptr) builtin_lshl, "lshl"},
{(functionptr) builtin_lshr, "lshr"},
{(functionptr) builtin_lushr, "lushr"},
static s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
{
- if (super->flags & ACC_INTERFACE) {
- s4 index = super->index;
- if (index >= sub->vftbl->interfacetablelength) return 0;
- return ( sub->vftbl->interfacevftbl[index] ) ? 1 : 0;
- }
- return (sub->vftbl->lowclassval >= super->vftbl->lowclassval) &
- (sub->vftbl->lowclassval <= super->vftbl->highclassval);
+ if (super->flags & ACC_INTERFACE)
+ return (sub->vftbl->interfacetablelength > super->index) &&
+ (sub->vftbl->interfacetable[-super->index] != NULL);
+
+ return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
+ (unsigned) (super->vftbl->diffval);
}
log_text ("builtin_checkcast called");
#endif
- if (!obj) return 1;
- if ( builtin_isanysubclass (obj->vftbl->class, class) ) {
+ if (obj == NULL)
return 1;
- }
-#if DEBUG
- printf ("#### checkcast failed ");
- unicode_display (obj->vftbl->class->name);
- printf (" -> ");
- unicode_display (class->name);
- printf ("\n");
-#endif
-
- return 0;
-}
-
-
-/***************** function: builtin_checkclasscast ****************************
-
- Returns 1 (true) if the object "sub" is a subclass of the class "super",
- otherwise returns 0 (false). If sub is NULL it also returns 1 (true).
-
-*******************************************************************************/
-
-s4 builtin_checkclasscast(java_objectheader *sub, classinfo *super)
-{
- if (!sub)
+ if (builtin_isanysubclass (obj->vftbl->class, class))
return 1;
- return (sub->vftbl->lowclassval >= super->vftbl->lowclassval) &
- (sub->vftbl->lowclassval <= super->vftbl->highclassval);
-}
-
-
-/***************** function: builtin_checkintercast ****************************
-
- Returns 1 (true) if the object "sub" is a subclass of the interface "super",
- otherwise returns 0 (false). If "sub" is NULL it also returns 1 (true).
-
-*******************************************************************************/
-
-s4 builtin_checkintercast(java_objectheader *sub, classinfo *super)
-{
- if (!sub)
- return 1;
+#if DEBUG
+ printf ("#### checkcast failed ");
+ unicode_display (obj->vftbl->class->name);
+ printf (" -> ");
+ unicode_display (class->name);
+ printf ("\n");
+#endif
- return (sub->vftbl->interfacetablelength > super->index) &&
- (sub->vftbl->interfacevftbl[super->index] != NULL);
return 0;
}
}
}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
s4 builtin_instanceof(java_objectheader *obj, classinfo *class);
s4 builtin_checkcast(java_objectheader *obj, classinfo *class);
-s4 new_builtin_checkcast(java_objectheader *obj, classinfo *class);
-s4 new_builtin_checkclasscast(java_objectheader *obj, classinfo *class);
-s4 new_builtin_checkintercast(java_objectheader *obj, classinfo *class);
s4 builtin_arrayinstanceof
(java_objectheader *obj, constant_arraydescriptor *desc);
s4 builtin_checkarraycast
(java_objectheader *obj, constant_arraydescriptor *desc);
-s4 new_builtin_checkarraycast
+s4 asm_builtin_checkarraycast
(java_objectheader *obj, constant_arraydescriptor *desc);
java_objectheader *builtin_throw_exception (java_objectheader *exception);
s4 builtin_canstore (java_objectarray *a, java_objectheader *o);
s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o);
-void new_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o);
+void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o);
void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5, methodinfo *method);
void builtin_displaymethodstart(methodinfo *method);
void builtin_displaymethodexception(methodinfo *method);
void builtin_monitorenter (java_objectheader *o);
-void new_builtin_monitorenter (java_objectheader *o);
+void asm_builtin_monitorenter (java_objectheader *o);
void builtin_monitorexit (java_objectheader *o);
-void new_builtin_monitorexit (java_objectheader *o);
+void asm_builtin_monitorexit (java_objectheader *o);
s4 builtin_idiv (s4 a, s4 b);
-s4 new_builtin_idiv (s4 a, s4 b);
+s4 asm_builtin_idiv (s4 a, s4 b);
s4 builtin_irem (s4 a, s4 b);
-s4 new_builtin_irem (s4 a, s4 b);
+s4 asm_builtin_irem (s4 a, s4 b);
s8 builtin_ladd (s8 a, s8 b);
s8 builtin_lsub (s8 a, s8 b);
s8 builtin_lmul (s8 a, s8 b);
s8 builtin_ldiv (s8 a, s8 b);
-s8 new_builtin_ldiv (s8 a, s8 b);
+s8 asm_builtin_ldiv (s8 a, s8 b);
s8 builtin_lrem (s8 a, s8 b);
-s8 new_builtin_lrem (s8 a, s8 b);
+s8 asm_builtin_lrem (s8 a, s8 b);
s8 builtin_lshl (s8 a, s4 b);
s8 builtin_lshr (s8 a, s4 b);
s8 builtin_lushr (s8 a, s4 b);
-/****************************** global.h ***************************************
+/* global.h ********************************************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
Contains global definitions which are used in the whole program, includes
some files and contains global used macros.
- Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
- Changes: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
- Mark Probst EMAIL: cacao@complang.tuwien.ac.at
- Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at
+ Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
+ Andreas Krall (andi) EMAIL: cacao@complang.tuwien.ac.at
+ Changes: Mark Probst (schani) EMAIL: cacao@complang.tuwien.ac.at
+ Philipp Tomsich (phil) EMAIL: cacao@complang.tuwien.ac.at
Last Change: 1998/10/30
marker functions on and off. */
#undef JIT_MARKER_SUPPORT /* phil */
-/***************************** standard includes ******************************/
+/* standard includes **********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "toolbox/loging.h"
-/**************************** system dependent types **************************/
+/* system dependent types *****************************************************/
#include "sysdep/types.h"
-/**************************** additional data types ***************************/
+/* additional data types ******************************************************/
typedef void *voidptr; /* generic pointer */
-
-typedef u1 bool; /* boolean data type */
+typedef int bool; /* boolean data type */
#define true 1
#define false 0
#define MAX_ALIGN 8 /* most generic alignment for JavaVM values */
-/**************************** shutdown function *******************************/
+/* shutdown function **********************************************************/
void cacao_shutdown(s4 status);
-/**************************** basic data types ********************************/
+/* basic data types ***********************************************************/
#define TYPE_INT 0 /* the JavaVM types must numbered in the */
#define TYPE_LONG 1 /* same order as the ICMD_Ixxx to ICMD_Axxx */
#define TYPE_FLOAT 2 /* instructions (LOAD and STORE) */
#define TYPE_DOUBLE 3 /* integer, long, float, double, address */
-#define TYPE_ADDRESS 4 /* all other types can be numbered arbitrarily*/
+#define TYPE_ADDRESS 4 /* all other types can be numbered arbitrarly */
#define TYPE_VOID 10
-/**************************** Java class file constants ***********************/
+/* Java class file constants **************************************************/
#define MAGIC 0xcafebabe
#define MINOR_VERSION 3
#define MAJOR_VERSION 45
-#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_Arraydescriptor 13
-#define CONSTANT_UNUSED 0
-
+#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_Arraydescriptor 13
+#define CONSTANT_UNUSED 0
#define ACC_PUBLIC 0x0001
#define ACC_PRIVATE 0x0002
#define ACC_ABSTRACT 0x0400
-
-/**************************** resolve typedef-cycles **************************/
+/* resolve typedef cycles *****************************************************/
typedef struct unicode unicode;
+typedef struct java_objectheader java_objectheader;
typedef struct classinfo classinfo;
typedef struct vftbl vftbl;
typedef u1* methodptr;
-/********************** data structures of UNICODE symbol *********************/
+/* constant pool entries *******************************************************
-struct unicode {
- unicode *hashlink; /* externe Verkettung f"ur die unicode-Hashtabelle */
- u4 key; /* Hash-Schl"ussel (h"angt nur vom Text ab) */
- int length; /* L"ange des Textes */
- u2 *text; /* Zeiger auf den Text (jeder Buchstabe 16 Bit) */
- classinfo *class; /* gegebenenfalls Referenz auf die Klasse dieses
- Namens (oder NULL, wenn es keine solche gibt) */
- struct java_objectheader *string;
- /* gegebenenfalls Referenz auf einen konstanten
- String mit dem entsprechenden Wert */
-};
+ All constant pool entries need a data structure which contain the entrys
+ value. In some cases this structure exist already, in the remaining cases
+ this structure must be generated:
-/* Alle Unicode-Symbole werden in einer einzigen globalen Tabelle
- (Hashtabelle) verwaltet, jedes Symbol wird nur einmal angelegt.
- -> Speicherersparnis, und "Uberpr"ufung auf Gleichheit durch einfachen
- Zeigervergleich */
+ kind structure generated?
+ ----------------------------------------------------------------------
+ CONSTANT_Class classinfo no
+ CONSTANT_Fieldref constant_FMIref yes
+ CONSTANT_Methodref constant_FMIref yes
+ CONSTANT_InterfaceMethodref constant_FMIref yes
+ CONSTANT_String unicode no
+ CONSTANT_Integer constant_integer yes
+ CONSTANT_Float constant_float yes
+ CONSTANT_Long constant_long yes
+ CONSTANT_Double constant_double yes
+ CONSTANT_NameAndType constant_nameandtype yes
+ CONSTANT_Utf8 unicode no
+ CONSTANT_Arraydescriptor constant_arraydescriptor yes
+ CONSTANT_UNUSED -
+*******************************************************************************/
-/************ data structures of remaining constant pool entries **************/
+/* data structures of Unicode symbol *******************************************
+ All Unicode symbols are stored in one global (hash) table, every symbol
+ exists only once. Equal symbols have identical pointers.
+*/
+
+struct unicode {
+ unicode *hashlink; /* link for external hash chain */
+ u4 key; /* hash key (computed from text) */
+ int length; /* text length */
+ u2 *text; /* pointer to text (each character is 16 Bit) */
+ classinfo *class; /* class pointer if it exists, otherwise NULL */
+ java_objectheader *string; /* string pointer if it exists, otherwise NULL*/
+};
-typedef struct {
- classinfo *class;
- unicode *name;
- unicode *descriptor;
-} constant_FMIref;
+/* data structures of remaining constant pool entries *************************/
-typedef struct {
+typedef struct { /* Fieldref, Methodref and InterfaceMethodref */
+ classinfo *class; /* class containing this field/method/interface */
+ unicode *name; /* field/method/interface name */
+ unicode *descriptor; /* field/method/interface type descriptor string */
+} constant_FMIref;
+
+typedef struct { /* Integer */
s4 value;
} constant_integer;
-typedef struct {
+typedef struct { /* Float */
float value;
} constant_float;
-typedef struct {
+typedef struct { /* Long */
s8 value;
} constant_long;
-typedef struct {
+typedef struct { /* Double */
double value;
} constant_double;
-
-typedef struct {
- unicode *name;
- unicode *descriptor;
+typedef struct { /* NameAndType (Field or Method) */
+ unicode *name; /* field/method name */
+ unicode *descriptor; /* field/method type descriptor string */
} constant_nameandtype;
+/* arraydescriptor describes array types. Basic array types contain their
+ type in the arraytype field, objectclass contains a class pointer for
+ arrays of objects (arraytype == ARRAYTYPE_OBJECT), elementdescriptor
+ contains a pointer to an arraydescriptor which describes the element
+ types in the case of arrays of arrays (arraytype == ARRAYTYPE_ARRAY).
+*/
typedef struct constant_arraydescriptor {
int arraytype;
struct constant_arraydescriptor *elementdescriptor;
} constant_arraydescriptor;
-/* Mit einem Arraydescriptor kann ein Array-Typ dargestellt werden.
- Bei normalen Arrays (z.B. Array von Bytes,...) gen"ugt dazu,
- dass das Feld arraytype die entsprechende Kennzahl enth"alt
- (z.B. ARRAYTYPE_BYTE).
- Bei Arrays von Objekten (arraytype=ARRAYTYPE_OBJECT) muss das
- Feld objectclass auf die Klassenstruktur der m"oglichen
- Element-Objekte zeigen.
- Bei Arrays von Arrays (arraytype=ARRAYTYPE_ARRAY) muss das
- Feld elementdescriptor auf eine weiter arraydescriptor-Struktur
- zeigen, die die Element-Typen beschreibt.
- */
-
-
-
-/********* Anmerkungen zum Constant-Pool:
-
- Die Typen der Eintr"age in den Constant-Pool werden durch die oben
- definierten CONSTANT_.. Werte angegeben.
- Bei allen Typen muss zus"atzlich noch eine Datenstruktur hinzugef"ugt
- werden, die den wirklichen Wert angibt.
- Bei manchen Typen reicht es, einen Verweis auf eine schon bereits
- existierende Struktur (z.B. unicode-Texte) einzutragen, bei anderen
- muss diese Struktur erst extra erzeugt werden.
- Ich habe folgende Datenstrukturen f"ur diese Typen verwendet:
-
- Typ Struktur extra erzeugt?
- ----------------------------------------------------------------------
- CONSTANT_Class classinfo nein
- CONSTANT_Fieldref constant_FMIref ja
- CONSTANT_Methodref constant_FMIref ja
- CONSTANT_InterfaceMethodref constant_FMIref ja
- CONSTANT_String unicode nein
- CONSTANT_Integer constant_integer ja
- CONSTANT_Float constant_float ja
- CONSTANT_Long constant_long ja
- CONSTANT_Double constant_double ja
- CONSTANT_NameAndType constant_nameandtype ja
- CONSTANT_Utf8 unicode nein
- CONSTANT_Arraydescriptor constant_arraydescriptor ja
- CONSTANT_UNUSED -
-
-*******************************/
-
+/* data structures of the runtime system **************************************/
-/***************** Die Datenstrukturen fuer das Laufzeitsystem ****************/
+/* objects *********************************************************************
+ All objects (and arrays) which resides on the heap need the following
+ header at the beginning of the data structure.
+*/
- /********* Objekte **********
-
- Alle Objekte (und Arrays), die am Heap gespeichert werden, m"ussen eine
- folgende spezielle Datenstruktur ganz vorne stehen haben:
-
- */
+struct java_objectheader { /* header for all objects */
+ vftbl *vftbl; /* pointer to virtual function table */
+};
-typedef struct java_objectheader { /* Der Header f"ur alle Objekte */
- vftbl *vftbl; /* Zeiger auf die Function Table */
-} java_objectheader;
+/* arrays **********************************************************************
-/********* Arrays ***********
-
- Alle Arrays in Java sind auch gleichzeitig Objekte (d.h. sie haben auch
- den obligatorischen Object-Header und darin einen Verweis auf eine Klasse)
- Es gibt aber (der Einfachheit halber) nur eine einzige Klasse f"ur alle
- m"oglichen Typen von Arrays, deshalb wird der tats"achliche Typ in einem
- Feld im Array-Objekt selbst gespeichert.
- Die Typen sind: */
+ All arrays are objects (they need the object header with a pointer to a
+ vvftbl (array class table). There is only one class for all arrays. The
+ type of an array is stored directly in the array object. Following types
+ are defined:
+*/
#define ARRAYTYPE_INT 0
#define ARRAYTYPE_LONG 1
#define ARRAYTYPE_OBJECT 8
#define ARRAYTYPE_ARRAY 9
-
-/** Der Header f"ur ein Java-Array **/
-
-typedef struct java_arrayheader { /* Der Arrayheader f"ur alle Arrays */
- java_objectheader objheader; /* Der Object-Header */
- s4 size; /* Gr"osse des Arrays */
- s4 arraytype; /* Typ der Elemente */
+typedef struct java_arrayheader { /* header for all arrays */
+ java_objectheader objheader; /* object header */
+ s4 size; /* array size */
+ s4 arraytype; /* array type from previous list */
} java_arrayheader;
-/** Die Unterschiedlichen Strukturen f"ur alle Typen von Arrays **/
+/* structs for all kinds of arrays ********************************************/
typedef struct java_chararray {
java_arrayheader header;
double data[1];
} java_doublearray;
-
-/* achtung: die beiden Stukturen booleanarray und bytearray m"ussen
- identisches memory-layout haben, weil mit den selben Funktionen
- darauf zugegriffen wird */
+/* booleanarray and bytearray need identical memory layout (access methods
+ use the same machine code */
typedef struct java_booleanarray {
java_arrayheader header;
s8 data[1];
} java_longarray;
-
-/* ACHTUNG: die beiden folgenden Strukturen m"ussen unbedingt gleiches
- Memory-Layout haben, weil mit ein und der selben Funktion auf die
- data-Eintr"age beider Typen zugegriffen wird !!!! */
+/* objectarray and arrayarray need identical memory layout (access methods
+ use the same machine code */
typedef struct java_objectarray {
java_arrayheader header;
} java_arrayarray;
+/* field, method and class structures *****************************************/
-
-/******************** class, field and method structures **********************/
-
-
-/********************** structure: fieldinfo **********************************/
+/* fieldinfo ******************************************************************/
typedef struct fieldinfo {/* field of a class */
s4 flags; /* ACC flags */
} fieldinfo;
-/********************** structure: exceptiontable *****************************/
+/* exceptiontable *************************************************************/
typedef struct exceptiontable { /* exceptiontable entry in a method */
s4 startpc; /* start pc of guarded area (inclusive) */
} exceptiontable;
-/********************** structure: methodinfo *********************************/
+/* methodinfo *****************************************************************/
typedef struct methodinfo { /* method structure */
s4 flags; /* ACC flags */
s4 paramcount; /* only temporary valid, parameter count */
u1 *paramtypes; /* only temporary valid, parameter types */
classinfo *class; /* class, the method belongs to */
- u4 vftblindex; /* index of method in virtual function table
+ s4 vftblindex; /* index of method in virtual function table
(if it is a virtual method) */
s4 maxstack; /* maximum stack depth of method */
s4 maxlocals; /* maximum number of local variables */
- u4 jcodelength; /* length of JavaVM code */
+ s4 jcodelength; /* length of JavaVM code */
u1 *jcode; /* pointer to JavaVM code */
s4 exceptiontablelength;/* exceptiontable length */
exceptiontable *exceptiontable; /* the exceptiontable */
u1 *stubroutine; /* stub for compiling or calling natives */
- u4 mcodelength; /* legth of generated machine code */
+ s4 mcodelength; /* legth of generated machine code */
u1 *mcode; /* pointer to machine code */
u1 *entrypoint; /* entry point in machine code */
} methodinfo;
-/********************** structure: classinfo **********************************/
+/* classinfo ******************************************************************/
struct classinfo { /* class structure */
java_objectheader header; /* classes are also objects */
methodinfo *marker;
#endif
};
+
+
+/* virtual function table ******************************************************
+
+ The vtbl has a bidirectional layout with open ends at both sides.
+ interfacetablelength gives the number of entries of the interface table at
+ the start of the vftbl. The vftbl pointer points to &interfacetable[0].
+ vftbllength gives the number of entries of table at the end of the vftbl.
+
+ runtime type check (checkcast):
+
+ Different methods are used for runtime type check depending on the
+ argument of checkcast/instanceof.
+ A check against a class is implemented via relative numbering on the class
+ hierachy tree. The tree is numbered in a depth first traversal setting
+ the base field and the diff field. The diff field gets the result of
+ (high - base) so that a range check can be implemented by an unsigned
+ compare. A sub type test is done by checking the inclusion of base of
+ the sub class in the range of the superclass.
+
+ A check against an interface is implemented via the interfacevftbl. If the
+ interfacevftbl contains a nonnull value a class is a subclass of this
+ interface.
+
+ interfacetable:
+
+ Like standard virtual methods interface methods are called using
+ virtual function tables. All interfaces are numbered sequentially
+ (starting with zero). For each class there exist an interface table
+ of virtual function tables for each implemented interface. The length
+ of the interface table is determined by the highest number of an
+ implemented interface.
+
+ The following example assumes a class which implements interface 0 and 3:
+
+ interfacetablelength = 4
+
+ | ... | +----------+
+ +-----------+ | method 2 |---> method z
+ | class | | method 1 |---> method y
+ +-----------+ | method 0 |---> method x
+ | ivftbl 0 |----------> +----------+
+ vftblptr ---> +-----------+
+ | ivftbl -1 |--> NULL +----------+
+ | ivftbl -2 |--> NULL | method 1 |---> method x
+ | ivftbl -3 |-----+ | method 0 |---> method a
+ +-----------+ +----> +----------+
+
+ +---------------+
+ | length 3 = 2 |
+ | length 2 = 0 |
+ | length 1 = 0 |
+ | length 0 = 3 |
+ interfacevftbllength ---> +---------------+
+
+*******************************************************************************/
struct vftbl {
- classinfo *class; /* Class, the function table belongs to */
+ methodptr *interfacetable[1]; /* interface table (access via macro) */
+
+ classinfo *class; /* class, the vtbl belongs to */
- s4 vftbllength; /* virtual function table length */
- s4 interfacetablelength; /* interface table length */
+ s4 vftbllength; /* virtual function table length */
+ s4 interfacetablelength; /* interface table length */
- s4 lowclassval; /* low value for relative numbering */
- s4 highclassval; /* high value for relative numbering */
+ s4 baseval; /* base for runtime type check */
+ s4 diffval; /* high - base for runtime type check */
- u4 *interfacevftbllength; /* see description below */
- methodptr **interfacevftbl;
+ s4 *interfacevftbllength; /* length of interface vftbls */
- methodptr table[1];
+ methodptr table[1]; /* class vftbl */
};
-/*********** Anmerkungen zur Interfacetable:
-
- "Ahnlich wie die 'normalen' virtuellen Methoden k"onnen auch die
- Interface-Methoden mit Hilfe einer Art Virtual Function Table
- aufgerufen werden.
- Dazu werden alle Interfaces im System fortlaufend nummeriert (beginnend
- bei 0), und f"ur jede Klasse wird eine ganze Tabelle von
- Virtual Function Tables erzeugt, n"amlich zu jedem Interface, das die
- Klasse implementiert, eine.
-
- z.B. Nehmen wir an, eine Klasse implementiert zwei Interfaces (die durch
- die Nummerierung die Indizes 0 und 3 bekommen haben)
-
- Das sieht dann ungef"ahr so aus:
- -------------- -------------
- interfacevftbl ---> | Eintrag 0 |---------> | Methode 0 |---> Methode X
- | Eintrag 1 |--> NULL | Methode 1 |---> Methode Y
- | Eintrag 2 |--> NULL | Methode 2 |---> Methode Z
- | Eintrag 3 |-----+ -------------
- -------------- |
- +---> -------------
- | Methode 0 |---> Methode X
- | Methode 1 |---> Methode A
- -------------
- ---------------
- interfacevftlblength ---> | Wert 0 = 3 |
- | Wert 1 = 0 |
- | Wert 2 = 0 |
- | Wert 3 = 2 |
- ---------------
-
- Der Aufruf einer Interface-Methode geht dann so vor sich:
- Zur Compilezeit steht der Index (i) des Interfaces und die Stelle (s), wo
- in der entsprechenden Untertabelle die Methode eingetragen ist, schon fest.
- Also muss zur Laufzeit nur mehr der n-te Eintrag aus der Interfacetable
- gelesen werden, von dieser Tabelle aus wird der s-te Eintrag geholt,
- und diese Methode wird angesprungen.
-
-****************/
-
-
-
-/********************** references to some system classes ********************/
+#define VFTBLINTERFACETABLE(v,i) (v)->interfacetable[-i]
+
+
+/* references to some system classes ******************************************/
extern classinfo *class_java_lang_Object;
extern classinfo *class_java_lang_String;
extern classinfo *class_array;
-/********************** instances of some system classes **********************/
+/* instances of some system classes *******************************************/
extern java_objectheader *proto_java_lang_ClassCastException;
extern java_objectheader *proto_java_lang_NullPointerException;
extern java_objectheader *proto_java_lang_ThreadDeath;
-/******************************* flag variables *******************************/
+/* flag variables *************************************************************/
extern bool compileall;
extern bool runverbose;
extern bool verbose;
-/******************************* trace variables ******************************/
+/* statistic variables ********************************************************/
extern int count_class_infos;
extern int count_const_pool_len;
void asm_calljavamethod () { }
void asm_dumpregistersandcall () { }
-s4 new_builtin_idiv (s4 a, s4 b) {return 0;}
-s4 new_builtin_irem (s4 a, s4 b) {return 0;}
-s8 new_builtin_ldiv (s8 a, s8 b) {return 0;}
-s8 new_builtin_lrem (s8 a, s8 b) {return 0;}
-
-
-void new_builtin_monitorenter (java_objectheader *o) {}
-void new_builtin_monitorexit (java_objectheader *o) {}
-
-s4 new_builtin_checkcast(java_objectheader *o, classinfo *c)
- {return 0;}
-s4 new_builtin_checkclasscast(java_objectheader *o, classinfo *c)
- {return 0;}
-s4 new_builtin_checkintercast(java_objectheader *o, classinfo *c)
- {return 0;}
-s4 new_builtin_checkarraycast
+s4 asm_builtin_idiv (s4 a, s4 b) {return 0;}
+s4 asm_builtin_irem (s4 a, s4 b) {return 0;}
+s8 asm_builtin_ldiv (s8 a, s8 b) {return 0;}
+s8 asm_builtin_lrem (s8 a, s8 b) {return 0;}
+
+
+void asm_builtin_monitorenter (java_objectheader *o) {}
+void asm_builtin_monitorexit (java_objectheader *o) {}
+
+s4 asm_builtin_checkarraycast
(java_objectheader *o, constant_arraydescriptor *d)
{return 0;}
-void new_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {}
+void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {}
u1 *createcompilerstub (methodinfo *m) {return NULL;}
u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;}
log_init (NULL);
log_text ("Java - header-generator started");
+ file = fopen("sysdep/offsets.h", "w");
+ if (file == NULL)
+ panic ("Can not open file 'sysdep/offsets.h' for write");
+
+ fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n");
+
+ fprintf (file, "#define offobjvftbl %3d\n", (int) OFFSET(java_objectheader, vftbl));
+ fprintf (file, "#define offarraysize %3d\n", (int) OFFSET(java_arrayheader, size));
+ fprintf (file, "#define offobjarrdata %3d\n\n", (int) OFFSET(java_objectarray, data[0]));
+ fprintf (file, "#define offbaseval %3d\n", (int) OFFSET(vftbl, baseval));
+ fprintf (file, "#define offdiffval %3d\n", (int) OFFSET(vftbl, diffval));
+
+ fclose (file);
suck_init (classpath);
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/****************************** loader.c ***************************************
+/* loader.c ********************************************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
#include "threads/thread.h" /* schani */
-/*************************** globale Variablen *******************************/
+/* global variables ***********************************************************/
-extern bool newcompiler;
+extern bool newcompiler; /* true if new compiler is used */
-int count_class_infos = 0;
+int count_class_infos = 0; /* variables for measurements */
int count_const_pool_len = 0;
int count_vftbl_len = 0;
int count_all_methods = 0;
int count_vmcode_len = 0;
int count_extable_len = 0;
-bool loadverbose = false; /* Switches f"ur mehr Debug-Meldungen */
+bool loadverbose = false; /* switches for debug messages */
bool linkverbose = false;
bool initverbose = false;
long int loadingtime = 0;
-static u4 interfaceindex; /* fortlaufende Nummer f"ur Interfaces */
+static s4 interfaceindex; /* sequential numbering of interfaces */
-static list unloadedclasses; /* Liste alle referenzierten, aber noch nicht
- geladenen Klassen */
-static list unlinkedclasses; /* Liste aller geladenen, aber noch nicht
- gelinkten Klassen */
- list linkedclasses; /* Liste aller fertig gelinkten Klassen */
+static list unloadedclasses; /* list of all referenced but not loaded classes */
+static list unlinkedclasses; /* list of all loaded but not linked classes */
+ list linkedclasses; /* list of all completely linked classes */
-/***************** die Referenzen auf die wichtigen Systemklassen ************/
+/* important system classes ***************************************************/
classinfo *class_java_lang_Object;
classinfo *class_java_lang_String;
classinfo *class_array;
-/************ einige vorgefertigte Instanzen wichtiger Systemklassen *********/
+/* instances of important system classes **************************************/
java_objectheader *proto_java_lang_ClassCastException;
java_objectheader *proto_java_lang_NullPointerException;
-/****************************************************************************/
-/******************* Einige Support-Funkionen *******************************/
-/****************************************************************************/
+/******************************************************************************/
+/******************* Einige Support-Funkionen *********************************/
+/******************************************************************************/
-/********** interne Funktion: printflags (nur zu Debug-Zwecken) ************/
+/********** interne Funktion: printflags (nur zu Debug-Zwecken) **************/
static void printflags (u2 f)
{
}
-/************************* Funktion: skipattribute ****************************
+/************************* Funktion: skipattribute *****************************
"uberliest im ClassFile eine (1) 'attribute'-Struktur
-******************************************************************************/
+*******************************************************************************/
static void skipattribute ()
{
- u4 len;
-
suck_u2 ();
- len = suck_u4 ();
- skip_nbytes (len);
+ skip_nbytes(suck_u4());
}
-/********************** Funktion: skipattributebody ***************************
+/********************** Funktion: skipattributebody ****************************
"uberliest im Classfile ein attribut, wobei die 16-bit - attribute_name -
Referenz schon gelesen worden ist.
-******************************************************************************/
+*******************************************************************************/
static void skipattributebody ()
{
- u4 len = suck_u4 ();
- skip_nbytes (len);
+ skip_nbytes(suck_u4());
}
-/************************* Funktion: skipattributes ***************************
+/************************* Funktion: skipattributes ****************************
"uberliest im ClassFile eine gew"unschte Anzahl von attribute-Strukturen
-******************************************************************************/
+*******************************************************************************/
static void skipattributes (u4 num)
{
u4 i;
- for (i=0; i<num; i++) skipattribute();
+ for (i = 0; i < num; i++)
+ skipattribute();
}
-/************************** Funktion: loadUtf8 ********************************
+/************************** Funktion: loadUtf8 *********************************
liest aus dem ClassFile einen Utf8-String (=komprimierter unicode-text)
und legt daf"ur ein unicode-Symbol an.
Return: Zeiger auf das Symbol
-******************************************************************************/
+*******************************************************************************/
#define MAXUNICODELEN 5000
static u2 unicodebuffer[MAXUNICODELEN];
-/******************** interne Funktion: checkfieldtype ***********************/
+/******************** interne Funktion: checkfieldtype ************************/
static void checkfieldtype (u2 *text, u4 *count, u4 length)
{
}
-/******************* Funktion: checkfielddescriptor ***************************
+/******************* Funktion: checkfielddescriptor ****************************
"uberpr"uft, ob ein Field-Descriptor ein g"ultiges Format hat.
Wenn nicht, dann wird das System angehalten.
Au"serdem werden alle Klassen, die hier referenziert werden,
in die Liste zu ladender Klassen eingetragen.
-******************************************************************************/
+*******************************************************************************/
void checkfielddescriptor (unicode *d)
{
}
-/******************* Funktion: checkmethoddescriptor **************************
+/******************* Funktion: checkmethoddescriptor ***************************
"uberpr"uft, ob ein Method-Descriptor ein g"ultiges Format hat.
Wenn nicht, dann wird das System angehalten.
Au"serdem werden alle Klassen, die hier referenziert werden,
in die Liste zu ladender Klassen eingetragen.
-******************************************************************************/
+*******************************************************************************/
void checkmethoddescriptor (unicode *d)
{
}
-/******************** Funktion: buildarraydescriptor ****************************
+/******************** Funktion: buildarraydescriptor ***************************
erzeugt zu einem namentlich als u2-String vorliegenden Arraytyp eine
entsprechende constant_arraydescriptor - Struktur
-********************************************************************************/
+*******************************************************************************/
static constant_arraydescriptor * buildarraydescriptor(u2 *name, u4 namelen)
{
}
-/******************* Funktion: freearraydescriptor ****************************
+/******************* Funktion: freearraydescriptor *****************************
entfernt eine mit buildarraydescriptor erzeugte Struktur wieder
aus dem Speicher
-/*****************************************************************************/
-/******************** Funktionen fuer Fields *********************************/
-/*****************************************************************************/
+/******************************************************************************/
+/******************** Funktionen fuer Fields **********************************/
+/******************************************************************************/
-/************************ Funktion: field_load ********************************
+/************************ Funktion: field_load *********************************
l"adt alle Informationen f"ur eine Feld einer Methode aus dem ClassFile,
und f"ullt mit diesen Infos eine schon existierende 'fieldinfo'-Struktur.
Bei 'static'-Fields wird auch noch ein Platz auf dem Datensegment
reserviert.
-******************************************************************************/
+*******************************************************************************/
static void field_load (fieldinfo *f, classinfo *c)
{
}
-/********************** Funktion: field_free *********************************/
+/********************** Funktion: field_free **********************************/
static void field_free (fieldinfo *f)
{
}
-/************** Funktion: field_display (nur zu Debug-Zwecken) ***************/
+/************** Funktion: field_display (nur zu Debug-Zwecken) ****************/
static void field_display (fieldinfo *f)
{
-/*****************************************************************************/
-/************************* Funktionen f"ur Methods ***************************/
-/*****************************************************************************/
+/******************************************************************************/
+/************************* Funktionen f"ur Methods ****************************/
+/******************************************************************************/
-/*********************** Funktion: method_load ********************************
+/*********************** Funktion: method_load *********************************
l"adt die Infos f"ur eine Methode aus dem ClassFile und f"ullt damit
eine schon existierende 'methodinfo'-Struktur aus.
Funktionszeiger eingetragen, bei JavaVM-Methoden einstweilen ein
Zeiger auf den Compiler
-******************************************************************************/
+*******************************************************************************/
static void method_load (methodinfo *m, classinfo *c)
{
}
-/********************* Funktion: method_free **********************************
+/********************* Funktion: method_free ***********************************
gibt allen Speicher, der extra f"ur eine Methode angefordert wurde,
wieder frei
-******************************************************************************/
+*******************************************************************************/
static void method_free (methodinfo *m)
{
}
-/************** Funktion: method_display (nur zu Debug-Zwecken) *************/
+/************** Funktion: method_display (nur zu Debug-Zwecken) **************/
void method_display (methodinfo *m)
{
}
-/******************** Funktion: method_canoverwrite ***************************
+/******************** Funktion: method_canoverwrite ****************************
"uberpr"ft, ob eine Methode mit einer anderen typ- und namensidentisch
ist (also mit einer Methodendefinition eine andere "uberschrieben
werden kann).
-******************************************************************************/
+*******************************************************************************/
static bool method_canoverwrite (methodinfo *m, methodinfo *old)
{
-/*****************************************************************************/
-/************************ Funktionen fuer Class ******************************/
-/*****************************************************************************/
+/******************************************************************************/
+/************************ Funktionen fuer Class *******************************/
+/******************************************************************************/
-/******************** Funktion: class_get *************************************
+/******************** Funktion: class_get **************************************
Sucht im System die Klasse mit dem gew"unschten Namen, oder erzeugt
eine neue 'classinfo'-Struktur (und h"angt sie in die Liste der zu
ladenen Klassen ein).
-******************************************************************************/
+*******************************************************************************/
classinfo *class_get (unicode *u)
{
c -> linked = false;
c -> index = 0;
c -> instancesize = 0;
+ c -> header.vftbl = NULL;
c -> vftbl = NULL;
c -> initialized = false;
-/******************** Funktion: class_getconstant *****************************
+/******************** Funktion: class_getconstant ******************************
holt aus dem ConstantPool einer Klasse den Wert an der Stelle 'pos'.
Der Wert mu"s vom Typ 'ctype' sein, sonst wird das System angehalten.
-******************************************************************************/
+*******************************************************************************/
voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype)
{
}
-/********************* Funktion: class_constanttype ***************************
+/********************* Funktion: class_constanttype ****************************
Findet heraus, welchen Typ ein Eintrag in den ConstantPool einer
Klasse hat.
-******************************************************************************/
+*******************************************************************************/
u4 class_constanttype (classinfo *c, u4 pos)
{
}
-/******************** Funktion: class_loadcpool *******************************
+/******************** Funktion: class_loadcpool ********************************
l"adt den gesammten ConstantPool einer Klasse.
Format gebracht (Klassenreferenzen werden aufgel"ost, ...)
F"ur eine genaue "Ubersicht "uber das kompakte Format siehe: 'global.h'
-******************************************************************************/
+*******************************************************************************/
static void class_loadcpool (classinfo *c)
{
}
-/********************** Funktion: class_load **********************************
+/********************** Funktion: class_load ***********************************
l"adt alle Infos f"ur eine ganze Klasse aus einem ClassFile. Die
'classinfo'-Struktur mu"s bereits angelegt worden sein.
Die gelesene Klasse wird dann aus der Liste 'unloadedclasses' ausgetragen
und in die Liste 'unlinkedclasses' eingh"angt.
-******************************************************************************/
+*******************************************************************************/
static void class_load (classinfo *c)
{
-/************** interne Funktion: class_highestinterface **********************
+/************** interne Funktion: class_highestinterface ***********************
wird von der Funktion class_link ben"otigt, um festzustellen, wie gro"s
die Interfacetable einer Klasse sein mu"s.
-******************************************************************************/
+*******************************************************************************/
static s4 class_highestinterface (classinfo *c)
{
}
-/**************** Funktion: class_addinterface ********************************
+/* class_addinterface **********************************************************
wird von der Funktion class_link ben"otigt, um eine Virtual Function
Table f"ur ein Interface (und alle weiteren von diesem Interface
implementierten Interfaces) in eine Klasse einzutragen.
-******************************************************************************/
+*******************************************************************************/
static void class_addinterface (classinfo *c, classinfo *ic)
{
- u4 i = ic->index;
- u4 j,m;
+ s4 j, m;
+ s4 i = ic->index;
vftbl *vftbl = c->vftbl;
- if (i>=vftbl->interfacetablelength) panic ("Interfacetable-Overflow");
- if (vftbl->interfacevftbl[i]) return;
+ if (i >= vftbl->interfacetablelength)
+ panic ("Inernal error: interfacetable overflow");
+ if (vftbl->interfacetable[-i])
+ return;
- if (ic->methodscount==0) { /* wenn interface keine Methoden hat, dann
- trotzdem eine Tabelle mit L"ange 1 anlegen,
- wegen Subclass-Tests */
- vftbl -> interfacevftbllength[i] = 1;
- vftbl -> interfacevftbl[i] = MNEW(methodptr, 1);
- vftbl -> interfacevftbl[i][0] = NULL;
+ if (ic->methodscount == 0) { /* fake entry needed for subtype test */
+ vftbl->interfacevftbllength[i] = 1;
+ vftbl->interfacetable[-i] = MNEW(methodptr, 1);
+ vftbl->interfacetable[-i][0] = NULL;
}
else {
- vftbl -> interfacevftbllength[i] = ic -> methodscount;
- vftbl -> interfacevftbl[i] = MNEW(methodptr, ic -> methodscount);
+ vftbl->interfacevftbllength[i] = ic->methodscount;
+ vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
#ifdef STATISTICS
- count_vftbl_len += sizeof(methodptr) * ic -> methodscount;
+ count_vftbl_len += sizeof(methodptr) *
+ (ic->methodscount + (ic->methodscount == 0));
#endif
for (j=0; j<ic->methodscount; j++) {
classinfo *sc = c;
while (sc) {
- for (m=0; m<sc->methodscount; m++) {
+ for (m = 0; m < sc->methodscount; m++) {
methodinfo *mi = &(sc->methods[m]);
- if (method_canoverwrite (mi, &(ic->methods[j])) ) {
- vftbl->interfacevftbl[i][j] =
- vftbl->table[mi->vftblindex];
+ if (method_canoverwrite(mi, &(ic->methods[j]))) {
+ vftbl->interfacetable[-i][j] =
+ vftbl->table[mi->vftblindex];
goto foundmethod;
}
}
foundmethod: ;
}
}
-
- for (j=0; j<ic->interfacescount; j++)
+
+ for (j = 0; j < ic->interfacescount; j++)
class_addinterface(c, ic->interfaces[j]);
}
-/********************** Funktion: class_link **********************************
+/********************** Funktion: class_link ***********************************
versucht, eine Klasse in das System voll zu integrieren (linken). Dazu
m"ussen sowol die Superklasse, als auch alle implementierten
Achtung: Bei zyklischen Klassendefinitionen ger"at das Programm hier in
eine Endlosschleife!! (Da muss ich mir noch was einfallen lassen)
-******************************************************************************/
+*******************************************************************************/
static void class_link (classinfo *c)
{
- u4 supervftbllength; /* L"ange der VFTBL der Superklasse */
- u4 vftbllength; /* L"ange der VFTBL dieser Klasse */
- classinfo *super = c->super;
- classinfo *ic,*c2; /* Hilfsvariablen */
- vftbl *v;
- u4 i;
+ s4 supervftbllength; /* vftbllegnth of super class */
+ s4 vftbllength; /* vftbllength of current class */
+ s4 interfacetablelength; /* interface table length */
+ classinfo *super = c->super; /* super class */
+ classinfo *ic, *c2; /* intermediate class variables */
+ vftbl *v; /* vftbl of current class */
+ s4 i; /* interface/method/field counter */
- /* schauen, ob alle "ubergeordneten Klassen schon fertig sind,
- und richtiges Initialisieren der lokalen Variablen */
+ /* check if all superclasses are already linked, if not put c at end of
+ unlinked list and return. Additionally initialize class fields. */
- for ( i=0; i<c->interfacescount; i++) {
+ /* check interfaces */
+
+ for (i = 0; i < c->interfacescount; i++) {
ic = c->interfaces[i];
- if ( !ic -> linked) {
- list_remove (&unlinkedclasses,c );
- list_addlast (&unlinkedclasses,c );
+ if (!ic->linked) {
+ list_remove(&unlinkedclasses, c);
+ list_addlast(&unlinkedclasses, c);
return;
}
}
- if (! super) {
- c -> index = 0;
- c -> instancesize = sizeof (java_objectheader);
+ /* check super class */
+
+ if (super == NULL) { /* class java.long.Object */
+ c->index = 0;
+ c->instancesize = sizeof(java_objectheader);
vftbllength = supervftbllength = 0;
- c -> finalizer = NULL;
+ c->finalizer = NULL;
}
else {
- if ( !super -> linked ) {
- list_remove (&unlinkedclasses,c );
- list_addlast (&unlinkedclasses,c );
+ if (!super->linked) {
+ list_remove(&unlinkedclasses, c);
+ list_addlast(&unlinkedclasses, c);
return;
}
- if ( c->flags & ACC_INTERFACE) c -> index = interfaceindex++;
- else c -> index = super -> index + 1;
+ if (c->flags & ACC_INTERFACE)
+ c->index = interfaceindex++;
+ else
+ c->index = super->index + 1;
- c -> instancesize = super -> instancesize;
+ c->instancesize = super->instancesize;
- vftbllength = supervftbllength = super -> vftbl -> vftbllength;
+ vftbllength = supervftbllength = super->vftbl->vftbllength;
- c -> finalizer = super -> finalizer;
+ c->finalizer = super->finalizer;
}
dolog ();
}
- /* Erstellen der Virtual Function Table */
+ /* compute vftbl length */
- for (i=0; i < c->methodscount; i++) {
+ for (i = 0; i < c->methodscount; i++) {
methodinfo *m = &(c->methods[i]);
- if (! (m->flags & ACC_STATIC) ) {
+ if (!(m->flags & ACC_STATIC)) { /* is instance method */
classinfo *sc = super;
while (sc) {
int j;
- for (j=0; j < sc->methodscount; j++) {
- if ( method_canoverwrite (m, &(sc->methods[j])) ) {
- m -> vftblindex = sc->methods[j].vftblindex;
+ for (j = 0; j < sc->methodscount; j++) {
+ if (method_canoverwrite(m, &(sc->methods[j]))) {
+ m->vftblindex = sc->methods[j].vftblindex;
goto foundvftblindex;
}
}
sc = sc->super;
}
- m -> vftblindex = (vftbllength++);
- foundvftblindex: ;
+ m->vftblindex = (vftbllength++);
+foundvftblindex: ;
}
}
count_vftbl_len += sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1);
#endif
- c -> vftbl = v = (vftbl*)
- mem_alloc (sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1));
- v -> class = c;
- v -> vftbllength = vftbllength;
- v -> interfacetablelength = 0;
-
- for (i=0; i < supervftbllength; i++)
- v -> table[i] = super -> vftbl -> table[i];
+ /* compute interfacetable length */
+
+ interfacetablelength = 0;
+ c2 = c;
+ while (c2) {
+ for (i = 0; i < c2->interfacescount; i++) {
+ s4 h = class_highestinterface (c2->interfaces[i]) + 1;
+ if (h > interfacetablelength)
+ interfacetablelength = h;
+ }
+ c2 = c2->super;
+ }
+
+ /* allocate virtual function table */
+
+ v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) *
+ (vftbllength - 1) + sizeof(methodptr*) *
+ (interfacetablelength - (interfacetablelength > 0)));
+ v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) *
+ (interfacetablelength > 1));
+ c->header.vftbl = c->vftbl = v;
+ v->class = c;
+ v->vftbllength = vftbllength;
+ v->interfacetablelength = interfacetablelength;
+
+ /* copy virtual function table of super class */
+
+ for (i = 0; i < supervftbllength; i++)
+ v->table[i] = super->vftbl->table[i];
- for (i=0; i < c->methodscount; i++) {
+ /* add method stubs into virtual function table */
+
+ for (i = 0; i < c->methodscount; i++) {
methodinfo *m = &(c->methods[i]);
- if ( ! (m->flags & ACC_STATIC) ) {
- v -> table[m->vftblindex] = m -> stubroutine;
+ if (!(m->flags & ACC_STATIC)) {
+ v->table[m->vftblindex] = m->stubroutine;
}
}
-
- /* Berechnen der Instanzengr"o"se und der Offsets der einzelnen
- Felder */
+ /* compute instance size and offset of each field */
- for (i=0; i < c->fieldscount; i++) {
- u4 dsize;
- fieldinfo *f = &(c -> fields[i]);
+ for (i = 0; i < c->fieldscount; i++) {
+ s4 dsize;
+ fieldinfo *f = &(c->fields[i]);
- if ( ! (f->flags & ACC_STATIC) ) {
+ if (!(f->flags & ACC_STATIC) ) {
dsize = desc_typesize (f->descriptor);
- c -> instancesize = ALIGN ( c->instancesize, dsize);
- f -> offset = c -> instancesize;
- c -> instancesize += dsize;
+ c->instancesize = ALIGN (c->instancesize, dsize);
+ f->offset = c->instancesize;
+ c->instancesize += dsize;
}
-
}
+ /* initialize interfacetable and interfacevftbllength */
- /* Berechnen der Virtual Function Tables f"ur alle Interfaces */
-
- c2 = c;
- while (c2) {
- for (i=0; i<c2->interfacescount; i++) {
- s4 h = class_highestinterface (c2->interfaces[i]) + 1;
- if ( h > v->interfacetablelength) v->interfacetablelength = h;
- }
- c2 = c2->super;
- }
- v -> interfacevftbllength = MNEW (u4, v->interfacetablelength);
- v -> interfacevftbl = MNEW (methodptr *, v->interfacetablelength);
+ v->interfacevftbllength = MNEW (s4, interfacetablelength);
#ifdef STATISTICS
- count_vftbl_len += (4 + sizeof(methodptr*)) * v->interfacetablelength;
+ count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
#endif
- for (i=0; i < v->interfacetablelength; i++) {
- v -> interfacevftbllength[i] = 0;
- v -> interfacevftbl[i] = NULL;
+ for (i = 0; i < interfacetablelength; i++) {
+ v->interfacevftbllength[i] = 0;
+ v->interfacetable[-i] = NULL;
}
- c2 = c;
- while (c2) {
- for (i=0; i<c2->interfacescount; i++) {
+ /* add interfaces */
+
+ for (c2 = c; c2 != NULL; c2 = c2->super)
+ for (i = 0; i < c2->interfacescount; i++) {
class_addinterface (c, c2->interfaces[i]);
}
- c2 = c2->super;
- }
-
-
- /* Die finalizer-Methode suchen und eintragen (wenn vorhanden),
- aber nur bei Objekten ausser java.lang.Object */
+ /* add finalizer method (not for java.lang.Object) */
- if (super) {
+ if (super != NULL) {
methodinfo *fi;
- static unicode *finame=NULL,*fidesc=NULL;
-
- if (!finame) finame = unicode_new_char ("finalize");
- if (!fidesc) fidesc = unicode_new_char ("()V");
+ static unicode *finame = NULL;
+ static unicode *fidesc = NULL;
+
+ if (finame == NULL)
+ finame = unicode_new_char("finalize");
+ if (fidesc == NULL)
+ fidesc = unicode_new_char("()V");
fi = class_findmethod (c, finame, fidesc);
- if (fi) {
- if (! (fi->flags & ACC_STATIC) ) {
- c -> finalizer = fi;
+ if (fi != NULL) {
+ if (!(fi->flags & ACC_STATIC)) {
+ c->finalizer = fi;
}
}
- }
-
-
- /* Abschlie"sende Aktionen */
-
- c -> linked = true;
+ }
+
+ /* final tasks */
+
+ c->linked = true;
list_remove (&unlinkedclasses, c);
list_addlast (&linkedclasses, c);
}
-/******************* Funktion: class_freepool *********************************
+/******************* Funktion: class_freepool **********************************
Gibt alle Resourcen, die der ConstantPool einer Klasse ben"otigt,
wieder frei.
-******************************************************************************/
+*******************************************************************************/
static void class_freecpool (classinfo *c)
{
}
-/*********************** Funktion: class_free *********************************
+/*********************** Funktion: class_free **********************************
Gibt alle Resourcen, die eine ganze Klasse ben"otigt, frei
-******************************************************************************/
+*******************************************************************************/
static void class_free (classinfo *c)
{
- u4 i;
+ s4 i;
vftbl *v;
unicode_unlinkclass (c->name);
MFREE (c->interfaces, classinfo*, c->interfacescount);
- for (i=0; i < c->fieldscount; i++) field_free ( &(c->fields[i]) );
+ for (i = 0; i < c->fieldscount; i++)
+ field_free(&(c->fields[i]));
MFREE (c->fields, fieldinfo, c->fieldscount);
- for (i=0; i < c->methodscount; i++) method_free ( &(c->methods[i]) );
+ for (i = 0; i < c->methodscount; i++)
+ method_free(&(c->methods[i]));
MFREE (c->methods, methodinfo, c->methodscount);
- if ( (v = c->vftbl) ) {
- for (i=0; i<v->interfacetablelength; i++) {
- MFREE (v->interfacevftbl[i], methodptr, v->interfacevftbllength[i]);
+ if ((v = c->vftbl) != NULL) {
+ for (i = 0; i < v->interfacetablelength; i++) {
+ MFREE (v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
}
- MFREE (v->interfacevftbllength, u4, v->interfacetablelength);
- MFREE (v->interfacevftbl, methodptr*, v->interfacetablelength);
-
- mem_free (v, sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1));
+ MFREE (v->interfacevftbllength, s4, v->interfacetablelength);
+
+ i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) +
+ sizeof(methodptr*) * (v->interfacetablelength -
+ (v->interfacetablelength > 0));
+ v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) *
+ (v->interfacetablelength > 1));
+ mem_free (v, i);
}
FREE (c, classinfo);
}
-/************************* Funktion: class_findfield *************************
+/************************* Funktion: class_findfield ***************************
sucht in einer 'classinfo'-Struktur nach einem Feld mit gew"unschtem
Namen und Typ.
-*****************************************************************************/
+*******************************************************************************/
fieldinfo *class_findfield (classinfo *c, unicode *name, unicode *desc)
{
- u4 i;
- for (i=0; i < c->fieldscount; i++) {
- if ( (c->fields[i].name == name) && (c->fields[i].descriptor == desc) )
+ s4 i;
+ for (i = 0; i < c->fieldscount; i++) {
+ if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
return &(c->fields[i]);
}
panic ("Can not find field given in CONSTANT_Fieldref");
}
-/************************* Funktion: class_findmethod *************************
+/************************* Funktion: class_findmethod **************************
sucht in einer 'classinfo'-Struktur nach einer Methode mit gew"unschtem
Namen und Typ.
Wenn als Typ NULL angegeben wird, dann ist der Typ egal.
-*****************************************************************************/
+*******************************************************************************/
methodinfo *class_findmethod (classinfo *c, unicode *name, unicode *desc)
{
- u4 i;
- for (i=0; i < c->methodscount; i++) {
- if ( (c->methods[i].name == name)
- && ( (desc == NULL)
- || (c->methods[i].descriptor == desc)
- )
- )
+ s4 i;
+ for (i = 0; i < c->methodscount; i++) {
+ if ((c->methods[i].name == name) && ((desc == NULL) ||
+ (c->methods[i].descriptor == desc)))
return &(c->methods[i]);
}
return NULL;
}
-/************************* Funktion: class_resolvemethod *************************
+/************************* Funktion: class_resolvemethod ***********************
sucht eine Klasse und alle Superklassen ab, um eine Methode zu finden.
-*****************************************************************************/
+*******************************************************************************/
methodinfo *class_resolvemethod (classinfo *c, unicode *name, unicode *desc)
-/************************* Funktion: class_issubclass ************************
+/************************* Funktion: class_issubclass **************************
"uberpr"uft, ob eine Klasse von einer anderen Klasse abgeleitet ist.
-*****************************************************************************/
+*******************************************************************************/
bool class_issubclass (classinfo *sub, classinfo *super)
{
-/****************** Initialisierungsfunktion f"ur eine Klasse ****************
+/****************** Initialisierungsfunktion f"ur eine Klasse ******************
In Java kann jede Klasse ein statische Initialisierungsfunktion haben.
Diese Funktion mu"s aufgerufen werden, BEVOR irgendwelche Methoden der
Klasse aufgerufen werden, oder auf statische Variablen zugegriffen
wird.
-******************************************************************************/
+*******************************************************************************/
#ifdef USE_THREADS
extern int blockInts;
-/********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) ********/
+/********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) *********/
void class_showconstantpool (classinfo *c)
{
-/********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) ************/
+/********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) *************/
void class_showmethods (classinfo *c)
{
- u4 i;
+ s4 i;
printf ("--------- Fields and Methods ----------------\n");
printf ("Flags: "); printflags (c->flags); printf ("\n");
-/*****************************************************************************/
-/******************* Funktionen fuer den Class-loader generell ***************/
-/*****************************************************************************/
+/******************************************************************************/
+/******************* Funktionen fuer den Class-loader generell ****************/
+/******************************************************************************/
-/********************* Funktion: loader_load **********************************
+/********************* Funktion: loader_load ***********************************
l"adt und linkt die ge"unschte Klasse und alle davon
referenzierten Klassen und Interfaces
Return: Einen Zeiger auf diese Klasse
-******************************************************************************/
+*******************************************************************************/
classinfo *loader_load (unicode *topname)
{
}
-/******************* interne Funktion: loader_createarrayclass ****************
+/******************* interne Funktion: loader_createarrayclass *****************
Erzeugt (und linkt) eine Klasse f"ur die Arrays.
-******************************************************************************/
+*******************************************************************************/
static classinfo *loader_createarrayclass ()
{
-/********************** Funktion: loader_init *********************************
+/********************** Funktion: loader_init **********************************
Initialisiert alle Listen und l"adt alle Klassen, die vom System
und vom Compiler direkt ben"otigt werden.
-******************************************************************************/
+*******************************************************************************/
void loader_init ()
{
initialisiert alle geladenen aber noch nicht initialisierten Klassen
-******************************************************************************/
+*******************************************************************************/
void loader_initclasses ()
{
{
classinfo *subs;
- c->vftbl->lowclassval = classvalue++;
+ c->vftbl->baseval = ++classvalue;
subs = c->sub;
while (subs != NULL) {
loader_compute_class_values(subs);
subs = subs->nextsub;
}
- c->vftbl->highclassval = classvalue++;
+ c->vftbl->diffval = classvalue - c->vftbl->baseval;
/*
{
int i;
for (i = 0; i < c->index; i++)
printf(" ");
- printf("%3d %3d ", (int) c->vftbl->lowclassval, (int) c->vftbl->highclassval);
+ printf("%3d %3d ", (int) c->vftbl->baseval, c->vftbl->diffval);
unicode_display(c->name);
printf("\n");
}
-/******************** Funktion: loader_close **********************************
+/******************** Funktion: loader_close ***********************************
gibt alle Resourcen wieder frei
-******************************************************************************/
+*******************************************************************************/
void loader_close ()
{
}
}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
void asm_calljavamethod () { }
void asm_dumpregistersandcall () { }
-s4 new_builtin_idiv (s4 a, s4 b) {return 0;}
-s4 new_builtin_irem (s4 a, s4 b) {return 0;}
-s8 new_builtin_ldiv (s8 a, s8 b) {return 0;}
-s8 new_builtin_lrem (s8 a, s8 b) {return 0;}
-
-
-void new_builtin_monitorenter (java_objectheader *o) {}
-void new_builtin_monitorexit (java_objectheader *o) {}
-
-s4 new_builtin_checkcast(java_objectheader *o, classinfo *c)
- {return 0;}
-s4 new_builtin_checkclasscast(java_objectheader *o, classinfo *c)
- {return 0;}
-s4 new_builtin_checkintercast(java_objectheader *o, classinfo *c)
- {return 0;}
-s4 new_builtin_checkarraycast
+s4 asm_builtin_idiv (s4 a, s4 b) {return 0;}
+s4 asm_builtin_irem (s4 a, s4 b) {return 0;}
+s8 asm_builtin_ldiv (s8 a, s8 b) {return 0;}
+s8 asm_builtin_lrem (s8 a, s8 b) {return 0;}
+
+
+void asm_builtin_monitorenter (java_objectheader *o) {}
+void asm_builtin_monitorexit (java_objectheader *o) {}
+
+s4 asm_builtin_checkarraycast
(java_objectheader *o, constant_arraydescriptor *d)
{return 0;}
-void new_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {}
+void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {}
u1 *createcompilerstub (methodinfo *m) {return NULL;}
u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;}
log_init (NULL);
log_text ("Java - header-generator started");
+ file = fopen("sysdep/offsets.h", "w");
+ if (file == NULL)
+ panic ("Can not open file 'sysdep/offsets.h' for write");
+
+ fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n");
+
+ fprintf (file, "#define offobjvftbl %3d\n", (int) OFFSET(java_objectheader, vftbl));
+ fprintf (file, "#define offarraysize %3d\n", (int) OFFSET(java_arrayheader, size));
+ fprintf (file, "#define offobjarrdata %3d\n\n", (int) OFFSET(java_objectarray, data[0]));
+ fprintf (file, "#define offbaseval %3d\n", (int) OFFSET(vftbl, baseval));
+ fprintf (file, "#define offdiffval %3d\n", (int) OFFSET(vftbl, diffval));
+
+ fclose (file);
suck_init (classpath);
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
/****************************** builtin.c **************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
builtin_descriptor builtin_desc[] = {
{(functionptr) builtin_instanceof, "instanceof"},
{(functionptr) builtin_checkcast, "checkcast"},
- {(functionptr) new_builtin_checkcast, "checkcast"},
- {(functionptr) new_builtin_checkclasscast, "checkclasscast"},
- {(functionptr) new_builtin_checkintercast, "checkintercast"},
{(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
{(functionptr) builtin_checkarraycast, "checkarraycast"},
- {(functionptr) new_builtin_checkarraycast, "checkarraycast"},
- {(functionptr) new_builtin_aastore, "aastore"},
+ {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
+ {(functionptr) asm_builtin_aastore, "aastore"},
{(functionptr) builtin_new, "new"},
{(functionptr) builtin_anewarray, "anewarray"},
{(functionptr) builtin_newarray_array, "newarray_array"},
{(functionptr) builtin_displaymethodstart, "displaymethodstart"},
{(functionptr) builtin_displaymethodstop, "displaymethodstop"},
{(functionptr) builtin_monitorenter, "monitorenter"},
- {(functionptr) new_builtin_monitorenter, "monitorenter"},
+ {(functionptr) asm_builtin_monitorenter, "monitorenter"},
{(functionptr) builtin_monitorexit, "monitorexit"},
- {(functionptr) new_builtin_monitorexit, "monitorexit"},
+ {(functionptr) asm_builtin_monitorexit, "monitorexit"},
{(functionptr) builtin_idiv, "idiv"},
- {(functionptr) new_builtin_idiv, "idiv"},
+ {(functionptr) asm_builtin_idiv, "idiv"},
{(functionptr) builtin_irem, "irem"},
- {(functionptr) new_builtin_irem, "irem"},
+ {(functionptr) asm_builtin_irem, "irem"},
{(functionptr) builtin_ladd, "ladd"},
{(functionptr) builtin_lsub, "lsub"},
{(functionptr) builtin_lmul, "lmul"},
{(functionptr) builtin_ldiv, "ldiv"},
- {(functionptr) new_builtin_ldiv, "ldiv"},
+ {(functionptr) asm_builtin_ldiv, "ldiv"},
{(functionptr) builtin_lrem, "lrem"},
- {(functionptr) new_builtin_lrem, "lrem"},
+ {(functionptr) asm_builtin_lrem, "lrem"},
{(functionptr) builtin_lshl, "lshl"},
{(functionptr) builtin_lshr, "lshr"},
{(functionptr) builtin_lushr, "lushr"},
static s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
{
- if (super->flags & ACC_INTERFACE) {
- s4 index = super->index;
- if (index >= sub->vftbl->interfacetablelength) return 0;
- return ( sub->vftbl->interfacevftbl[index] ) ? 1 : 0;
- }
- return (sub->vftbl->lowclassval >= super->vftbl->lowclassval) &
- (sub->vftbl->lowclassval <= super->vftbl->highclassval);
+ if (super->flags & ACC_INTERFACE)
+ return (sub->vftbl->interfacetablelength > super->index) &&
+ (sub->vftbl->interfacetable[-super->index] != NULL);
+
+ return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
+ (unsigned) (super->vftbl->diffval);
}
log_text ("builtin_checkcast called");
#endif
- if (!obj) return 1;
- if ( builtin_isanysubclass (obj->vftbl->class, class) ) {
+ if (obj == NULL)
return 1;
- }
-#if DEBUG
- printf ("#### checkcast failed ");
- unicode_display (obj->vftbl->class->name);
- printf (" -> ");
- unicode_display (class->name);
- printf ("\n");
-#endif
-
- return 0;
-}
-
-
-/***************** function: builtin_checkclasscast ****************************
-
- Returns 1 (true) if the object "sub" is a subclass of the class "super",
- otherwise returns 0 (false). If sub is NULL it also returns 1 (true).
-
-*******************************************************************************/
-
-s4 builtin_checkclasscast(java_objectheader *sub, classinfo *super)
-{
- if (!sub)
+ if (builtin_isanysubclass (obj->vftbl->class, class))
return 1;
- return (sub->vftbl->lowclassval >= super->vftbl->lowclassval) &
- (sub->vftbl->lowclassval <= super->vftbl->highclassval);
-}
-
-
-/***************** function: builtin_checkintercast ****************************
-
- Returns 1 (true) if the object "sub" is a subclass of the interface "super",
- otherwise returns 0 (false). If "sub" is NULL it also returns 1 (true).
-
-*******************************************************************************/
-
-s4 builtin_checkintercast(java_objectheader *sub, classinfo *super)
-{
- if (!sub)
- return 1;
+#if DEBUG
+ printf ("#### checkcast failed ");
+ unicode_display (obj->vftbl->class->name);
+ printf (" -> ");
+ unicode_display (class->name);
+ printf ("\n");
+#endif
- return (sub->vftbl->interfacetablelength > super->index) &&
- (sub->vftbl->interfacevftbl[super->index] != NULL);
return 0;
}
}
}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
s4 builtin_instanceof(java_objectheader *obj, classinfo *class);
s4 builtin_checkcast(java_objectheader *obj, classinfo *class);
-s4 new_builtin_checkcast(java_objectheader *obj, classinfo *class);
-s4 new_builtin_checkclasscast(java_objectheader *obj, classinfo *class);
-s4 new_builtin_checkintercast(java_objectheader *obj, classinfo *class);
s4 builtin_arrayinstanceof
(java_objectheader *obj, constant_arraydescriptor *desc);
s4 builtin_checkarraycast
(java_objectheader *obj, constant_arraydescriptor *desc);
-s4 new_builtin_checkarraycast
+s4 asm_builtin_checkarraycast
(java_objectheader *obj, constant_arraydescriptor *desc);
java_objectheader *builtin_throw_exception (java_objectheader *exception);
s4 builtin_canstore (java_objectarray *a, java_objectheader *o);
s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o);
-void new_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o);
+void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o);
void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5, methodinfo *method);
void builtin_displaymethodstart(methodinfo *method);
void builtin_displaymethodexception(methodinfo *method);
void builtin_monitorenter (java_objectheader *o);
-void new_builtin_monitorenter (java_objectheader *o);
+void asm_builtin_monitorenter (java_objectheader *o);
void builtin_monitorexit (java_objectheader *o);
-void new_builtin_monitorexit (java_objectheader *o);
+void asm_builtin_monitorexit (java_objectheader *o);
s4 builtin_idiv (s4 a, s4 b);
-s4 new_builtin_idiv (s4 a, s4 b);
+s4 asm_builtin_idiv (s4 a, s4 b);
s4 builtin_irem (s4 a, s4 b);
-s4 new_builtin_irem (s4 a, s4 b);
+s4 asm_builtin_irem (s4 a, s4 b);
s8 builtin_ladd (s8 a, s8 b);
s8 builtin_lsub (s8 a, s8 b);
s8 builtin_lmul (s8 a, s8 b);
s8 builtin_ldiv (s8 a, s8 b);
-s8 new_builtin_ldiv (s8 a, s8 b);
+s8 asm_builtin_ldiv (s8 a, s8 b);
s8 builtin_lrem (s8 a, s8 b);
-s8 new_builtin_lrem (s8 a, s8 b);
+s8 asm_builtin_lrem (s8 a, s8 b);
s8 builtin_lshl (s8 a, s4 b);
s8 builtin_lshr (s8 a, s4 b);
s8 builtin_lushr (s8 a, s4 b);
-/****************************** global.h ***************************************
+/* global.h ********************************************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
Contains global definitions which are used in the whole program, includes
some files and contains global used macros.
- Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
- Changes: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
- Mark Probst EMAIL: cacao@complang.tuwien.ac.at
- Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at
+ Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
+ Andreas Krall (andi) EMAIL: cacao@complang.tuwien.ac.at
+ Changes: Mark Probst (schani) EMAIL: cacao@complang.tuwien.ac.at
+ Philipp Tomsich (phil) EMAIL: cacao@complang.tuwien.ac.at
Last Change: 1998/10/30
marker functions on and off. */
#undef JIT_MARKER_SUPPORT /* phil */
-/***************************** standard includes ******************************/
+/* standard includes **********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "toolbox/loging.h"
-/**************************** system dependent types **************************/
+/* system dependent types *****************************************************/
#include "sysdep/types.h"
-/**************************** additional data types ***************************/
+/* additional data types ******************************************************/
typedef void *voidptr; /* generic pointer */
-
-typedef u1 bool; /* boolean data type */
+typedef int bool; /* boolean data type */
#define true 1
#define false 0
#define MAX_ALIGN 8 /* most generic alignment for JavaVM values */
-/**************************** shutdown function *******************************/
+/* shutdown function **********************************************************/
void cacao_shutdown(s4 status);
-/**************************** basic data types ********************************/
+/* basic data types ***********************************************************/
#define TYPE_INT 0 /* the JavaVM types must numbered in the */
#define TYPE_LONG 1 /* same order as the ICMD_Ixxx to ICMD_Axxx */
#define TYPE_FLOAT 2 /* instructions (LOAD and STORE) */
#define TYPE_DOUBLE 3 /* integer, long, float, double, address */
-#define TYPE_ADDRESS 4 /* all other types can be numbered arbitrarily*/
+#define TYPE_ADDRESS 4 /* all other types can be numbered arbitrarly */
#define TYPE_VOID 10
-/**************************** Java class file constants ***********************/
+/* Java class file constants **************************************************/
#define MAGIC 0xcafebabe
#define MINOR_VERSION 3
#define MAJOR_VERSION 45
-#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_Arraydescriptor 13
-#define CONSTANT_UNUSED 0
-
+#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_Arraydescriptor 13
+#define CONSTANT_UNUSED 0
#define ACC_PUBLIC 0x0001
#define ACC_PRIVATE 0x0002
#define ACC_ABSTRACT 0x0400
-
-/**************************** resolve typedef-cycles **************************/
+/* resolve typedef cycles *****************************************************/
typedef struct unicode unicode;
+typedef struct java_objectheader java_objectheader;
typedef struct classinfo classinfo;
typedef struct vftbl vftbl;
typedef u1* methodptr;
-/********************** data structures of UNICODE symbol *********************/
+/* constant pool entries *******************************************************
-struct unicode {
- unicode *hashlink; /* externe Verkettung f"ur die unicode-Hashtabelle */
- u4 key; /* Hash-Schl"ussel (h"angt nur vom Text ab) */
- int length; /* L"ange des Textes */
- u2 *text; /* Zeiger auf den Text (jeder Buchstabe 16 Bit) */
- classinfo *class; /* gegebenenfalls Referenz auf die Klasse dieses
- Namens (oder NULL, wenn es keine solche gibt) */
- struct java_objectheader *string;
- /* gegebenenfalls Referenz auf einen konstanten
- String mit dem entsprechenden Wert */
-};
+ All constant pool entries need a data structure which contain the entrys
+ value. In some cases this structure exist already, in the remaining cases
+ this structure must be generated:
-/* Alle Unicode-Symbole werden in einer einzigen globalen Tabelle
- (Hashtabelle) verwaltet, jedes Symbol wird nur einmal angelegt.
- -> Speicherersparnis, und "Uberpr"ufung auf Gleichheit durch einfachen
- Zeigervergleich */
+ kind structure generated?
+ ----------------------------------------------------------------------
+ CONSTANT_Class classinfo no
+ CONSTANT_Fieldref constant_FMIref yes
+ CONSTANT_Methodref constant_FMIref yes
+ CONSTANT_InterfaceMethodref constant_FMIref yes
+ CONSTANT_String unicode no
+ CONSTANT_Integer constant_integer yes
+ CONSTANT_Float constant_float yes
+ CONSTANT_Long constant_long yes
+ CONSTANT_Double constant_double yes
+ CONSTANT_NameAndType constant_nameandtype yes
+ CONSTANT_Utf8 unicode no
+ CONSTANT_Arraydescriptor constant_arraydescriptor yes
+ CONSTANT_UNUSED -
+*******************************************************************************/
-/************ data structures of remaining constant pool entries **************/
+/* data structures of Unicode symbol *******************************************
+ All Unicode symbols are stored in one global (hash) table, every symbol
+ exists only once. Equal symbols have identical pointers.
+*/
+
+struct unicode {
+ unicode *hashlink; /* link for external hash chain */
+ u4 key; /* hash key (computed from text) */
+ int length; /* text length */
+ u2 *text; /* pointer to text (each character is 16 Bit) */
+ classinfo *class; /* class pointer if it exists, otherwise NULL */
+ java_objectheader *string; /* string pointer if it exists, otherwise NULL*/
+};
-typedef struct {
- classinfo *class;
- unicode *name;
- unicode *descriptor;
-} constant_FMIref;
+/* data structures of remaining constant pool entries *************************/
-typedef struct {
+typedef struct { /* Fieldref, Methodref and InterfaceMethodref */
+ classinfo *class; /* class containing this field/method/interface */
+ unicode *name; /* field/method/interface name */
+ unicode *descriptor; /* field/method/interface type descriptor string */
+} constant_FMIref;
+
+typedef struct { /* Integer */
s4 value;
} constant_integer;
-typedef struct {
+typedef struct { /* Float */
float value;
} constant_float;
-typedef struct {
+typedef struct { /* Long */
s8 value;
} constant_long;
-typedef struct {
+typedef struct { /* Double */
double value;
} constant_double;
-
-typedef struct {
- unicode *name;
- unicode *descriptor;
+typedef struct { /* NameAndType (Field or Method) */
+ unicode *name; /* field/method name */
+ unicode *descriptor; /* field/method type descriptor string */
} constant_nameandtype;
+/* arraydescriptor describes array types. Basic array types contain their
+ type in the arraytype field, objectclass contains a class pointer for
+ arrays of objects (arraytype == ARRAYTYPE_OBJECT), elementdescriptor
+ contains a pointer to an arraydescriptor which describes the element
+ types in the case of arrays of arrays (arraytype == ARRAYTYPE_ARRAY).
+*/
typedef struct constant_arraydescriptor {
int arraytype;
struct constant_arraydescriptor *elementdescriptor;
} constant_arraydescriptor;
-/* Mit einem Arraydescriptor kann ein Array-Typ dargestellt werden.
- Bei normalen Arrays (z.B. Array von Bytes,...) gen"ugt dazu,
- dass das Feld arraytype die entsprechende Kennzahl enth"alt
- (z.B. ARRAYTYPE_BYTE).
- Bei Arrays von Objekten (arraytype=ARRAYTYPE_OBJECT) muss das
- Feld objectclass auf die Klassenstruktur der m"oglichen
- Element-Objekte zeigen.
- Bei Arrays von Arrays (arraytype=ARRAYTYPE_ARRAY) muss das
- Feld elementdescriptor auf eine weiter arraydescriptor-Struktur
- zeigen, die die Element-Typen beschreibt.
- */
-
-
-
-/********* Anmerkungen zum Constant-Pool:
-
- Die Typen der Eintr"age in den Constant-Pool werden durch die oben
- definierten CONSTANT_.. Werte angegeben.
- Bei allen Typen muss zus"atzlich noch eine Datenstruktur hinzugef"ugt
- werden, die den wirklichen Wert angibt.
- Bei manchen Typen reicht es, einen Verweis auf eine schon bereits
- existierende Struktur (z.B. unicode-Texte) einzutragen, bei anderen
- muss diese Struktur erst extra erzeugt werden.
- Ich habe folgende Datenstrukturen f"ur diese Typen verwendet:
-
- Typ Struktur extra erzeugt?
- ----------------------------------------------------------------------
- CONSTANT_Class classinfo nein
- CONSTANT_Fieldref constant_FMIref ja
- CONSTANT_Methodref constant_FMIref ja
- CONSTANT_InterfaceMethodref constant_FMIref ja
- CONSTANT_String unicode nein
- CONSTANT_Integer constant_integer ja
- CONSTANT_Float constant_float ja
- CONSTANT_Long constant_long ja
- CONSTANT_Double constant_double ja
- CONSTANT_NameAndType constant_nameandtype ja
- CONSTANT_Utf8 unicode nein
- CONSTANT_Arraydescriptor constant_arraydescriptor ja
- CONSTANT_UNUSED -
-
-*******************************/
-
+/* data structures of the runtime system **************************************/
-/***************** Die Datenstrukturen fuer das Laufzeitsystem ****************/
+/* objects *********************************************************************
+ All objects (and arrays) which resides on the heap need the following
+ header at the beginning of the data structure.
+*/
- /********* Objekte **********
-
- Alle Objekte (und Arrays), die am Heap gespeichert werden, m"ussen eine
- folgende spezielle Datenstruktur ganz vorne stehen haben:
-
- */
+struct java_objectheader { /* header for all objects */
+ vftbl *vftbl; /* pointer to virtual function table */
+};
-typedef struct java_objectheader { /* Der Header f"ur alle Objekte */
- vftbl *vftbl; /* Zeiger auf die Function Table */
-} java_objectheader;
+/* arrays **********************************************************************
-/********* Arrays ***********
-
- Alle Arrays in Java sind auch gleichzeitig Objekte (d.h. sie haben auch
- den obligatorischen Object-Header und darin einen Verweis auf eine Klasse)
- Es gibt aber (der Einfachheit halber) nur eine einzige Klasse f"ur alle
- m"oglichen Typen von Arrays, deshalb wird der tats"achliche Typ in einem
- Feld im Array-Objekt selbst gespeichert.
- Die Typen sind: */
+ All arrays are objects (they need the object header with a pointer to a
+ vvftbl (array class table). There is only one class for all arrays. The
+ type of an array is stored directly in the array object. Following types
+ are defined:
+*/
#define ARRAYTYPE_INT 0
#define ARRAYTYPE_LONG 1
#define ARRAYTYPE_OBJECT 8
#define ARRAYTYPE_ARRAY 9
-
-/** Der Header f"ur ein Java-Array **/
-
-typedef struct java_arrayheader { /* Der Arrayheader f"ur alle Arrays */
- java_objectheader objheader; /* Der Object-Header */
- s4 size; /* Gr"osse des Arrays */
- s4 arraytype; /* Typ der Elemente */
+typedef struct java_arrayheader { /* header for all arrays */
+ java_objectheader objheader; /* object header */
+ s4 size; /* array size */
+ s4 arraytype; /* array type from previous list */
} java_arrayheader;
-/** Die Unterschiedlichen Strukturen f"ur alle Typen von Arrays **/
+/* structs for all kinds of arrays ********************************************/
typedef struct java_chararray {
java_arrayheader header;
double data[1];
} java_doublearray;
-
-/* achtung: die beiden Stukturen booleanarray und bytearray m"ussen
- identisches memory-layout haben, weil mit den selben Funktionen
- darauf zugegriffen wird */
+/* booleanarray and bytearray need identical memory layout (access methods
+ use the same machine code */
typedef struct java_booleanarray {
java_arrayheader header;
s8 data[1];
} java_longarray;
-
-/* ACHTUNG: die beiden folgenden Strukturen m"ussen unbedingt gleiches
- Memory-Layout haben, weil mit ein und der selben Funktion auf die
- data-Eintr"age beider Typen zugegriffen wird !!!! */
+/* objectarray and arrayarray need identical memory layout (access methods
+ use the same machine code */
typedef struct java_objectarray {
java_arrayheader header;
} java_arrayarray;
+/* field, method and class structures *****************************************/
-
-/******************** class, field and method structures **********************/
-
-
-/********************** structure: fieldinfo **********************************/
+/* fieldinfo ******************************************************************/
typedef struct fieldinfo {/* field of a class */
s4 flags; /* ACC flags */
} fieldinfo;
-/********************** structure: exceptiontable *****************************/
+/* exceptiontable *************************************************************/
typedef struct exceptiontable { /* exceptiontable entry in a method */
s4 startpc; /* start pc of guarded area (inclusive) */
} exceptiontable;
-/********************** structure: methodinfo *********************************/
+/* methodinfo *****************************************************************/
typedef struct methodinfo { /* method structure */
s4 flags; /* ACC flags */
s4 paramcount; /* only temporary valid, parameter count */
u1 *paramtypes; /* only temporary valid, parameter types */
classinfo *class; /* class, the method belongs to */
- u4 vftblindex; /* index of method in virtual function table
+ s4 vftblindex; /* index of method in virtual function table
(if it is a virtual method) */
s4 maxstack; /* maximum stack depth of method */
s4 maxlocals; /* maximum number of local variables */
- u4 jcodelength; /* length of JavaVM code */
+ s4 jcodelength; /* length of JavaVM code */
u1 *jcode; /* pointer to JavaVM code */
s4 exceptiontablelength;/* exceptiontable length */
exceptiontable *exceptiontable; /* the exceptiontable */
u1 *stubroutine; /* stub for compiling or calling natives */
- u4 mcodelength; /* legth of generated machine code */
+ s4 mcodelength; /* legth of generated machine code */
u1 *mcode; /* pointer to machine code */
u1 *entrypoint; /* entry point in machine code */
} methodinfo;
-/********************** structure: classinfo **********************************/
+/* classinfo ******************************************************************/
struct classinfo { /* class structure */
java_objectheader header; /* classes are also objects */
methodinfo *marker;
#endif
};
+
+
+/* virtual function table ******************************************************
+
+ The vtbl has a bidirectional layout with open ends at both sides.
+ interfacetablelength gives the number of entries of the interface table at
+ the start of the vftbl. The vftbl pointer points to &interfacetable[0].
+ vftbllength gives the number of entries of table at the end of the vftbl.
+
+ runtime type check (checkcast):
+
+ Different methods are used for runtime type check depending on the
+ argument of checkcast/instanceof.
+ A check against a class is implemented via relative numbering on the class
+ hierachy tree. The tree is numbered in a depth first traversal setting
+ the base field and the diff field. The diff field gets the result of
+ (high - base) so that a range check can be implemented by an unsigned
+ compare. A sub type test is done by checking the inclusion of base of
+ the sub class in the range of the superclass.
+
+ A check against an interface is implemented via the interfacevftbl. If the
+ interfacevftbl contains a nonnull value a class is a subclass of this
+ interface.
+
+ interfacetable:
+
+ Like standard virtual methods interface methods are called using
+ virtual function tables. All interfaces are numbered sequentially
+ (starting with zero). For each class there exist an interface table
+ of virtual function tables for each implemented interface. The length
+ of the interface table is determined by the highest number of an
+ implemented interface.
+
+ The following example assumes a class which implements interface 0 and 3:
+
+ interfacetablelength = 4
+
+ | ... | +----------+
+ +-----------+ | method 2 |---> method z
+ | class | | method 1 |---> method y
+ +-----------+ | method 0 |---> method x
+ | ivftbl 0 |----------> +----------+
+ vftblptr ---> +-----------+
+ | ivftbl -1 |--> NULL +----------+
+ | ivftbl -2 |--> NULL | method 1 |---> method x
+ | ivftbl -3 |-----+ | method 0 |---> method a
+ +-----------+ +----> +----------+
+
+ +---------------+
+ | length 3 = 2 |
+ | length 2 = 0 |
+ | length 1 = 0 |
+ | length 0 = 3 |
+ interfacevftbllength ---> +---------------+
+
+*******************************************************************************/
struct vftbl {
- classinfo *class; /* Class, the function table belongs to */
+ methodptr *interfacetable[1]; /* interface table (access via macro) */
+
+ classinfo *class; /* class, the vtbl belongs to */
- s4 vftbllength; /* virtual function table length */
- s4 interfacetablelength; /* interface table length */
+ s4 vftbllength; /* virtual function table length */
+ s4 interfacetablelength; /* interface table length */
- s4 lowclassval; /* low value for relative numbering */
- s4 highclassval; /* high value for relative numbering */
+ s4 baseval; /* base for runtime type check */
+ s4 diffval; /* high - base for runtime type check */
- u4 *interfacevftbllength; /* see description below */
- methodptr **interfacevftbl;
+ s4 *interfacevftbllength; /* length of interface vftbls */
- methodptr table[1];
+ methodptr table[1]; /* class vftbl */
};
-/*********** Anmerkungen zur Interfacetable:
-
- "Ahnlich wie die 'normalen' virtuellen Methoden k"onnen auch die
- Interface-Methoden mit Hilfe einer Art Virtual Function Table
- aufgerufen werden.
- Dazu werden alle Interfaces im System fortlaufend nummeriert (beginnend
- bei 0), und f"ur jede Klasse wird eine ganze Tabelle von
- Virtual Function Tables erzeugt, n"amlich zu jedem Interface, das die
- Klasse implementiert, eine.
-
- z.B. Nehmen wir an, eine Klasse implementiert zwei Interfaces (die durch
- die Nummerierung die Indizes 0 und 3 bekommen haben)
-
- Das sieht dann ungef"ahr so aus:
- -------------- -------------
- interfacevftbl ---> | Eintrag 0 |---------> | Methode 0 |---> Methode X
- | Eintrag 1 |--> NULL | Methode 1 |---> Methode Y
- | Eintrag 2 |--> NULL | Methode 2 |---> Methode Z
- | Eintrag 3 |-----+ -------------
- -------------- |
- +---> -------------
- | Methode 0 |---> Methode X
- | Methode 1 |---> Methode A
- -------------
- ---------------
- interfacevftlblength ---> | Wert 0 = 3 |
- | Wert 1 = 0 |
- | Wert 2 = 0 |
- | Wert 3 = 2 |
- ---------------
-
- Der Aufruf einer Interface-Methode geht dann so vor sich:
- Zur Compilezeit steht der Index (i) des Interfaces und die Stelle (s), wo
- in der entsprechenden Untertabelle die Methode eingetragen ist, schon fest.
- Also muss zur Laufzeit nur mehr der n-te Eintrag aus der Interfacetable
- gelesen werden, von dieser Tabelle aus wird der s-te Eintrag geholt,
- und diese Methode wird angesprungen.
-
-****************/
-
-
-
-/********************** references to some system classes ********************/
+#define VFTBLINTERFACETABLE(v,i) (v)->interfacetable[-i]
+
+
+/* references to some system classes ******************************************/
extern classinfo *class_java_lang_Object;
extern classinfo *class_java_lang_String;
extern classinfo *class_array;
-/********************** instances of some system classes **********************/
+/* instances of some system classes *******************************************/
extern java_objectheader *proto_java_lang_ClassCastException;
extern java_objectheader *proto_java_lang_NullPointerException;
extern java_objectheader *proto_java_lang_ThreadDeath;
-/******************************* flag variables *******************************/
+/* flag variables *************************************************************/
extern bool compileall;
extern bool runverbose;
extern bool verbose;
-/******************************* trace variables ******************************/
+/* statistic variables ********************************************************/
extern int count_class_infos;
extern int count_const_pool_len;
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/****************************** loader.c ***************************************
+/* loader.c ********************************************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
#include "threads/thread.h" /* schani */
-/*************************** globale Variablen *******************************/
+/* global variables ***********************************************************/
-extern bool newcompiler;
+extern bool newcompiler; /* true if new compiler is used */
-int count_class_infos = 0;
+int count_class_infos = 0; /* variables for measurements */
int count_const_pool_len = 0;
int count_vftbl_len = 0;
int count_all_methods = 0;
int count_vmcode_len = 0;
int count_extable_len = 0;
-bool loadverbose = false; /* Switches f"ur mehr Debug-Meldungen */
+bool loadverbose = false; /* switches for debug messages */
bool linkverbose = false;
bool initverbose = false;
long int loadingtime = 0;
-static u4 interfaceindex; /* fortlaufende Nummer f"ur Interfaces */
+static s4 interfaceindex; /* sequential numbering of interfaces */
-static list unloadedclasses; /* Liste alle referenzierten, aber noch nicht
- geladenen Klassen */
-static list unlinkedclasses; /* Liste aller geladenen, aber noch nicht
- gelinkten Klassen */
- list linkedclasses; /* Liste aller fertig gelinkten Klassen */
+static list unloadedclasses; /* list of all referenced but not loaded classes */
+static list unlinkedclasses; /* list of all loaded but not linked classes */
+ list linkedclasses; /* list of all completely linked classes */
-/***************** die Referenzen auf die wichtigen Systemklassen ************/
+/* important system classes ***************************************************/
classinfo *class_java_lang_Object;
classinfo *class_java_lang_String;
classinfo *class_array;
-/************ einige vorgefertigte Instanzen wichtiger Systemklassen *********/
+/* instances of important system classes **************************************/
java_objectheader *proto_java_lang_ClassCastException;
java_objectheader *proto_java_lang_NullPointerException;
-/****************************************************************************/
-/******************* Einige Support-Funkionen *******************************/
-/****************************************************************************/
+/******************************************************************************/
+/******************* Einige Support-Funkionen *********************************/
+/******************************************************************************/
-/********** interne Funktion: printflags (nur zu Debug-Zwecken) ************/
+/********** interne Funktion: printflags (nur zu Debug-Zwecken) **************/
static void printflags (u2 f)
{
}
-/************************* Funktion: skipattribute ****************************
+/************************* Funktion: skipattribute *****************************
"uberliest im ClassFile eine (1) 'attribute'-Struktur
-******************************************************************************/
+*******************************************************************************/
static void skipattribute ()
{
- u4 len;
-
suck_u2 ();
- len = suck_u4 ();
- skip_nbytes (len);
+ skip_nbytes(suck_u4());
}
-/********************** Funktion: skipattributebody ***************************
+/********************** Funktion: skipattributebody ****************************
"uberliest im Classfile ein attribut, wobei die 16-bit - attribute_name -
Referenz schon gelesen worden ist.
-******************************************************************************/
+*******************************************************************************/
static void skipattributebody ()
{
- u4 len = suck_u4 ();
- skip_nbytes (len);
+ skip_nbytes(suck_u4());
}
-/************************* Funktion: skipattributes ***************************
+/************************* Funktion: skipattributes ****************************
"uberliest im ClassFile eine gew"unschte Anzahl von attribute-Strukturen
-******************************************************************************/
+*******************************************************************************/
static void skipattributes (u4 num)
{
u4 i;
- for (i=0; i<num; i++) skipattribute();
+ for (i = 0; i < num; i++)
+ skipattribute();
}
-/************************** Funktion: loadUtf8 ********************************
+/************************** Funktion: loadUtf8 *********************************
liest aus dem ClassFile einen Utf8-String (=komprimierter unicode-text)
und legt daf"ur ein unicode-Symbol an.
Return: Zeiger auf das Symbol
-******************************************************************************/
+*******************************************************************************/
#define MAXUNICODELEN 5000
static u2 unicodebuffer[MAXUNICODELEN];
-/******************** interne Funktion: checkfieldtype ***********************/
+/******************** interne Funktion: checkfieldtype ************************/
static void checkfieldtype (u2 *text, u4 *count, u4 length)
{
}
-/******************* Funktion: checkfielddescriptor ***************************
+/******************* Funktion: checkfielddescriptor ****************************
"uberpr"uft, ob ein Field-Descriptor ein g"ultiges Format hat.
Wenn nicht, dann wird das System angehalten.
Au"serdem werden alle Klassen, die hier referenziert werden,
in die Liste zu ladender Klassen eingetragen.
-******************************************************************************/
+*******************************************************************************/
void checkfielddescriptor (unicode *d)
{
}
-/******************* Funktion: checkmethoddescriptor **************************
+/******************* Funktion: checkmethoddescriptor ***************************
"uberpr"uft, ob ein Method-Descriptor ein g"ultiges Format hat.
Wenn nicht, dann wird das System angehalten.
Au"serdem werden alle Klassen, die hier referenziert werden,
in die Liste zu ladender Klassen eingetragen.
-******************************************************************************/
+*******************************************************************************/
void checkmethoddescriptor (unicode *d)
{
}
-/******************** Funktion: buildarraydescriptor ****************************
+/******************** Funktion: buildarraydescriptor ***************************
erzeugt zu einem namentlich als u2-String vorliegenden Arraytyp eine
entsprechende constant_arraydescriptor - Struktur
-********************************************************************************/
+*******************************************************************************/
static constant_arraydescriptor * buildarraydescriptor(u2 *name, u4 namelen)
{
}
-/******************* Funktion: freearraydescriptor ****************************
+/******************* Funktion: freearraydescriptor *****************************
entfernt eine mit buildarraydescriptor erzeugte Struktur wieder
aus dem Speicher
-/*****************************************************************************/
-/******************** Funktionen fuer Fields *********************************/
-/*****************************************************************************/
+/******************************************************************************/
+/******************** Funktionen fuer Fields **********************************/
+/******************************************************************************/
-/************************ Funktion: field_load ********************************
+/************************ Funktion: field_load *********************************
l"adt alle Informationen f"ur eine Feld einer Methode aus dem ClassFile,
und f"ullt mit diesen Infos eine schon existierende 'fieldinfo'-Struktur.
Bei 'static'-Fields wird auch noch ein Platz auf dem Datensegment
reserviert.
-******************************************************************************/
+*******************************************************************************/
static void field_load (fieldinfo *f, classinfo *c)
{
}
-/********************** Funktion: field_free *********************************/
+/********************** Funktion: field_free **********************************/
static void field_free (fieldinfo *f)
{
}
-/************** Funktion: field_display (nur zu Debug-Zwecken) ***************/
+/************** Funktion: field_display (nur zu Debug-Zwecken) ****************/
static void field_display (fieldinfo *f)
{
-/*****************************************************************************/
-/************************* Funktionen f"ur Methods ***************************/
-/*****************************************************************************/
+/******************************************************************************/
+/************************* Funktionen f"ur Methods ****************************/
+/******************************************************************************/
-/*********************** Funktion: method_load ********************************
+/*********************** Funktion: method_load *********************************
l"adt die Infos f"ur eine Methode aus dem ClassFile und f"ullt damit
eine schon existierende 'methodinfo'-Struktur aus.
Funktionszeiger eingetragen, bei JavaVM-Methoden einstweilen ein
Zeiger auf den Compiler
-******************************************************************************/
+*******************************************************************************/
static void method_load (methodinfo *m, classinfo *c)
{
}
-/********************* Funktion: method_free **********************************
+/********************* Funktion: method_free ***********************************
gibt allen Speicher, der extra f"ur eine Methode angefordert wurde,
wieder frei
-******************************************************************************/
+*******************************************************************************/
static void method_free (methodinfo *m)
{
}
-/************** Funktion: method_display (nur zu Debug-Zwecken) *************/
+/************** Funktion: method_display (nur zu Debug-Zwecken) **************/
void method_display (methodinfo *m)
{
}
-/******************** Funktion: method_canoverwrite ***************************
+/******************** Funktion: method_canoverwrite ****************************
"uberpr"ft, ob eine Methode mit einer anderen typ- und namensidentisch
ist (also mit einer Methodendefinition eine andere "uberschrieben
werden kann).
-******************************************************************************/
+*******************************************************************************/
static bool method_canoverwrite (methodinfo *m, methodinfo *old)
{
-/*****************************************************************************/
-/************************ Funktionen fuer Class ******************************/
-/*****************************************************************************/
+/******************************************************************************/
+/************************ Funktionen fuer Class *******************************/
+/******************************************************************************/
-/******************** Funktion: class_get *************************************
+/******************** Funktion: class_get **************************************
Sucht im System die Klasse mit dem gew"unschten Namen, oder erzeugt
eine neue 'classinfo'-Struktur (und h"angt sie in die Liste der zu
ladenen Klassen ein).
-******************************************************************************/
+*******************************************************************************/
classinfo *class_get (unicode *u)
{
c -> linked = false;
c -> index = 0;
c -> instancesize = 0;
+ c -> header.vftbl = NULL;
c -> vftbl = NULL;
c -> initialized = false;
-/******************** Funktion: class_getconstant *****************************
+/******************** Funktion: class_getconstant ******************************
holt aus dem ConstantPool einer Klasse den Wert an der Stelle 'pos'.
Der Wert mu"s vom Typ 'ctype' sein, sonst wird das System angehalten.
-******************************************************************************/
+*******************************************************************************/
voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype)
{
}
-/********************* Funktion: class_constanttype ***************************
+/********************* Funktion: class_constanttype ****************************
Findet heraus, welchen Typ ein Eintrag in den ConstantPool einer
Klasse hat.
-******************************************************************************/
+*******************************************************************************/
u4 class_constanttype (classinfo *c, u4 pos)
{
}
-/******************** Funktion: class_loadcpool *******************************
+/******************** Funktion: class_loadcpool ********************************
l"adt den gesammten ConstantPool einer Klasse.
Format gebracht (Klassenreferenzen werden aufgel"ost, ...)
F"ur eine genaue "Ubersicht "uber das kompakte Format siehe: 'global.h'
-******************************************************************************/
+*******************************************************************************/
static void class_loadcpool (classinfo *c)
{
}
-/********************** Funktion: class_load **********************************
+/********************** Funktion: class_load ***********************************
l"adt alle Infos f"ur eine ganze Klasse aus einem ClassFile. Die
'classinfo'-Struktur mu"s bereits angelegt worden sein.
Die gelesene Klasse wird dann aus der Liste 'unloadedclasses' ausgetragen
und in die Liste 'unlinkedclasses' eingh"angt.
-******************************************************************************/
+*******************************************************************************/
static void class_load (classinfo *c)
{
-/************** interne Funktion: class_highestinterface **********************
+/************** interne Funktion: class_highestinterface ***********************
wird von der Funktion class_link ben"otigt, um festzustellen, wie gro"s
die Interfacetable einer Klasse sein mu"s.
-******************************************************************************/
+*******************************************************************************/
static s4 class_highestinterface (classinfo *c)
{
}
-/**************** Funktion: class_addinterface ********************************
+/* class_addinterface **********************************************************
wird von der Funktion class_link ben"otigt, um eine Virtual Function
Table f"ur ein Interface (und alle weiteren von diesem Interface
implementierten Interfaces) in eine Klasse einzutragen.
-******************************************************************************/
+*******************************************************************************/
static void class_addinterface (classinfo *c, classinfo *ic)
{
- u4 i = ic->index;
- u4 j,m;
+ s4 j, m;
+ s4 i = ic->index;
vftbl *vftbl = c->vftbl;
- if (i>=vftbl->interfacetablelength) panic ("Interfacetable-Overflow");
- if (vftbl->interfacevftbl[i]) return;
+ if (i >= vftbl->interfacetablelength)
+ panic ("Inernal error: interfacetable overflow");
+ if (vftbl->interfacetable[-i])
+ return;
- if (ic->methodscount==0) { /* wenn interface keine Methoden hat, dann
- trotzdem eine Tabelle mit L"ange 1 anlegen,
- wegen Subclass-Tests */
- vftbl -> interfacevftbllength[i] = 1;
- vftbl -> interfacevftbl[i] = MNEW(methodptr, 1);
- vftbl -> interfacevftbl[i][0] = NULL;
+ if (ic->methodscount == 0) { /* fake entry needed for subtype test */
+ vftbl->interfacevftbllength[i] = 1;
+ vftbl->interfacetable[-i] = MNEW(methodptr, 1);
+ vftbl->interfacetable[-i][0] = NULL;
}
else {
- vftbl -> interfacevftbllength[i] = ic -> methodscount;
- vftbl -> interfacevftbl[i] = MNEW(methodptr, ic -> methodscount);
+ vftbl->interfacevftbllength[i] = ic->methodscount;
+ vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
#ifdef STATISTICS
- count_vftbl_len += sizeof(methodptr) * ic -> methodscount;
+ count_vftbl_len += sizeof(methodptr) *
+ (ic->methodscount + (ic->methodscount == 0));
#endif
for (j=0; j<ic->methodscount; j++) {
classinfo *sc = c;
while (sc) {
- for (m=0; m<sc->methodscount; m++) {
+ for (m = 0; m < sc->methodscount; m++) {
methodinfo *mi = &(sc->methods[m]);
- if (method_canoverwrite (mi, &(ic->methods[j])) ) {
- vftbl->interfacevftbl[i][j] =
- vftbl->table[mi->vftblindex];
+ if (method_canoverwrite(mi, &(ic->methods[j]))) {
+ vftbl->interfacetable[-i][j] =
+ vftbl->table[mi->vftblindex];
goto foundmethod;
}
}
foundmethod: ;
}
}
-
- for (j=0; j<ic->interfacescount; j++)
+
+ for (j = 0; j < ic->interfacescount; j++)
class_addinterface(c, ic->interfaces[j]);
}
-/********************** Funktion: class_link **********************************
+/********************** Funktion: class_link ***********************************
versucht, eine Klasse in das System voll zu integrieren (linken). Dazu
m"ussen sowol die Superklasse, als auch alle implementierten
Achtung: Bei zyklischen Klassendefinitionen ger"at das Programm hier in
eine Endlosschleife!! (Da muss ich mir noch was einfallen lassen)
-******************************************************************************/
+*******************************************************************************/
static void class_link (classinfo *c)
{
- u4 supervftbllength; /* L"ange der VFTBL der Superklasse */
- u4 vftbllength; /* L"ange der VFTBL dieser Klasse */
- classinfo *super = c->super;
- classinfo *ic,*c2; /* Hilfsvariablen */
- vftbl *v;
- u4 i;
+ s4 supervftbllength; /* vftbllegnth of super class */
+ s4 vftbllength; /* vftbllength of current class */
+ s4 interfacetablelength; /* interface table length */
+ classinfo *super = c->super; /* super class */
+ classinfo *ic, *c2; /* intermediate class variables */
+ vftbl *v; /* vftbl of current class */
+ s4 i; /* interface/method/field counter */
- /* schauen, ob alle "ubergeordneten Klassen schon fertig sind,
- und richtiges Initialisieren der lokalen Variablen */
+ /* check if all superclasses are already linked, if not put c at end of
+ unlinked list and return. Additionally initialize class fields. */
- for ( i=0; i<c->interfacescount; i++) {
+ /* check interfaces */
+
+ for (i = 0; i < c->interfacescount; i++) {
ic = c->interfaces[i];
- if ( !ic -> linked) {
- list_remove (&unlinkedclasses,c );
- list_addlast (&unlinkedclasses,c );
+ if (!ic->linked) {
+ list_remove(&unlinkedclasses, c);
+ list_addlast(&unlinkedclasses, c);
return;
}
}
- if (! super) {
- c -> index = 0;
- c -> instancesize = sizeof (java_objectheader);
+ /* check super class */
+
+ if (super == NULL) { /* class java.long.Object */
+ c->index = 0;
+ c->instancesize = sizeof(java_objectheader);
vftbllength = supervftbllength = 0;
- c -> finalizer = NULL;
+ c->finalizer = NULL;
}
else {
- if ( !super -> linked ) {
- list_remove (&unlinkedclasses,c );
- list_addlast (&unlinkedclasses,c );
+ if (!super->linked) {
+ list_remove(&unlinkedclasses, c);
+ list_addlast(&unlinkedclasses, c);
return;
}
- if ( c->flags & ACC_INTERFACE) c -> index = interfaceindex++;
- else c -> index = super -> index + 1;
+ if (c->flags & ACC_INTERFACE)
+ c->index = interfaceindex++;
+ else
+ c->index = super->index + 1;
- c -> instancesize = super -> instancesize;
+ c->instancesize = super->instancesize;
- vftbllength = supervftbllength = super -> vftbl -> vftbllength;
+ vftbllength = supervftbllength = super->vftbl->vftbllength;
- c -> finalizer = super -> finalizer;
+ c->finalizer = super->finalizer;
}
dolog ();
}
- /* Erstellen der Virtual Function Table */
+ /* compute vftbl length */
- for (i=0; i < c->methodscount; i++) {
+ for (i = 0; i < c->methodscount; i++) {
methodinfo *m = &(c->methods[i]);
- if (! (m->flags & ACC_STATIC) ) {
+ if (!(m->flags & ACC_STATIC)) { /* is instance method */
classinfo *sc = super;
while (sc) {
int j;
- for (j=0; j < sc->methodscount; j++) {
- if ( method_canoverwrite (m, &(sc->methods[j])) ) {
- m -> vftblindex = sc->methods[j].vftblindex;
+ for (j = 0; j < sc->methodscount; j++) {
+ if (method_canoverwrite(m, &(sc->methods[j]))) {
+ m->vftblindex = sc->methods[j].vftblindex;
goto foundvftblindex;
}
}
sc = sc->super;
}
- m -> vftblindex = (vftbllength++);
- foundvftblindex: ;
+ m->vftblindex = (vftbllength++);
+foundvftblindex: ;
}
}
count_vftbl_len += sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1);
#endif
- c -> vftbl = v = (vftbl*)
- mem_alloc (sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1));
- v -> class = c;
- v -> vftbllength = vftbllength;
- v -> interfacetablelength = 0;
-
- for (i=0; i < supervftbllength; i++)
- v -> table[i] = super -> vftbl -> table[i];
+ /* compute interfacetable length */
+
+ interfacetablelength = 0;
+ c2 = c;
+ while (c2) {
+ for (i = 0; i < c2->interfacescount; i++) {
+ s4 h = class_highestinterface (c2->interfaces[i]) + 1;
+ if (h > interfacetablelength)
+ interfacetablelength = h;
+ }
+ c2 = c2->super;
+ }
+
+ /* allocate virtual function table */
+
+ v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) *
+ (vftbllength - 1) + sizeof(methodptr*) *
+ (interfacetablelength - (interfacetablelength > 0)));
+ v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) *
+ (interfacetablelength > 1));
+ c->header.vftbl = c->vftbl = v;
+ v->class = c;
+ v->vftbllength = vftbllength;
+ v->interfacetablelength = interfacetablelength;
+
+ /* copy virtual function table of super class */
+
+ for (i = 0; i < supervftbllength; i++)
+ v->table[i] = super->vftbl->table[i];
- for (i=0; i < c->methodscount; i++) {
+ /* add method stubs into virtual function table */
+
+ for (i = 0; i < c->methodscount; i++) {
methodinfo *m = &(c->methods[i]);
- if ( ! (m->flags & ACC_STATIC) ) {
- v -> table[m->vftblindex] = m -> stubroutine;
+ if (!(m->flags & ACC_STATIC)) {
+ v->table[m->vftblindex] = m->stubroutine;
}
}
-
- /* Berechnen der Instanzengr"o"se und der Offsets der einzelnen
- Felder */
+ /* compute instance size and offset of each field */
- for (i=0; i < c->fieldscount; i++) {
- u4 dsize;
- fieldinfo *f = &(c -> fields[i]);
+ for (i = 0; i < c->fieldscount; i++) {
+ s4 dsize;
+ fieldinfo *f = &(c->fields[i]);
- if ( ! (f->flags & ACC_STATIC) ) {
+ if (!(f->flags & ACC_STATIC) ) {
dsize = desc_typesize (f->descriptor);
- c -> instancesize = ALIGN ( c->instancesize, dsize);
- f -> offset = c -> instancesize;
- c -> instancesize += dsize;
+ c->instancesize = ALIGN (c->instancesize, dsize);
+ f->offset = c->instancesize;
+ c->instancesize += dsize;
}
-
}
+ /* initialize interfacetable and interfacevftbllength */
- /* Berechnen der Virtual Function Tables f"ur alle Interfaces */
-
- c2 = c;
- while (c2) {
- for (i=0; i<c2->interfacescount; i++) {
- s4 h = class_highestinterface (c2->interfaces[i]) + 1;
- if ( h > v->interfacetablelength) v->interfacetablelength = h;
- }
- c2 = c2->super;
- }
- v -> interfacevftbllength = MNEW (u4, v->interfacetablelength);
- v -> interfacevftbl = MNEW (methodptr *, v->interfacetablelength);
+ v->interfacevftbllength = MNEW (s4, interfacetablelength);
#ifdef STATISTICS
- count_vftbl_len += (4 + sizeof(methodptr*)) * v->interfacetablelength;
+ count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
#endif
- for (i=0; i < v->interfacetablelength; i++) {
- v -> interfacevftbllength[i] = 0;
- v -> interfacevftbl[i] = NULL;
+ for (i = 0; i < interfacetablelength; i++) {
+ v->interfacevftbllength[i] = 0;
+ v->interfacetable[-i] = NULL;
}
- c2 = c;
- while (c2) {
- for (i=0; i<c2->interfacescount; i++) {
+ /* add interfaces */
+
+ for (c2 = c; c2 != NULL; c2 = c2->super)
+ for (i = 0; i < c2->interfacescount; i++) {
class_addinterface (c, c2->interfaces[i]);
}
- c2 = c2->super;
- }
-
-
- /* Die finalizer-Methode suchen und eintragen (wenn vorhanden),
- aber nur bei Objekten ausser java.lang.Object */
+ /* add finalizer method (not for java.lang.Object) */
- if (super) {
+ if (super != NULL) {
methodinfo *fi;
- static unicode *finame=NULL,*fidesc=NULL;
-
- if (!finame) finame = unicode_new_char ("finalize");
- if (!fidesc) fidesc = unicode_new_char ("()V");
+ static unicode *finame = NULL;
+ static unicode *fidesc = NULL;
+
+ if (finame == NULL)
+ finame = unicode_new_char("finalize");
+ if (fidesc == NULL)
+ fidesc = unicode_new_char("()V");
fi = class_findmethod (c, finame, fidesc);
- if (fi) {
- if (! (fi->flags & ACC_STATIC) ) {
- c -> finalizer = fi;
+ if (fi != NULL) {
+ if (!(fi->flags & ACC_STATIC)) {
+ c->finalizer = fi;
}
}
- }
-
-
- /* Abschlie"sende Aktionen */
-
- c -> linked = true;
+ }
+
+ /* final tasks */
+
+ c->linked = true;
list_remove (&unlinkedclasses, c);
list_addlast (&linkedclasses, c);
}
-/******************* Funktion: class_freepool *********************************
+/******************* Funktion: class_freepool **********************************
Gibt alle Resourcen, die der ConstantPool einer Klasse ben"otigt,
wieder frei.
-******************************************************************************/
+*******************************************************************************/
static void class_freecpool (classinfo *c)
{
}
-/*********************** Funktion: class_free *********************************
+/*********************** Funktion: class_free **********************************
Gibt alle Resourcen, die eine ganze Klasse ben"otigt, frei
-******************************************************************************/
+*******************************************************************************/
static void class_free (classinfo *c)
{
- u4 i;
+ s4 i;
vftbl *v;
unicode_unlinkclass (c->name);
MFREE (c->interfaces, classinfo*, c->interfacescount);
- for (i=0; i < c->fieldscount; i++) field_free ( &(c->fields[i]) );
+ for (i = 0; i < c->fieldscount; i++)
+ field_free(&(c->fields[i]));
MFREE (c->fields, fieldinfo, c->fieldscount);
- for (i=0; i < c->methodscount; i++) method_free ( &(c->methods[i]) );
+ for (i = 0; i < c->methodscount; i++)
+ method_free(&(c->methods[i]));
MFREE (c->methods, methodinfo, c->methodscount);
- if ( (v = c->vftbl) ) {
- for (i=0; i<v->interfacetablelength; i++) {
- MFREE (v->interfacevftbl[i], methodptr, v->interfacevftbllength[i]);
+ if ((v = c->vftbl) != NULL) {
+ for (i = 0; i < v->interfacetablelength; i++) {
+ MFREE (v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
}
- MFREE (v->interfacevftbllength, u4, v->interfacetablelength);
- MFREE (v->interfacevftbl, methodptr*, v->interfacetablelength);
-
- mem_free (v, sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1));
+ MFREE (v->interfacevftbllength, s4, v->interfacetablelength);
+
+ i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) +
+ sizeof(methodptr*) * (v->interfacetablelength -
+ (v->interfacetablelength > 0));
+ v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) *
+ (v->interfacetablelength > 1));
+ mem_free (v, i);
}
FREE (c, classinfo);
}
-/************************* Funktion: class_findfield *************************
+/************************* Funktion: class_findfield ***************************
sucht in einer 'classinfo'-Struktur nach einem Feld mit gew"unschtem
Namen und Typ.
-*****************************************************************************/
+*******************************************************************************/
fieldinfo *class_findfield (classinfo *c, unicode *name, unicode *desc)
{
- u4 i;
- for (i=0; i < c->fieldscount; i++) {
- if ( (c->fields[i].name == name) && (c->fields[i].descriptor == desc) )
+ s4 i;
+ for (i = 0; i < c->fieldscount; i++) {
+ if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
return &(c->fields[i]);
}
panic ("Can not find field given in CONSTANT_Fieldref");
}
-/************************* Funktion: class_findmethod *************************
+/************************* Funktion: class_findmethod **************************
sucht in einer 'classinfo'-Struktur nach einer Methode mit gew"unschtem
Namen und Typ.
Wenn als Typ NULL angegeben wird, dann ist der Typ egal.
-*****************************************************************************/
+*******************************************************************************/
methodinfo *class_findmethod (classinfo *c, unicode *name, unicode *desc)
{
- u4 i;
- for (i=0; i < c->methodscount; i++) {
- if ( (c->methods[i].name == name)
- && ( (desc == NULL)
- || (c->methods[i].descriptor == desc)
- )
- )
+ s4 i;
+ for (i = 0; i < c->methodscount; i++) {
+ if ((c->methods[i].name == name) && ((desc == NULL) ||
+ (c->methods[i].descriptor == desc)))
return &(c->methods[i]);
}
return NULL;
}
-/************************* Funktion: class_resolvemethod *************************
+/************************* Funktion: class_resolvemethod ***********************
sucht eine Klasse und alle Superklassen ab, um eine Methode zu finden.
-*****************************************************************************/
+*******************************************************************************/
methodinfo *class_resolvemethod (classinfo *c, unicode *name, unicode *desc)
-/************************* Funktion: class_issubclass ************************
+/************************* Funktion: class_issubclass **************************
"uberpr"uft, ob eine Klasse von einer anderen Klasse abgeleitet ist.
-*****************************************************************************/
+*******************************************************************************/
bool class_issubclass (classinfo *sub, classinfo *super)
{
-/****************** Initialisierungsfunktion f"ur eine Klasse ****************
+/****************** Initialisierungsfunktion f"ur eine Klasse ******************
In Java kann jede Klasse ein statische Initialisierungsfunktion haben.
Diese Funktion mu"s aufgerufen werden, BEVOR irgendwelche Methoden der
Klasse aufgerufen werden, oder auf statische Variablen zugegriffen
wird.
-******************************************************************************/
+*******************************************************************************/
#ifdef USE_THREADS
extern int blockInts;
-/********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) ********/
+/********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) *********/
void class_showconstantpool (classinfo *c)
{
-/********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) ************/
+/********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) *************/
void class_showmethods (classinfo *c)
{
- u4 i;
+ s4 i;
printf ("--------- Fields and Methods ----------------\n");
printf ("Flags: "); printflags (c->flags); printf ("\n");
-/*****************************************************************************/
-/******************* Funktionen fuer den Class-loader generell ***************/
-/*****************************************************************************/
+/******************************************************************************/
+/******************* Funktionen fuer den Class-loader generell ****************/
+/******************************************************************************/
-/********************* Funktion: loader_load **********************************
+/********************* Funktion: loader_load ***********************************
l"adt und linkt die ge"unschte Klasse und alle davon
referenzierten Klassen und Interfaces
Return: Einen Zeiger auf diese Klasse
-******************************************************************************/
+*******************************************************************************/
classinfo *loader_load (unicode *topname)
{
}
-/******************* interne Funktion: loader_createarrayclass ****************
+/******************* interne Funktion: loader_createarrayclass *****************
Erzeugt (und linkt) eine Klasse f"ur die Arrays.
-******************************************************************************/
+*******************************************************************************/
static classinfo *loader_createarrayclass ()
{
-/********************** Funktion: loader_init *********************************
+/********************** Funktion: loader_init **********************************
Initialisiert alle Listen und l"adt alle Klassen, die vom System
und vom Compiler direkt ben"otigt werden.
-******************************************************************************/
+*******************************************************************************/
void loader_init ()
{
initialisiert alle geladenen aber noch nicht initialisierten Klassen
-******************************************************************************/
+*******************************************************************************/
void loader_initclasses ()
{
{
classinfo *subs;
- c->vftbl->lowclassval = classvalue++;
+ c->vftbl->baseval = ++classvalue;
subs = c->sub;
while (subs != NULL) {
loader_compute_class_values(subs);
subs = subs->nextsub;
}
- c->vftbl->highclassval = classvalue++;
+ c->vftbl->diffval = classvalue - c->vftbl->baseval;
/*
{
int i;
for (i = 0; i < c->index; i++)
printf(" ");
- printf("%3d %3d ", (int) c->vftbl->lowclassval, (int) c->vftbl->highclassval);
+ printf("%3d %3d ", (int) c->vftbl->baseval, c->vftbl->diffval);
unicode_display(c->name);
printf("\n");
}
-/******************** Funktion: loader_close **********************************
+/******************** Funktion: loader_close ***********************************
gibt alle Resourcen wieder frei
-******************************************************************************/
+*******************************************************************************/
void loader_close ()
{
}
}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */