calls instead of machine instructions, using the C calling
convention.
- $Id: builtin.c 718 2003-12-08 13:03:43Z jowenn $
+ $Id: builtin.c 727 2003-12-11 10:52:40Z edwin $
*/
#undef DEBUG /*define DEBUG 1*/
+/* XXX delete? */
+#if 0
builtin_descriptor builtin_desc[] = {
{(functionptr) builtin_instanceof, "instanceof"},
{(functionptr) builtin_checkcast, "checkcast"},
{(functionptr) builtin_d2f, "d2f"},
{(functionptr) NULL, "unknown"}
};
+#endif
/*****************************************************************************
Authors: Reinhard Grafl
- $Id: builtin.h 716 2003-12-07 21:59:12Z twisti $
+ $Id: builtin.h 727 2003-12-11 10:52:40Z edwin $
*/
#define DBL_POSINF 0x7ff0000000000000LL
#define DBL_NEGINF 0xfff0000000000000LL
-
+/* XXX delete */
+#if 0
typedef struct builtin_descriptor {
functionptr bptr;
char *name;
} builtin_descriptor;
+#endif
+
+typedef struct builtin_descriptor builtin_descriptor;
+
+struct builtin_descriptor {
+ int opcode;
+ functionptr builtin;
+ int icmd;
+ u1 type_s1;
+ u1 type_s2;
+ u1 type_s3;
+ u1 type_d;
+ bool supported;
+ bool isfloat;
+ char *name;
+};
extern builtin_descriptor builtin_desc[];
+extern int builtintablelen;
+
extern java_objectheader* exceptionptr;
-/* function prototypes */
+/**********************************************************************/
+/* BUILTIN FUNCTIONS */
+/**********************************************************************/
+
+/* NOTE: Builtin functions which are used in the BUILTIN* opcodes must
+ * have a BUILTIN_... macro defined as seen below. In code dealing
+ * with the BUILTIN* opcodes the functions may only be addressed by
+ * these macros, never by their actual name! (This helps to make this
+ * code more portable.)
+ *
+ * C and assembler code which does not deal with the BUILTIN* opcodes,
+ * can use the builtin functions normally (like all other functions).
+ *
+ * IMPORTANT:
+ * For each builtin function which is used in a BUILTIN* opcode there
+ * must be an entry in the builtin_desc table in builtin.c!
+ *
+ * Below each prototype is either the BUILTIN_ macro definition or a
+ * comment specifiying that this function is not used in BUILTIN*
+ * opcodes.
+ *
+ * (The BUILTIN* opcodes are ICMD_BUILTIN1, ICMD_BUILTIN2 and
+ * ICMD_BUILTIN3.)
+ */
s4 builtin_instanceof(java_objectheader *obj, classinfo *class);
+#define BUILTIN_instanceof (functionptr) builtin_instanceof
s4 builtin_isanysubclass (classinfo *sub, classinfo *super);
+/* NOT AN OP */
s4 builtin_isanysubclass_vftbl (vftbl *sub, vftbl *super);
+/* NOT AN OP */
s4 builtin_checkcast(java_objectheader *obj, classinfo *class);
-s4 asm_builtin_checkcast(java_objectheader *obj, classinfo *class);
-
+/* NOT AN OP */
s4 builtin_arrayinstanceof(java_objectheader *obj, vftbl *target);
+#define BUILTIN_arrayinstanceof (functionptr) builtin_arrayinstanceof
+
#if defined(__I386__)
s4 asm_builtin_arrayinstanceof(java_objectheader *obj, classinfo *class); /* XXX ? */
+#undef BUILTIN_arrayinstanceof
+#define BUILTIN_arrayinstanceof (functionptr) asm_builtin_arrayinstanceof
#endif
+
s4 builtin_checkarraycast(java_objectheader *obj, vftbl *target);
+/* NOT AN OP */
s4 asm_builtin_checkarraycast(java_objectheader *obj, vftbl *target);
+#define BUILTIN_checkarraycast (functionptr) asm_builtin_checkarraycast
java_objectheader *builtin_throw_exception(java_objectheader *exception);
+/* NOT AN OP */
java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
methodinfo *method,
int *pos, int noindent);
+/* NOT AN OP */
java_objectheader *builtin_new(classinfo *c);
-
+#define BUILTIN_new (functionptr) builtin_new
java_arrayheader *builtin_newarray(s4 size, vftbl *arrayvftbl);
+#define BUILTIN_newarray (functionptr) builtin_newarray
java_objectarray *builtin_anewarray(s4 size, classinfo *component);
+/* NOT AN OP */
+
#if defined(__I386__)
void asm_builtin_newarray(s4 size, vftbl *arrayvftbl);
+#undef BUILTIN_newarray
+#define BUILTIN_newarray (functionptr) asm_builtin_newarray
#endif
+
java_booleanarray *builtin_newarray_boolean(s4 size);
+#define BUILTIN_newarray_boolean (functionptr) builtin_newarray_boolean
java_chararray *builtin_newarray_char(s4 size);
+#define BUILTIN_newarray_char (functionptr) builtin_newarray_char
java_floatarray *builtin_newarray_float(s4 size);
+#define BUILTIN_newarray_float (functionptr) builtin_newarray_float
java_doublearray *builtin_newarray_double(s4 size);
+#define BUILTIN_newarray_double (functionptr) builtin_newarray_double
java_bytearray *builtin_newarray_byte(s4 size);
+#define BUILTIN_newarray_byte (functionptr) builtin_newarray_byte
java_shortarray *builtin_newarray_short(s4 size);
+#define BUILTIN_newarray_short (functionptr) builtin_newarray_short
java_intarray *builtin_newarray_int(s4 size);
+#define BUILTIN_newarray_int (functionptr) builtin_newarray_int
java_longarray *builtin_newarray_long(s4 size);
+#define BUILTIN_newarray_long (functionptr) builtin_newarray_long
java_arrayheader *builtin_nmultianewarray(int n,
vftbl *arrayvftbl, long *dims);
+/* NOT AN OP */
s4 builtin_canstore(java_objectarray *a, java_objectheader *o);
+/* NOT AN OP */
void asm_builtin_aastore(java_objectarray *a, s4 index, java_objectheader *o);
+#define BUILTIN_aastore (functionptr) asm_builtin_aastore
#ifdef TRACE_ARGS_NUM
#if TRACE_ARGS_NUM == 6
void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5, methodinfo *method);
+/* NOT AN OP */
#else
void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5, s8 a6, s8 a7, methodinfo *method);
+/* NOT AN OP */
#endif
#endif
-void builtin_displaymethodstart(methodinfo *method);
+void builtin_displaymethodstart(methodinfo *method); /* XXX? */
+/* NOT AN OP */
void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f);
-/* void builtin_displaymethodstop(methodinfo *method); */
-void builtin_displaymethodexception(methodinfo *method);
+/* NOT AN OP */
+/* void builtin_displaymethodstop(methodinfo *method); */ /* XXX? */
+void builtin_displaymethodexception(methodinfo *method); /* XXX? */
+/* NOT AN OP */
void builtin_monitorenter(java_objectheader *o);
+/* NOT AN OP */
void asm_builtin_monitorenter(java_objectheader *o);
+#define BUILTIN_monitorenter (functionptr) asm_builtin_monitorenter
void builtin_monitorexit(java_objectheader *o);
+/* NOT AN OP */
void asm_builtin_monitorexit(java_objectheader *o);
+#define BUILTIN_monitorexit (functionptr) asm_builtin_monitorexit
-s4 builtin_idiv(s4 a, s4 b);
-s4 asm_builtin_idiv(s4 a, s4 b);
+s4 builtin_idiv(s4 a, s4 b);
+/* NOT AN OP */
+s4 asm_builtin_idiv(s4 a, s4 b);
+#define BUILTIN_idiv (functionptr) asm_builtin_idiv
s4 builtin_irem(s4 a, s4 b);
+/* NOT AN OP */
s4 asm_builtin_irem(s4 a, s4 b);
+#define BUILTIN_irem (functionptr) asm_builtin_irem
s8 builtin_ladd(s8 a, s8 b);
+#define BUILTIN_ladd (functionptr) builtin_ladd
s8 builtin_lsub(s8 a, s8 b);
+#define BUILTIN_lsub (functionptr) builtin_lsub
s8 builtin_lmul(s8 a, s8 b);
+#define BUILTIN_lmul (functionptr) builtin_lmul
s8 builtin_ldiv(s8 a, s8 b);
+/* NOT AN OP */
s8 asm_builtin_ldiv(s8 a, s8 b);
+#define BUILTIN_ldiv (functionptr) asm_builtin_ldiv
s8 builtin_lrem(s8 a, s8 b);
+/* NOT AN OP */
s8 asm_builtin_lrem(s8 a, s8 b);
+#define BUILTIN_lrem (functionptr) asm_builtin_lrem
s8 builtin_lshl(s8 a, s4 b);
+#define BUILTIN_lshl (functionptr) builtin_lshl
s8 builtin_lshr(s8 a, s4 b);
+#define BUILTIN_lshr (functionptr) builtin_lshr
s8 builtin_lushr(s8 a, s4 b);
+#define BUILTIN_lushr (functionptr) builtin_lushr
s8 builtin_land(s8 a, s8 b);
+#define BUILTIN_land (functionptr) builtin_land
s8 builtin_lor(s8 a, s8 b);
+#define BUILTIN_lor (functionptr) builtin_lor
s8 builtin_lxor(s8 a, s8 b);
+#define BUILTIN_lxor (functionptr) builtin_lxor
s8 builtin_lneg(s8 a);
+#define BUILTIN_lneg (functionptr) builtin_lneg
s4 builtin_lcmp(s8 a, s8 b);
-
-float builtin_fadd(float a, float b);
-float builtin_fsub(float a, float b);
-float builtin_fmul(float a, float b);
-float builtin_fdiv(float a, float b);
+#define BUILTIN_lcmp (functionptr) builtin_lcmp
+
+float builtin_fadd(float a, float b); /* XXX? */
+/* NOT AN OP */
+float builtin_fsub(float a, float b); /* XXX? */
+/* NOT AN OP */
+float builtin_fmul(float a, float b); /* XXX? */
+/* NOT AN OP */
+float builtin_fdiv(float a, float b); /* XXX? */
+/* NOT AN OP */
+float builtin_fneg(float a); /* XXX? */
+/* NOT AN OP */
+s4 builtin_fcmpl(float a, float b); /* XXX? */
+/* NOT AN OP */
+s4 builtin_fcmpg(float a, float b); /* XXX? */
+/* NOT AN OP */
float builtin_frem(float a, float b);
-float builtin_fneg(float a);
-s4 builtin_fcmpl(float a, float b);
-s4 builtin_fcmpg(float a, float b);
-
-double builtin_dadd(double a, double b);
-double builtin_dsub(double a, double b);
-double builtin_dmul(double a, double b);
-double builtin_ddiv(double a, double b);
+#define BUILTIN_frem (functionptr) builtin_frem
+
+double builtin_dadd(double a, double b); /* XXX? */
+/* NOT AN OP */
+double builtin_dsub(double a, double b); /* XXX? */
+/* NOT AN OP */
+double builtin_dmul(double a, double b); /* XXX? */
+/* NOT AN OP */
+double builtin_ddiv(double a, double b); /* XXX? */
+/* NOT AN OP */
+double builtin_dneg(double a); /* XXX? */
+/* NOT AN OP */
+s4 builtin_dcmpl(double a, double b); /* XXX? */
+/* NOT AN OP */
+s4 builtin_dcmpg(double a, double b); /* XXX? */
+/* NOT AN OP */
double builtin_drem(double a, double b);
-double builtin_dneg(double a);
-s4 builtin_dcmpl(double a, double b);
-s4 builtin_dcmpg(double a, double b);
+#define BUILTIN_drem (functionptr) builtin_drem
s8 builtin_i2l(s4 i);
+/* NOT AN OP */
float builtin_i2f(s4 i);
+#define BUILTIN_i2f (functionptr) builtin_i2f
double builtin_i2d(s4 i);
+#define BUILTIN_i2d (functionptr) builtin_i2d
s4 builtin_l2i(s8 l);
+/* NOT AN OP */
float builtin_l2f(s8 l);
+#define BUILTIN_l2f (functionptr) builtin_l2f
double builtin_l2d(s8 l);
+#define BUILTIN_l2d (functionptr) builtin_l2d
s4 builtin_f2i(float a);
+#define BUILTIN_f2i (functionptr) builtin_f2i
s4 asm_builtin_f2i(float a);
+/* NOT AN OP */
s8 builtin_f2l(float a);
+#define BUILTIN_f2l (functionptr) builtin_f2l
s8 asm_builtin_f2l(float a);
+/* NOT AN OP */
-double builtin_f2d(float a);
+double builtin_f2d(float a); /* XXX? */
+/* NOT AN OP */
s4 builtin_d2i(double a);
+#define BUILTIN_d2i (functionptr) builtin_d2i
s4 asm_builtin_d2i(double a);
+/* NOT AN OP */
s8 builtin_d2l(double a);
+#define BUILTIN_d2l (functionptr) builtin_d2l
s8 asm_builtin_d2l(double a);
+/* NOT AN OP */
-float builtin_d2f(double a);
+float builtin_d2f(double a); /* XXX? */
+/* NOT AN OP */
+java_arrayheader *builtin_clone_array(void *env, java_arrayheader *o);
+/* NOT AN OP */
/* conversion helper functions */
inline float intBitsToFloat(s4 i);
inline float longBitsToDouble(s8 l);
-java_arrayheader *builtin_clone_array(void *env, java_arrayheader *o);
-
#endif /* _BUILTIN_H */
Philipp Tomsich
Edwin Steiner
- $Id: global.h 723 2003-12-08 19:51:32Z edwin $
+ $Id: global.h 727 2003-12-11 10:52:40Z edwin $
*/
s4 offset; /* offset from start of object (instance variables) */
imm_union value; /* storage for static values (class variables) */
+
+ classinfo *class; /* XXX needed by typechecker. Could be optimized */
+ /* away by using constant_FMIref instead of */
+ /* fieldinfo throughout the compiler. */
xtafldinfo *xta;
};
Authors: Andreas Krall
Reinhard Grafl
- $Id: jit.c 725 2003-12-10 00:24:36Z edwin $
+ $Id: jit.c 727 2003-12-11 10:52:40Z edwin $
*/
#if defined(USEBUILTINTABLE)
+#if 0
stdopdescriptor builtintable[] = {
{ ICMD_LCMP, TYPE_LONG, TYPE_LONG, TYPE_INT, ICMD_BUILTIN2,
(functionptr) builtin_lcmp , SUPPORT_LONG && SUPPORT_LONG_CMP, false },
{ 255, 0, 0, 0, 0, NULL, true, false },
};
-static int builtintablelen;
+#endif
+int builtintablelen; /* XXX make static again? */
#endif /* USEBUILTINTABLE */
+/*****************************************************************************
+ TABLE OF BUILTIN FUNCTIONS
+
+ This table lists the builtin functions which are used inside
+ BUILTIN* opcodes.
+
+ The first part of the table (up to the 255-marker) lists the
+ opcodes which are automatically replaced in stack.c.
+
+ The second part lists the builtin functions which are used for
+ BUILTIN* opcodes in parse.c and stack.c.
+
+*****************************************************************************/
+
+builtin_descriptor builtin_desc[] = {
+ {ICMD_LCMP , BUILTIN_lcmp ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_INT ,
+ SUPPORT_LONG && SUPPORT_LONG_CMP,false,"lcmp"},
+
+ {ICMD_LAND , BUILTIN_land ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_LOG,false,"land"},
+ {ICMD_LOR , BUILTIN_lor ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_LOG,false,"lor"},
+ {ICMD_LXOR , BUILTIN_lxor ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_LOG,false,"lxor"},
+
+ {ICMD_LSHL , BUILTIN_lshl ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lshl"},
+ {ICMD_LSHR , BUILTIN_lshr ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lshr"},
+ {ICMD_LUSHR, BUILTIN_lushr,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lushr"},
+
+ {ICMD_LADD , BUILTIN_ladd ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_ADD,false,"ladd"},
+ {ICMD_LSUB , BUILTIN_lsub ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_ADD,false,"lsub"},
+ {ICMD_LNEG , BUILTIN_lneg ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_ADD,false,"lneg"},
+ {ICMD_LMUL , BUILTIN_lmul ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_MUL,false,"lmul"},
+
+ {ICMD_I2F , BUILTIN_i2f ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_FLOAT ,
+ SUPPORT_FLOAT && SUPPORT_IFCVT,true ,"i2f"},
+ {ICMD_I2D , BUILTIN_i2d ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_DOUBLE,
+ SUPPORT_DOUBLE && SUPPORT_IFCVT,true ,"i2d"},
+ {ICMD_L2F , BUILTIN_l2f ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_FLOAT ,
+ SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_LONG_FCVT,true ,"l2f"},
+ {ICMD_L2D , BUILTIN_l2d ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_DOUBLE,
+ SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_LONG_FCVT,true ,"l2d"},
+ {ICMD_F2L , BUILTIN_f2l ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_LONG_ICVT,true ,"f2l"},
+ {ICMD_D2L , BUILTIN_d2l ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_ICVT,true ,"d2l"},
+ {ICMD_F2I , BUILTIN_f2i ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID ,TYPE_VOID ,TYPE_INT ,
+ SUPPORT_FLOAT && SUPPORT_FICVT,true ,"f2i"},
+ {ICMD_D2I , BUILTIN_d2i ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID ,TYPE_VOID ,TYPE_INT ,
+ SUPPORT_DOUBLE && SUPPORT_FICVT,true ,"d2i"},
+
+ /* this record marks the end of the automatically replaced opcodes */
+ {255 , NULL ,0 ,0 ,0 ,0 ,0 ,
+ true ,false,"<INVALID>"},
+
+ /* the following functions are not replaced automatically */
+ {255,BUILTIN_instanceof ,ICMD_BUILTIN2,TYPE_ADR ,TYPE_ADR ,TYPE_VOID ,TYPE_INT ,0,0,"instanceof"},
+ {255,BUILTIN_arrayinstanceof ,ICMD_BUILTIN2,TYPE_ADR ,TYPE_ADR ,TYPE_VOID ,TYPE_INT ,0,0,"arrayinstanceof"},
+ {255,BUILTIN_checkarraycast ,ICMD_BUILTIN2,TYPE_ADR ,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,0,0,"checkarraycast"},
+ {255,BUILTIN_aastore ,ICMD_BUILTIN3,TYPE_ADR ,TYPE_INT ,TYPE_ADR ,TYPE_VOID ,0,0,"aastore"},
+ {255,BUILTIN_new ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"new"},
+ {255,BUILTIN_newarray ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray"},
+ {255,BUILTIN_newarray_boolean,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_boolean"},
+ {255,BUILTIN_newarray_char ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_char"},
+ {255,BUILTIN_newarray_float ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_float"},
+ {255,BUILTIN_newarray_double ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_double"},
+ {255,BUILTIN_newarray_byte ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_byte"},
+ {255,BUILTIN_newarray_short ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_short"},
+ {255,BUILTIN_newarray_int ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_int"},
+ {255,BUILTIN_newarray_long ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_long"},
+ {255,BUILTIN_monitorenter ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_VOID ,0,0,"monitorenter"},
+ {255,BUILTIN_monitorexit ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_VOID ,0,0,"monitorexit"},
+#if !SUPPORT_DIVISION
+ {255,BUILTIN_idiv ,ICMD_BUILTIN2,TYPE_INT ,TYPE_INT ,TYPE_VOID ,TYPE_INT ,0,0,"idiv"},
+ {255,BUILTIN_irem ,ICMD_BUILTIN2,TYPE_INT ,TYPE_INT ,TYPE_VOID ,TYPE_INT ,0,0,"irem"},
+#endif
+#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
+ {255,BUILTIN_ldiv ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,0,0,"ldiv"},
+ {255,BUILTIN_lrem ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,0,0,"lrem"},
+#endif
+ {255,BUILTIN_frem ,ICMD_BUILTIN2,TYPE_FLOAT ,TYPE_FLOAT ,TYPE_VOID ,TYPE_FLOAT ,0,0,"frem"},
+ {255,BUILTIN_drem ,ICMD_BUILTIN2,TYPE_DOUBLE,TYPE_DOUBLE,TYPE_VOID ,TYPE_DOUBLE,0,0,"drem"},
+
+ /* this record marks the end of the list */
+ { 0,NULL,0,0,0,0,0,0,0,"<END>"}
+};
+
/* include compiler subsystems ************************************************/
/* from codegen.inc */
#ifdef USEBUILTINTABLE
+/* XXX delete */
+#if 0
static int stdopcompare(const void *a, const void *b)
{
stdopdescriptor *o1 = (stdopdescriptor *) a;
return 1;
return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode);
}
+#endif
+static int stdopcompare(const void *a, const void *b)
+{
+ builtin_descriptor *o1 = (builtin_descriptor *) a;
+ builtin_descriptor *o2 = (builtin_descriptor *) b;
+ if (!o1->supported && o2->supported)
+ return -1;
+ if (o1->supported && !o2->supported)
+ return 1;
+ return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode);
+}
-
+/* XXX delete */
+#if 0
static inline void sort_builtintable()
{
int len;
len = sizeof(builtintable) / sizeof(stdopdescriptor);
- qsort(builtintable, len, sizeof(stdopdescriptor), stdopcompare);
+ qsort(builtintable, len, sizeof(builtin_descriptor), stdopcompare);
for (--len; len>=0 && builtintable[len].supported; len--);
builtintablelen = ++len;
}
#endif
}
+#endif
+
+static inline void sort_builtintable()
+{
+ int len;
+
+ len = 0;
+ while (builtin_desc[len].opcode != 255) len++;
+ qsort(builtin_desc, len, sizeof(builtin_descriptor), stdopcompare);
+
+ for (--len; len>=0 && builtin_desc[len].supported; len--);
+ builtintablelen = ++len;
+}
+#if 0
stdopdescriptor *find_builtin(int icmd)
{
- stdopdescriptor *first = builtintable;
- stdopdescriptor *last = builtintable + builtintablelen;
+ builtin_descriptor *first = builtintable;
+ builtin_descriptor *last = builtintable + builtintablelen;
+#endif
+builtin_descriptor *find_builtin(int icmd)
+{
+ builtin_descriptor *first = builtin_desc;
+ builtin_descriptor *last = builtin_desc + builtintablelen;
int len = last - first;
int half;
- stdopdescriptor *middle;
+ builtin_descriptor *middle;
while (len > 0) {
half = len / 2;
Changes: Christian Thalinger
- $Id: jit.h 723 2003-12-08 19:51:32Z edwin $
+ $Id: jit.h 727 2003-12-11 10:52:40Z edwin $
*/
#include "toolbox/chain.h"
#include "global.h"
+#include "builtin.h"
#include "typeinfo.h"
/**************************** resolve typedef-cycles **************************/
#if defined(USEBUILTINTABLE)
+/* XXX delete? */
+#if 0
typedef struct {
u1 opcode;
u1 type_s1;
extern stdopdescriptor builtintable[];
stdopdescriptor *find_builtin(int icmd);
+#endif
+
+builtin_descriptor *find_builtin(int opcode);
#endif /* USEBUILTINTABLE */
void removecompilerstub(u1 *stub);
void removenativestub(u1 *stub);
+void typecheck();
+
/* debug helpers (in stack.c) */
void icmd_print_stack(stackptr s);
+char *icmd_builtin_name(functionptr bptr);
void show_icmd_block(basicblock *bptr);
void show_icmd(instruction *iptr,bool deadcode);
void show_icmd_method();
Changes: Carolyn Oates
Edwin Steiner
- $Id: parse.c 726 2003-12-10 15:41:07Z edwin $
+ $Id: parse.c 727 2003-12-11 10:52:40Z edwin $
*/
OP2I(ICMD_CHECKASIZE, 0, 0);
switch (code_get_s1(p + 1)) {
case 4:
- BUILTIN1((functionptr) builtin_newarray_boolean, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_boolean, TYPE_ADR);
break;
case 5:
- BUILTIN1((functionptr) builtin_newarray_char, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_char, TYPE_ADR);
break;
case 6:
- BUILTIN1((functionptr) builtin_newarray_float, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_float, TYPE_ADR);
break;
case 7:
- BUILTIN1((functionptr) builtin_newarray_double, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_double, TYPE_ADR);
break;
case 8:
- BUILTIN1((functionptr) builtin_newarray_byte, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_byte, TYPE_ADR);
break;
case 9:
- BUILTIN1((functionptr) builtin_newarray_short, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_short, TYPE_ADR);
break;
case 10:
- BUILTIN1((functionptr) builtin_newarray_int, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_int, TYPE_ADR);
break;
case 11:
- BUILTIN1((functionptr) builtin_newarray_long, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_long, TYPE_ADR);
break;
default: panic("Invalid array-type to create");
}
s_count++;
-#if defined(__I386__)
- BUILTIN2((functionptr) asm_builtin_newarray, TYPE_ADR);
-#else
- BUILTIN2((functionptr)builtin_newarray, TYPE_ADR);
-#endif
+ BUILTIN2(BUILTIN_newarray, TYPE_ADR);
}
break;
/* load and store of object fields *******************/
case JAVA_AASTORE:
- BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
+ BUILTIN3(BUILTIN_aastore, TYPE_VOID);
break;
case JAVA_PUTSTATIC:
LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
s_count++;
- BUILTIN1((functionptr) builtin_new, TYPE_ADR);
+ BUILTIN1(BUILTIN_new, TYPE_ADR);
break;
case JAVA_CHECKCAST:
/* array type cast-check */
LOADCONST_A(cls->vftbl);
s_count++;
- BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
+ BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR);
}
else { /* object type cast-check */
/*
+ LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+ s_count++;
-+ BUILTIN2((functionptr) asm_builtin_checkcast, TYPE_ADR);
++ BUILTIN2(BUILTIN_checkcast, TYPE_ADR);
+ */
OP2A(opcode, 1, cls);
}
/* array type cast-check */
LOADCONST_A(cls->vftbl);
s_count++;
- #if defined(__I386__)
- BUILTIN2((functionptr) asm_builtin_arrayinstanceof, TYPE_INT);
- #else
- BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
- #endif
+ BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT);
}
else { /* object type cast-check */
/*
LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
s_count++;
- BUILTIN2((functionptr) builtin_instanceof, TYPE_INT);
+ BUILTIN2(BUILTIN_instanceof, TYPE_INT);
+ */
OP2A(opcode, 1, cls);
}
case JAVA_MONITORENTER:
#ifdef USE_THREADS
if (checksync) {
- BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+ BUILTIN1(BUILTIN_monitorenter, TYPE_VOID);
} else
#endif
{
case JAVA_MONITOREXIT:
#ifdef USE_THREADS
if (checksync) {
- BUILTIN1((functionptr) asm_builtin_monitorexit, TYPE_VOID);
+ BUILTIN1(BUILTIN_monitorexit, TYPE_VOID);
}
else
#endif
#if defined(__I386__)
OP(opcode);
#else
- BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
+ BUILTIN2(BUILTIN_frem, TYPE_FLOAT);
#endif
break;
#if defined(__I386__)
OP(opcode);
#else
- BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
+ BUILTIN2(BUILTIN_drem, TYPE_DOUBLE);
#endif
break;
case JAVA_F2I:
#if defined(__ALPHA__)
if (!opt_noieee) {
- BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
+ BUILTIN1(BUILTIN_f2i, TYPE_INT);
} else
#endif
{
case JAVA_F2L:
#if defined(__ALPHA__)
if (!opt_noieee) {
- BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
+ BUILTIN1(BUILTIN_f2l, TYPE_LONG);
} else
#endif
{
case JAVA_D2I:
#if defined(__ALPHA__)
if (!opt_noieee) {
- BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
+ BUILTIN1(BUILTIN_d2i, TYPE_INT);
} else
#endif
{
case JAVA_D2L:
#if defined(__ALPHA__)
if (!opt_noieee) {
- BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
+ BUILTIN1(BUILTIN_d2l, TYPE_LONG);
} else
#endif
{
Changes: Edwin Steiner
- $Id: stack.c 725 2003-12-10 00:24:36Z edwin $
+ $Id: stack.c 727 2003-12-11 10:52:40Z edwin $
*/
#ifdef USEBUILTINTABLE
{
+#if 0
stdopdescriptor *breplace;
breplace = find_builtin(opcode);
+ if (breplace && opcode == breplace->opcode) {
+ iptr[0].opc = breplace->icmd;
+ iptr[0].op1 = breplace->type_d;
+ iptr[0].val.a = breplace->builtin;
+ isleafmethod = false;
+ switch (breplace->icmd) {
+ case ICMD_BUILTIN1:
+ goto builtin1;
+ case ICMD_BUILTIN2:
+ goto builtin2;
+ }
+ }
+#endif
+ builtin_descriptor *breplace;
+ breplace = find_builtin(opcode);
+
if (breplace && opcode == breplace->opcode) {
iptr[0].opc = breplace->icmd;
iptr[0].op1 = breplace->type_d;
#if !SUPPORT_DIVISION
iptr[0].opc = ICMD_BUILTIN2;
iptr[0].op1 = TYPE_INT;
- iptr[0].val.a = (functionptr) asm_builtin_idiv;
+ iptr[0].val.a = BUILTIN_idiv;
isleafmethod = false;
goto builtin2;
#endif
#if !SUPPORT_DIVISION
iptr[0].opc = ICMD_BUILTIN2;
iptr[0].op1 = TYPE_INT;
- iptr[0].val.a = (functionptr) asm_builtin_irem;
+ iptr[0].val.a = BUILTIN_irem;
isleafmethod = false;
goto builtin2;
#endif
#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
iptr[0].opc = ICMD_BUILTIN2;
iptr[0].op1 = TYPE_LNG;
- iptr[0].val.a = (functionptr) asm_builtin_ldiv;
+ iptr[0].val.a = BUILTIN_ldiv;
isleafmethod = false;
goto builtin2;
#endif
#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
iptr[0].opc = ICMD_BUILTIN2;
iptr[0].op1 = TYPE_LNG;
- iptr[0].val.a = (functionptr) asm_builtin_lrem;
+ iptr[0].val.a = BUILTIN_lrem;
isleafmethod = false;
goto builtin2;
#endif
char *icmd_builtin_name(functionptr bptr)
{
builtin_descriptor *bdesc = builtin_desc;
- while ((bdesc->bptr != NULL) && (bdesc->bptr != bptr))
+ while ((bdesc->opcode != 0) && (bdesc->builtin != bptr))
bdesc++;
- return bdesc->name;
+ return (bdesc->opcode) ? bdesc->name : "<NOT IN TABLE>";
}
case ICMD_PUTSTATIC:
case ICMD_GETSTATIC:
printf(" ");
+ utf_fprint(stdout,
+ ((fieldinfo *) iptr->val.a)->class->name);
+ printf(".");
utf_fprint(stdout,
((fieldinfo *) iptr->val.a)->name);
+ printf(" (type ");
+ utf_fprint(stdout,
+ ((fieldinfo *) iptr->val.a)->descriptor);
+ printf(")");
break;
case ICMD_IINC:
printf(" %d + %d", iptr->op1, iptr->val.i);
((classinfo *) iptr->val.a)->name);
}
break;
+ case ICMD_MULTIANEWARRAY:
+ {
+ vftbl *vft;
+ printf(" %d ",iptr->op1);
+ vft = (vftbl *)iptr->val.a;
+ if (vft)
+ utf_fprint(stdout,vft->class->name);
+ else
+ printf("<null>");
+ }
+ break;
case ICMD_CHECKCAST:
case ICMD_INSTANCEOF:
if (iptr->op1) {
Authors: Edwin Steiner
- $Id: typecheck.c 726 2003-12-10 15:41:07Z edwin $
+ $Id: typecheck.c 727 2003-12-11 10:52:40Z edwin $
*/
#define TYPECHECK_FLT(sp) TYPECHECK_STACK(sp,TYPE_FLT)
#define TYPECHECK_DBL(sp) TYPECHECK_STACK(sp,TYPE_DBL)
+#define TYPECHECK_ARGS1(t1) \
+ do {TYPECHECK_STACK(curstack,t1);} while (0)
+#define TYPECHECK_ARGS2(t1,t2) \
+ do {TYPECHECK_ARGS1(t1); \
+ TYPECHECK_STACK(curstack->prev,t2);} while (0)
+#define TYPECHECK_ARGS3(t1,t2,t3) \
+ do {TYPECHECK_ARGS2(t1,t2); \
+ TYPECHECK_STACK(curstack->prev->prev,t3);} while (0)
+
/* TYPECHECK_COPYVARS: copy the types and typeinfos of the current local
* variables to the local variables of the target block.
* Input:
bool maythrow; /* true if this instruction may throw */
utf *name_init; /* "<init>" */
bool initmethod; /* true if this is an "<init>" method */
+ builtin_descriptor *builtindesc;
#ifdef TYPECHECK_STATISTICS
int count_iterations = 0;
if (TYPEINFO_IS_ARRAY(curstack->prev->typeinfo)) /* XXX arraystub */
panic("illegal instruction: PUTFIELD on array");
-
- /* XXX */
+ /* check if the value is assignable to the field */
+ {
+ fieldinfo *fi = (fieldinfo*) iptr[0].val.a;
+
+ if (!TYPEINFO_IS_NULLTYPE(curstack->prev->typeinfo)) {
+ cls = fi->class;
+ /* XXX treat uinitialized objects specially? */
+ if (!class_issubclass(curstack->prev->typeinfo.typeclass,
+ cls))
+ panic("PUTFIELD reference type does not support field");
+ }
+
+ /* XXX check flags */
+
+ /* XXX ---> unify with ICMD_PUTSTATIC? */
+
+ /* XXX check access rights */
+
+ if (curstack->type != fi->type)
+ panic("PUTFIELD type mismatch");
+ if (fi->type == TYPE_ADR) {
+ TYPEINFO_INIT_FROM_FIELDINFO(rinfo,fi);
+ if (!typeinfo_is_assignable(&(curstack->typeinfo),
+ &rinfo))
+ panic("PUTFIELD reference type not assignable");
+ }
+ }
maythrow = true;
break;
case ICMD_PUTSTATIC:
- /* XXX */
+ /* check if the value is assignable to the field */
+ {
+ fieldinfo *fi = (fieldinfo*) iptr[0].val.a;
+
+ /* check flags */
+ /* XXX check access rights */
+
+ if (curstack->type != fi->type)
+ panic("PUTSTATIC type mismatch");
+ if (fi->type == TYPE_ADR) {
+ TYPEINFO_INIT_FROM_FIELDINFO(rinfo,fi);
+ if (!typeinfo_is_assignable(&(curstack->typeinfo),
+ &rinfo))
+ panic("PUTSTATIC reference type not assignable");
+ }
+ }
maythrow = true;
break;
{
fieldinfo *fi = (fieldinfo *)(iptr->val.a);
- /* XXX check non-static? */
+
+ if (!TYPEINFO_IS_NULLTYPE(curstack->typeinfo)) {
+ cls = fi->class;
+ if (!class_issubclass(curstack->typeinfo.typeclass,
+ cls))
+ panic("GETFIELD reference type does not support field");
+ }
+
+ /* XXX check flags */
+ /* XXX check access rights */
if (dst->type == TYPE_ADR) {
TYPEINFO_INIT_FROM_FIELDINFO(dst->typeinfo,fi);
}
case ICMD_GETSTATIC:
{
fieldinfo *fi = (fieldinfo *)(iptr->val.a);
- /* XXX check static? */
+ /* XXX check flags */
+ /* XXX check access rights */
if (dst->type == TYPE_ADR) {
TYPEINFO_INIT_FROM_FIELDINFO(dst->typeinfo,fi);
}
break;
case ICMD_MULTIANEWARRAY:
- /* check the array lengths on the stack */
- i = iptr[0].op1;
- if (i<1) panic("MULTIANEWARRAY with dimensions < 1");
- srcstack = curstack;
- while (i--) {
- if (!srcstack)
- panic("MULTIANEWARRAY missing array length");
- if (srcstack->type != TYPE_INT)
- panic("MULTIANEWARRAY using non-int as array length");
- srcstack = srcstack->prev;
- }
-
- /* set the array type of the result */
- TYPEINFO_INIT_CLASSINFO(dst->typeinfo,((vftbl *)iptr[0].val.a)->class);
+ {
+ vftbl *arrayvftbl;
+ arraydescriptor *desc;
+
+ /* check the array lengths on the stack */
+ i = iptr[0].op1;
+ if (i<1) panic("MULTIANEWARRAY with dimensions < 1");
+ srcstack = curstack;
+ while (i--) {
+ if (!srcstack)
+ panic("MULTIANEWARRAY missing array length");
+ if (srcstack->type != TYPE_INT)
+ panic("MULTIANEWARRAY using non-int as array length");
+ srcstack = srcstack->prev;
+ }
+
+ /* check array descriptor */
+ arrayvftbl = (vftbl*) iptr[0].val.a;
+ if (!arrayvftbl)
+ panic("MULTIANEWARRAY with unlinked class");
+ if ((desc = arrayvftbl->arraydesc) == NULL)
+ panic("MULTIANEWARRAY with non-array class");
+ if (desc->dimension < iptr[0].op1)
+ panic("MULTIANEWARRAY dimension to high");
+
+ /* set the array type of the result */
+ TYPEINFO_INIT_CLASSINFO(dst->typeinfo,arrayvftbl->class);
+ }
maythrow = true;
break;
case ICMD_BUILTIN3:
- if (ISBUILTIN(asm_builtin_aastore)) {
+ if (ISBUILTIN(BUILTIN_aastore)) {
TYPECHECK_ADR(curstack);
TYPECHECK_INT(curstack->prev);
TYPECHECK_ADR(curstack->prev->prev);
panic("illegal instruction: AASTORE to incompatible type");
*/
}
- /* XXX check for missed builtins in debug mode? */
+ else {
+ builtindesc = builtin_desc;
+ while (builtindesc->opcode && builtindesc->builtin
+ != (functionptr) iptr->val.a) builtindesc++;
+ if (!builtindesc->opcode) {
+ dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+ panic("Internal error: builtin not found in table");
+ }
+ TYPECHECK_ARGS3(builtindesc->type_s3,builtindesc->type_s2,builtindesc->type_s1);
+ }
maythrow = true; /* XXX better safe than sorry */
break;
case ICMD_BUILTIN2:
- if (
-#if defined(__I386__)
- ISBUILTIN(asm_builtin_newarray)
-#else
- ISBUILTIN(builtin_newarray)
-#endif
- )
+ /* XXX use BUILTIN_ macros */
+ if (ISBUILTIN(BUILTIN_newarray))
{
+ vftbl *vft;
TYPECHECK_INT(curstack->prev);
if (iptr[-1].opc != ICMD_ACONST)
panic("illegal instruction: builtin_newarray without classinfo");
- TYPEINFO_INIT_CLASSINFO(dst->typeinfo,((vftbl *)iptr[-1].val.a)->class);
+ vft = (vftbl *)iptr[-1].val.a;
+ if (!vft)
+ panic("ANEWARRAY with unlinked class");
+ if (!vft->arraydesc)
+ panic("ANEWARRAY with non-array class");
+ TYPEINFO_INIT_CLASSINFO(dst->typeinfo,vft->class);
}
- else if (ISBUILTIN(asm_builtin_checkarraycast)) {
+ else if (ISBUILTIN(BUILTIN_arrayinstanceof))
+ {
+ vftbl *vft;
+ TYPECHECK_ADR(curstack->prev);
+ if (iptr[-1].opc != ICMD_ACONST)
+ panic("illegal instruction: builtin_arrayinstanceof without classinfo");
+ vft = (vftbl *)iptr[-1].val.a;
+ if (!vft)
+ panic("INSTANCEOF with unlinked class");
+ if (!vft->arraydesc)
+ panic("internal error: builtin_arrayinstanceof with non-array class");
+ }
+ else if (ISBUILTIN(BUILTIN_checkarraycast)) {
+ vftbl *vft;
TYPECHECK_ADR(curstack->prev);
if (iptr[-1].opc != ICMD_ACONST)
- panic("illegal instruction: asm_builtin_checkarraycast without classinfo");
- TYPEINFO_INIT_CLASSINFO(dst->typeinfo,((vftbl *)iptr[-1].val.a)->class);
+ panic("illegal instruction: BUILTIN_checkarraycast without classinfo");
+ vft = (vftbl *)iptr[-1].val.a;
+ if (!vft)
+ panic("CHECKCAST with unlinked class");
+ if (!vft->arraydesc)
+ panic("internal error: builtin_checkarraycast with non-array class");
+ TYPEINFO_INIT_CLASSINFO(dst->typeinfo,vft->class);
}
- /* XXX check for missed builtins in debug mode? */
+ else {
+ builtindesc = builtin_desc;
+ while (builtindesc->opcode && builtindesc->builtin
+ != (functionptr) iptr->val.a) builtindesc++;
+ if (!builtindesc->opcode) {
+ dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+ panic("Internal error: builtin not found in table");
+ }
+ TYPECHECK_ARGS2(builtindesc->type_s2,builtindesc->type_s1);
+ }
maythrow = true; /* XXX better safe than sorry */
break;
case ICMD_BUILTIN1:
- if (ISBUILTIN(builtin_new)) {
+ if (ISBUILTIN(BUILTIN_new)) {
if (iptr[-1].opc != ICMD_ACONST)
panic("illegal instruction: builtin_new without classinfo");
TYPEINFO_INIT_NEWOBJECT(dst->typeinfo,iptr);
}
/* XXX unify the following cases */
- else if (ISBUILTIN(builtin_newarray_boolean)) {
+ else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_BOOLEAN);
}
- else if (ISBUILTIN(builtin_newarray_char)) {
+ else if (ISBUILTIN(BUILTIN_newarray_char)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_CHAR);
}
- else if (ISBUILTIN(builtin_newarray_float)) {
+ else if (ISBUILTIN(BUILTIN_newarray_float)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_FLOAT);
}
- else if (ISBUILTIN(builtin_newarray_double)) {
+ else if (ISBUILTIN(BUILTIN_newarray_double)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_DOUBLE);
}
- else if (ISBUILTIN(builtin_newarray_byte)) {
+ else if (ISBUILTIN(BUILTIN_newarray_byte)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_BYTE);
}
- else if (ISBUILTIN(builtin_newarray_short)) {
+ else if (ISBUILTIN(BUILTIN_newarray_short)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_SHORT);
}
- else if (ISBUILTIN(builtin_newarray_int)) {
+ else if (ISBUILTIN(BUILTIN_newarray_int)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_INT);
}
- else if (ISBUILTIN(builtin_newarray_long)) {
+ else if (ISBUILTIN(BUILTIN_newarray_long)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_LONG);
}
- /* XXX check for missed builtins in debug mode? */
+ else {
+ builtindesc = builtin_desc;
+ while (builtindesc->opcode && builtindesc->builtin
+ != (functionptr) iptr->val.a) builtindesc++;
+ if (!builtindesc->opcode) {
+ dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+ panic("Internal error: builtin not found in table");
+ }
+ TYPECHECK_ARGS1(builtindesc->type_s1);
+ }
maythrow = true; /* XXX better safe than sorry */
break;
for (i=0; i<block_count; ++i) {
if (block[i].flags != BBDELETED
&& block[i].flags != BBUNDEF
- && block[i].flags != BBFINISHED)
+ && block[i].flags != BBFINISHED
+ && block[i].flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
+ * some exception handlers,
+ * that's ok. */
{
LOG2("block L%03d has invalid flags after typecheck: %d",
block[i].debug_nr,block[i].flags);
}
}
#endif
-
+
+ /* Reset blocks we never reached */
+ for (i=0; i<block_count; ++i) {
+ if (block[i].flags == BBTYPECHECK_UNDEF)
+ block[i].flags = BBFINISHED;
+ }
+
LOGimp("exiting typecheck");
}
Mark Probst
Edwin Steiner
- $Id: loader.c 726 2003-12-10 15:41:07Z edwin $
+ $Id: loader.c 727 2003-12-11 10:52:40Z edwin $
*/
static u1 *classbuf_pos; /* current position in classfile buffer */
static int classbuffer_size; /* size of classfile-data */
-#define ASSERT_LEFT(len) \
- do {if (((classbuffer + classbuffer_size) - classbuf_pos - 1) < (len)) \
+/* assert that at least <len> bytes are left to read */
+/* <len> is limited to the range of non-negative s4 values */
+#define ASSERT_LEFT(len) \
+ do {if ( ((s4)(len)) < 0 \
+ || ((classbuffer + classbuffer_size) - classbuf_pos - 1) < (len)) \
panic("Unexpected end of classfile"); } while(0)
/* transfer block of classfile data into a buffer */
f -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8); /* JavaVM descriptor */
f -> type = jtype = desc_to_type (f->descriptor); /* data type */
f -> offset = 0; /* offset from start of object */
+ f -> class = c;
f->xta = NULL;
switch (f->type) {
calls instead of machine instructions, using the C calling
convention.
- $Id: builtin.c 718 2003-12-08 13:03:43Z jowenn $
+ $Id: builtin.c 727 2003-12-11 10:52:40Z edwin $
*/
#undef DEBUG /*define DEBUG 1*/
+/* XXX delete? */
+#if 0
builtin_descriptor builtin_desc[] = {
{(functionptr) builtin_instanceof, "instanceof"},
{(functionptr) builtin_checkcast, "checkcast"},
{(functionptr) builtin_d2f, "d2f"},
{(functionptr) NULL, "unknown"}
};
+#endif
/*****************************************************************************
Authors: Reinhard Grafl
- $Id: builtin.h 716 2003-12-07 21:59:12Z twisti $
+ $Id: builtin.h 727 2003-12-11 10:52:40Z edwin $
*/
#define DBL_POSINF 0x7ff0000000000000LL
#define DBL_NEGINF 0xfff0000000000000LL
-
+/* XXX delete */
+#if 0
typedef struct builtin_descriptor {
functionptr bptr;
char *name;
} builtin_descriptor;
+#endif
+
+typedef struct builtin_descriptor builtin_descriptor;
+
+struct builtin_descriptor {
+ int opcode;
+ functionptr builtin;
+ int icmd;
+ u1 type_s1;
+ u1 type_s2;
+ u1 type_s3;
+ u1 type_d;
+ bool supported;
+ bool isfloat;
+ char *name;
+};
extern builtin_descriptor builtin_desc[];
+extern int builtintablelen;
+
extern java_objectheader* exceptionptr;
-/* function prototypes */
+/**********************************************************************/
+/* BUILTIN FUNCTIONS */
+/**********************************************************************/
+
+/* NOTE: Builtin functions which are used in the BUILTIN* opcodes must
+ * have a BUILTIN_... macro defined as seen below. In code dealing
+ * with the BUILTIN* opcodes the functions may only be addressed by
+ * these macros, never by their actual name! (This helps to make this
+ * code more portable.)
+ *
+ * C and assembler code which does not deal with the BUILTIN* opcodes,
+ * can use the builtin functions normally (like all other functions).
+ *
+ * IMPORTANT:
+ * For each builtin function which is used in a BUILTIN* opcode there
+ * must be an entry in the builtin_desc table in builtin.c!
+ *
+ * Below each prototype is either the BUILTIN_ macro definition or a
+ * comment specifiying that this function is not used in BUILTIN*
+ * opcodes.
+ *
+ * (The BUILTIN* opcodes are ICMD_BUILTIN1, ICMD_BUILTIN2 and
+ * ICMD_BUILTIN3.)
+ */
s4 builtin_instanceof(java_objectheader *obj, classinfo *class);
+#define BUILTIN_instanceof (functionptr) builtin_instanceof
s4 builtin_isanysubclass (classinfo *sub, classinfo *super);
+/* NOT AN OP */
s4 builtin_isanysubclass_vftbl (vftbl *sub, vftbl *super);
+/* NOT AN OP */
s4 builtin_checkcast(java_objectheader *obj, classinfo *class);
-s4 asm_builtin_checkcast(java_objectheader *obj, classinfo *class);
-
+/* NOT AN OP */
s4 builtin_arrayinstanceof(java_objectheader *obj, vftbl *target);
+#define BUILTIN_arrayinstanceof (functionptr) builtin_arrayinstanceof
+
#if defined(__I386__)
s4 asm_builtin_arrayinstanceof(java_objectheader *obj, classinfo *class); /* XXX ? */
+#undef BUILTIN_arrayinstanceof
+#define BUILTIN_arrayinstanceof (functionptr) asm_builtin_arrayinstanceof
#endif
+
s4 builtin_checkarraycast(java_objectheader *obj, vftbl *target);
+/* NOT AN OP */
s4 asm_builtin_checkarraycast(java_objectheader *obj, vftbl *target);
+#define BUILTIN_checkarraycast (functionptr) asm_builtin_checkarraycast
java_objectheader *builtin_throw_exception(java_objectheader *exception);
+/* NOT AN OP */
java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
methodinfo *method,
int *pos, int noindent);
+/* NOT AN OP */
java_objectheader *builtin_new(classinfo *c);
-
+#define BUILTIN_new (functionptr) builtin_new
java_arrayheader *builtin_newarray(s4 size, vftbl *arrayvftbl);
+#define BUILTIN_newarray (functionptr) builtin_newarray
java_objectarray *builtin_anewarray(s4 size, classinfo *component);
+/* NOT AN OP */
+
#if defined(__I386__)
void asm_builtin_newarray(s4 size, vftbl *arrayvftbl);
+#undef BUILTIN_newarray
+#define BUILTIN_newarray (functionptr) asm_builtin_newarray
#endif
+
java_booleanarray *builtin_newarray_boolean(s4 size);
+#define BUILTIN_newarray_boolean (functionptr) builtin_newarray_boolean
java_chararray *builtin_newarray_char(s4 size);
+#define BUILTIN_newarray_char (functionptr) builtin_newarray_char
java_floatarray *builtin_newarray_float(s4 size);
+#define BUILTIN_newarray_float (functionptr) builtin_newarray_float
java_doublearray *builtin_newarray_double(s4 size);
+#define BUILTIN_newarray_double (functionptr) builtin_newarray_double
java_bytearray *builtin_newarray_byte(s4 size);
+#define BUILTIN_newarray_byte (functionptr) builtin_newarray_byte
java_shortarray *builtin_newarray_short(s4 size);
+#define BUILTIN_newarray_short (functionptr) builtin_newarray_short
java_intarray *builtin_newarray_int(s4 size);
+#define BUILTIN_newarray_int (functionptr) builtin_newarray_int
java_longarray *builtin_newarray_long(s4 size);
+#define BUILTIN_newarray_long (functionptr) builtin_newarray_long
java_arrayheader *builtin_nmultianewarray(int n,
vftbl *arrayvftbl, long *dims);
+/* NOT AN OP */
s4 builtin_canstore(java_objectarray *a, java_objectheader *o);
+/* NOT AN OP */
void asm_builtin_aastore(java_objectarray *a, s4 index, java_objectheader *o);
+#define BUILTIN_aastore (functionptr) asm_builtin_aastore
#ifdef TRACE_ARGS_NUM
#if TRACE_ARGS_NUM == 6
void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5, methodinfo *method);
+/* NOT AN OP */
#else
void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5, s8 a6, s8 a7, methodinfo *method);
+/* NOT AN OP */
#endif
#endif
-void builtin_displaymethodstart(methodinfo *method);
+void builtin_displaymethodstart(methodinfo *method); /* XXX? */
+/* NOT AN OP */
void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f);
-/* void builtin_displaymethodstop(methodinfo *method); */
-void builtin_displaymethodexception(methodinfo *method);
+/* NOT AN OP */
+/* void builtin_displaymethodstop(methodinfo *method); */ /* XXX? */
+void builtin_displaymethodexception(methodinfo *method); /* XXX? */
+/* NOT AN OP */
void builtin_monitorenter(java_objectheader *o);
+/* NOT AN OP */
void asm_builtin_monitorenter(java_objectheader *o);
+#define BUILTIN_monitorenter (functionptr) asm_builtin_monitorenter
void builtin_monitorexit(java_objectheader *o);
+/* NOT AN OP */
void asm_builtin_monitorexit(java_objectheader *o);
+#define BUILTIN_monitorexit (functionptr) asm_builtin_monitorexit
-s4 builtin_idiv(s4 a, s4 b);
-s4 asm_builtin_idiv(s4 a, s4 b);
+s4 builtin_idiv(s4 a, s4 b);
+/* NOT AN OP */
+s4 asm_builtin_idiv(s4 a, s4 b);
+#define BUILTIN_idiv (functionptr) asm_builtin_idiv
s4 builtin_irem(s4 a, s4 b);
+/* NOT AN OP */
s4 asm_builtin_irem(s4 a, s4 b);
+#define BUILTIN_irem (functionptr) asm_builtin_irem
s8 builtin_ladd(s8 a, s8 b);
+#define BUILTIN_ladd (functionptr) builtin_ladd
s8 builtin_lsub(s8 a, s8 b);
+#define BUILTIN_lsub (functionptr) builtin_lsub
s8 builtin_lmul(s8 a, s8 b);
+#define BUILTIN_lmul (functionptr) builtin_lmul
s8 builtin_ldiv(s8 a, s8 b);
+/* NOT AN OP */
s8 asm_builtin_ldiv(s8 a, s8 b);
+#define BUILTIN_ldiv (functionptr) asm_builtin_ldiv
s8 builtin_lrem(s8 a, s8 b);
+/* NOT AN OP */
s8 asm_builtin_lrem(s8 a, s8 b);
+#define BUILTIN_lrem (functionptr) asm_builtin_lrem
s8 builtin_lshl(s8 a, s4 b);
+#define BUILTIN_lshl (functionptr) builtin_lshl
s8 builtin_lshr(s8 a, s4 b);
+#define BUILTIN_lshr (functionptr) builtin_lshr
s8 builtin_lushr(s8 a, s4 b);
+#define BUILTIN_lushr (functionptr) builtin_lushr
s8 builtin_land(s8 a, s8 b);
+#define BUILTIN_land (functionptr) builtin_land
s8 builtin_lor(s8 a, s8 b);
+#define BUILTIN_lor (functionptr) builtin_lor
s8 builtin_lxor(s8 a, s8 b);
+#define BUILTIN_lxor (functionptr) builtin_lxor
s8 builtin_lneg(s8 a);
+#define BUILTIN_lneg (functionptr) builtin_lneg
s4 builtin_lcmp(s8 a, s8 b);
-
-float builtin_fadd(float a, float b);
-float builtin_fsub(float a, float b);
-float builtin_fmul(float a, float b);
-float builtin_fdiv(float a, float b);
+#define BUILTIN_lcmp (functionptr) builtin_lcmp
+
+float builtin_fadd(float a, float b); /* XXX? */
+/* NOT AN OP */
+float builtin_fsub(float a, float b); /* XXX? */
+/* NOT AN OP */
+float builtin_fmul(float a, float b); /* XXX? */
+/* NOT AN OP */
+float builtin_fdiv(float a, float b); /* XXX? */
+/* NOT AN OP */
+float builtin_fneg(float a); /* XXX? */
+/* NOT AN OP */
+s4 builtin_fcmpl(float a, float b); /* XXX? */
+/* NOT AN OP */
+s4 builtin_fcmpg(float a, float b); /* XXX? */
+/* NOT AN OP */
float builtin_frem(float a, float b);
-float builtin_fneg(float a);
-s4 builtin_fcmpl(float a, float b);
-s4 builtin_fcmpg(float a, float b);
-
-double builtin_dadd(double a, double b);
-double builtin_dsub(double a, double b);
-double builtin_dmul(double a, double b);
-double builtin_ddiv(double a, double b);
+#define BUILTIN_frem (functionptr) builtin_frem
+
+double builtin_dadd(double a, double b); /* XXX? */
+/* NOT AN OP */
+double builtin_dsub(double a, double b); /* XXX? */
+/* NOT AN OP */
+double builtin_dmul(double a, double b); /* XXX? */
+/* NOT AN OP */
+double builtin_ddiv(double a, double b); /* XXX? */
+/* NOT AN OP */
+double builtin_dneg(double a); /* XXX? */
+/* NOT AN OP */
+s4 builtin_dcmpl(double a, double b); /* XXX? */
+/* NOT AN OP */
+s4 builtin_dcmpg(double a, double b); /* XXX? */
+/* NOT AN OP */
double builtin_drem(double a, double b);
-double builtin_dneg(double a);
-s4 builtin_dcmpl(double a, double b);
-s4 builtin_dcmpg(double a, double b);
+#define BUILTIN_drem (functionptr) builtin_drem
s8 builtin_i2l(s4 i);
+/* NOT AN OP */
float builtin_i2f(s4 i);
+#define BUILTIN_i2f (functionptr) builtin_i2f
double builtin_i2d(s4 i);
+#define BUILTIN_i2d (functionptr) builtin_i2d
s4 builtin_l2i(s8 l);
+/* NOT AN OP */
float builtin_l2f(s8 l);
+#define BUILTIN_l2f (functionptr) builtin_l2f
double builtin_l2d(s8 l);
+#define BUILTIN_l2d (functionptr) builtin_l2d
s4 builtin_f2i(float a);
+#define BUILTIN_f2i (functionptr) builtin_f2i
s4 asm_builtin_f2i(float a);
+/* NOT AN OP */
s8 builtin_f2l(float a);
+#define BUILTIN_f2l (functionptr) builtin_f2l
s8 asm_builtin_f2l(float a);
+/* NOT AN OP */
-double builtin_f2d(float a);
+double builtin_f2d(float a); /* XXX? */
+/* NOT AN OP */
s4 builtin_d2i(double a);
+#define BUILTIN_d2i (functionptr) builtin_d2i
s4 asm_builtin_d2i(double a);
+/* NOT AN OP */
s8 builtin_d2l(double a);
+#define BUILTIN_d2l (functionptr) builtin_d2l
s8 asm_builtin_d2l(double a);
+/* NOT AN OP */
-float builtin_d2f(double a);
+float builtin_d2f(double a); /* XXX? */
+/* NOT AN OP */
+java_arrayheader *builtin_clone_array(void *env, java_arrayheader *o);
+/* NOT AN OP */
/* conversion helper functions */
inline float intBitsToFloat(s4 i);
inline float longBitsToDouble(s8 l);
-java_arrayheader *builtin_clone_array(void *env, java_arrayheader *o);
-
#endif /* _BUILTIN_H */
Philipp Tomsich
Edwin Steiner
- $Id: global.h 723 2003-12-08 19:51:32Z edwin $
+ $Id: global.h 727 2003-12-11 10:52:40Z edwin $
*/
s4 offset; /* offset from start of object (instance variables) */
imm_union value; /* storage for static values (class variables) */
+
+ classinfo *class; /* XXX needed by typechecker. Could be optimized */
+ /* away by using constant_FMIref instead of */
+ /* fieldinfo throughout the compiler. */
xtafldinfo *xta;
};
Authors: Andreas Krall
Reinhard Grafl
- $Id: jit.c 725 2003-12-10 00:24:36Z edwin $
+ $Id: jit.c 727 2003-12-11 10:52:40Z edwin $
*/
#if defined(USEBUILTINTABLE)
+#if 0
stdopdescriptor builtintable[] = {
{ ICMD_LCMP, TYPE_LONG, TYPE_LONG, TYPE_INT, ICMD_BUILTIN2,
(functionptr) builtin_lcmp , SUPPORT_LONG && SUPPORT_LONG_CMP, false },
{ 255, 0, 0, 0, 0, NULL, true, false },
};
-static int builtintablelen;
+#endif
+int builtintablelen; /* XXX make static again? */
#endif /* USEBUILTINTABLE */
+/*****************************************************************************
+ TABLE OF BUILTIN FUNCTIONS
+
+ This table lists the builtin functions which are used inside
+ BUILTIN* opcodes.
+
+ The first part of the table (up to the 255-marker) lists the
+ opcodes which are automatically replaced in stack.c.
+
+ The second part lists the builtin functions which are used for
+ BUILTIN* opcodes in parse.c and stack.c.
+
+*****************************************************************************/
+
+builtin_descriptor builtin_desc[] = {
+ {ICMD_LCMP , BUILTIN_lcmp ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_INT ,
+ SUPPORT_LONG && SUPPORT_LONG_CMP,false,"lcmp"},
+
+ {ICMD_LAND , BUILTIN_land ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_LOG,false,"land"},
+ {ICMD_LOR , BUILTIN_lor ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_LOG,false,"lor"},
+ {ICMD_LXOR , BUILTIN_lxor ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_LOG,false,"lxor"},
+
+ {ICMD_LSHL , BUILTIN_lshl ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lshl"},
+ {ICMD_LSHR , BUILTIN_lshr ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lshr"},
+ {ICMD_LUSHR, BUILTIN_lushr,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lushr"},
+
+ {ICMD_LADD , BUILTIN_ladd ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_ADD,false,"ladd"},
+ {ICMD_LSUB , BUILTIN_lsub ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_ADD,false,"lsub"},
+ {ICMD_LNEG , BUILTIN_lneg ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_ADD,false,"lneg"},
+ {ICMD_LMUL , BUILTIN_lmul ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_LONG && SUPPORT_LONG_MUL,false,"lmul"},
+
+ {ICMD_I2F , BUILTIN_i2f ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_FLOAT ,
+ SUPPORT_FLOAT && SUPPORT_IFCVT,true ,"i2f"},
+ {ICMD_I2D , BUILTIN_i2d ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_DOUBLE,
+ SUPPORT_DOUBLE && SUPPORT_IFCVT,true ,"i2d"},
+ {ICMD_L2F , BUILTIN_l2f ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_FLOAT ,
+ SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_LONG_FCVT,true ,"l2f"},
+ {ICMD_L2D , BUILTIN_l2d ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_DOUBLE,
+ SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_LONG_FCVT,true ,"l2d"},
+ {ICMD_F2L , BUILTIN_f2l ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_LONG_ICVT,true ,"f2l"},
+ {ICMD_D2L , BUILTIN_d2l ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID ,TYPE_VOID ,TYPE_LONG ,
+ SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_ICVT,true ,"d2l"},
+ {ICMD_F2I , BUILTIN_f2i ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID ,TYPE_VOID ,TYPE_INT ,
+ SUPPORT_FLOAT && SUPPORT_FICVT,true ,"f2i"},
+ {ICMD_D2I , BUILTIN_d2i ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID ,TYPE_VOID ,TYPE_INT ,
+ SUPPORT_DOUBLE && SUPPORT_FICVT,true ,"d2i"},
+
+ /* this record marks the end of the automatically replaced opcodes */
+ {255 , NULL ,0 ,0 ,0 ,0 ,0 ,
+ true ,false,"<INVALID>"},
+
+ /* the following functions are not replaced automatically */
+ {255,BUILTIN_instanceof ,ICMD_BUILTIN2,TYPE_ADR ,TYPE_ADR ,TYPE_VOID ,TYPE_INT ,0,0,"instanceof"},
+ {255,BUILTIN_arrayinstanceof ,ICMD_BUILTIN2,TYPE_ADR ,TYPE_ADR ,TYPE_VOID ,TYPE_INT ,0,0,"arrayinstanceof"},
+ {255,BUILTIN_checkarraycast ,ICMD_BUILTIN2,TYPE_ADR ,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,0,0,"checkarraycast"},
+ {255,BUILTIN_aastore ,ICMD_BUILTIN3,TYPE_ADR ,TYPE_INT ,TYPE_ADR ,TYPE_VOID ,0,0,"aastore"},
+ {255,BUILTIN_new ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"new"},
+ {255,BUILTIN_newarray ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray"},
+ {255,BUILTIN_newarray_boolean,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_boolean"},
+ {255,BUILTIN_newarray_char ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_char"},
+ {255,BUILTIN_newarray_float ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_float"},
+ {255,BUILTIN_newarray_double ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_double"},
+ {255,BUILTIN_newarray_byte ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_byte"},
+ {255,BUILTIN_newarray_short ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_short"},
+ {255,BUILTIN_newarray_int ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_int"},
+ {255,BUILTIN_newarray_long ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_long"},
+ {255,BUILTIN_monitorenter ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_VOID ,0,0,"monitorenter"},
+ {255,BUILTIN_monitorexit ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_VOID ,0,0,"monitorexit"},
+#if !SUPPORT_DIVISION
+ {255,BUILTIN_idiv ,ICMD_BUILTIN2,TYPE_INT ,TYPE_INT ,TYPE_VOID ,TYPE_INT ,0,0,"idiv"},
+ {255,BUILTIN_irem ,ICMD_BUILTIN2,TYPE_INT ,TYPE_INT ,TYPE_VOID ,TYPE_INT ,0,0,"irem"},
+#endif
+#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
+ {255,BUILTIN_ldiv ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,0,0,"ldiv"},
+ {255,BUILTIN_lrem ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,0,0,"lrem"},
+#endif
+ {255,BUILTIN_frem ,ICMD_BUILTIN2,TYPE_FLOAT ,TYPE_FLOAT ,TYPE_VOID ,TYPE_FLOAT ,0,0,"frem"},
+ {255,BUILTIN_drem ,ICMD_BUILTIN2,TYPE_DOUBLE,TYPE_DOUBLE,TYPE_VOID ,TYPE_DOUBLE,0,0,"drem"},
+
+ /* this record marks the end of the list */
+ { 0,NULL,0,0,0,0,0,0,0,"<END>"}
+};
+
/* include compiler subsystems ************************************************/
/* from codegen.inc */
#ifdef USEBUILTINTABLE
+/* XXX delete */
+#if 0
static int stdopcompare(const void *a, const void *b)
{
stdopdescriptor *o1 = (stdopdescriptor *) a;
return 1;
return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode);
}
+#endif
+static int stdopcompare(const void *a, const void *b)
+{
+ builtin_descriptor *o1 = (builtin_descriptor *) a;
+ builtin_descriptor *o2 = (builtin_descriptor *) b;
+ if (!o1->supported && o2->supported)
+ return -1;
+ if (o1->supported && !o2->supported)
+ return 1;
+ return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode);
+}
-
+/* XXX delete */
+#if 0
static inline void sort_builtintable()
{
int len;
len = sizeof(builtintable) / sizeof(stdopdescriptor);
- qsort(builtintable, len, sizeof(stdopdescriptor), stdopcompare);
+ qsort(builtintable, len, sizeof(builtin_descriptor), stdopcompare);
for (--len; len>=0 && builtintable[len].supported; len--);
builtintablelen = ++len;
}
#endif
}
+#endif
+
+static inline void sort_builtintable()
+{
+ int len;
+
+ len = 0;
+ while (builtin_desc[len].opcode != 255) len++;
+ qsort(builtin_desc, len, sizeof(builtin_descriptor), stdopcompare);
+
+ for (--len; len>=0 && builtin_desc[len].supported; len--);
+ builtintablelen = ++len;
+}
+#if 0
stdopdescriptor *find_builtin(int icmd)
{
- stdopdescriptor *first = builtintable;
- stdopdescriptor *last = builtintable + builtintablelen;
+ builtin_descriptor *first = builtintable;
+ builtin_descriptor *last = builtintable + builtintablelen;
+#endif
+builtin_descriptor *find_builtin(int icmd)
+{
+ builtin_descriptor *first = builtin_desc;
+ builtin_descriptor *last = builtin_desc + builtintablelen;
int len = last - first;
int half;
- stdopdescriptor *middle;
+ builtin_descriptor *middle;
while (len > 0) {
half = len / 2;
Changes: Christian Thalinger
- $Id: jit.h 723 2003-12-08 19:51:32Z edwin $
+ $Id: jit.h 727 2003-12-11 10:52:40Z edwin $
*/
#include "toolbox/chain.h"
#include "global.h"
+#include "builtin.h"
#include "typeinfo.h"
/**************************** resolve typedef-cycles **************************/
#if defined(USEBUILTINTABLE)
+/* XXX delete? */
+#if 0
typedef struct {
u1 opcode;
u1 type_s1;
extern stdopdescriptor builtintable[];
stdopdescriptor *find_builtin(int icmd);
+#endif
+
+builtin_descriptor *find_builtin(int opcode);
#endif /* USEBUILTINTABLE */
void removecompilerstub(u1 *stub);
void removenativestub(u1 *stub);
+void typecheck();
+
/* debug helpers (in stack.c) */
void icmd_print_stack(stackptr s);
+char *icmd_builtin_name(functionptr bptr);
void show_icmd_block(basicblock *bptr);
void show_icmd(instruction *iptr,bool deadcode);
void show_icmd_method();
Changes: Carolyn Oates
Edwin Steiner
- $Id: parse.c 726 2003-12-10 15:41:07Z edwin $
+ $Id: parse.c 727 2003-12-11 10:52:40Z edwin $
*/
OP2I(ICMD_CHECKASIZE, 0, 0);
switch (code_get_s1(p + 1)) {
case 4:
- BUILTIN1((functionptr) builtin_newarray_boolean, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_boolean, TYPE_ADR);
break;
case 5:
- BUILTIN1((functionptr) builtin_newarray_char, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_char, TYPE_ADR);
break;
case 6:
- BUILTIN1((functionptr) builtin_newarray_float, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_float, TYPE_ADR);
break;
case 7:
- BUILTIN1((functionptr) builtin_newarray_double, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_double, TYPE_ADR);
break;
case 8:
- BUILTIN1((functionptr) builtin_newarray_byte, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_byte, TYPE_ADR);
break;
case 9:
- BUILTIN1((functionptr) builtin_newarray_short, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_short, TYPE_ADR);
break;
case 10:
- BUILTIN1((functionptr) builtin_newarray_int, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_int, TYPE_ADR);
break;
case 11:
- BUILTIN1((functionptr) builtin_newarray_long, TYPE_ADR);
+ BUILTIN1(BUILTIN_newarray_long, TYPE_ADR);
break;
default: panic("Invalid array-type to create");
}
s_count++;
-#if defined(__I386__)
- BUILTIN2((functionptr) asm_builtin_newarray, TYPE_ADR);
-#else
- BUILTIN2((functionptr)builtin_newarray, TYPE_ADR);
-#endif
+ BUILTIN2(BUILTIN_newarray, TYPE_ADR);
}
break;
/* load and store of object fields *******************/
case JAVA_AASTORE:
- BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
+ BUILTIN3(BUILTIN_aastore, TYPE_VOID);
break;
case JAVA_PUTSTATIC:
LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
s_count++;
- BUILTIN1((functionptr) builtin_new, TYPE_ADR);
+ BUILTIN1(BUILTIN_new, TYPE_ADR);
break;
case JAVA_CHECKCAST:
/* array type cast-check */
LOADCONST_A(cls->vftbl);
s_count++;
- BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
+ BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR);
}
else { /* object type cast-check */
/*
+ LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+ s_count++;
-+ BUILTIN2((functionptr) asm_builtin_checkcast, TYPE_ADR);
++ BUILTIN2(BUILTIN_checkcast, TYPE_ADR);
+ */
OP2A(opcode, 1, cls);
}
/* array type cast-check */
LOADCONST_A(cls->vftbl);
s_count++;
- #if defined(__I386__)
- BUILTIN2((functionptr) asm_builtin_arrayinstanceof, TYPE_INT);
- #else
- BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
- #endif
+ BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT);
}
else { /* object type cast-check */
/*
LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
s_count++;
- BUILTIN2((functionptr) builtin_instanceof, TYPE_INT);
+ BUILTIN2(BUILTIN_instanceof, TYPE_INT);
+ */
OP2A(opcode, 1, cls);
}
case JAVA_MONITORENTER:
#ifdef USE_THREADS
if (checksync) {
- BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+ BUILTIN1(BUILTIN_monitorenter, TYPE_VOID);
} else
#endif
{
case JAVA_MONITOREXIT:
#ifdef USE_THREADS
if (checksync) {
- BUILTIN1((functionptr) asm_builtin_monitorexit, TYPE_VOID);
+ BUILTIN1(BUILTIN_monitorexit, TYPE_VOID);
}
else
#endif
#if defined(__I386__)
OP(opcode);
#else
- BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
+ BUILTIN2(BUILTIN_frem, TYPE_FLOAT);
#endif
break;
#if defined(__I386__)
OP(opcode);
#else
- BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
+ BUILTIN2(BUILTIN_drem, TYPE_DOUBLE);
#endif
break;
case JAVA_F2I:
#if defined(__ALPHA__)
if (!opt_noieee) {
- BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
+ BUILTIN1(BUILTIN_f2i, TYPE_INT);
} else
#endif
{
case JAVA_F2L:
#if defined(__ALPHA__)
if (!opt_noieee) {
- BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
+ BUILTIN1(BUILTIN_f2l, TYPE_LONG);
} else
#endif
{
case JAVA_D2I:
#if defined(__ALPHA__)
if (!opt_noieee) {
- BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
+ BUILTIN1(BUILTIN_d2i, TYPE_INT);
} else
#endif
{
case JAVA_D2L:
#if defined(__ALPHA__)
if (!opt_noieee) {
- BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
+ BUILTIN1(BUILTIN_d2l, TYPE_LONG);
} else
#endif
{
Changes: Edwin Steiner
- $Id: stack.c 725 2003-12-10 00:24:36Z edwin $
+ $Id: stack.c 727 2003-12-11 10:52:40Z edwin $
*/
#ifdef USEBUILTINTABLE
{
+#if 0
stdopdescriptor *breplace;
breplace = find_builtin(opcode);
+ if (breplace && opcode == breplace->opcode) {
+ iptr[0].opc = breplace->icmd;
+ iptr[0].op1 = breplace->type_d;
+ iptr[0].val.a = breplace->builtin;
+ isleafmethod = false;
+ switch (breplace->icmd) {
+ case ICMD_BUILTIN1:
+ goto builtin1;
+ case ICMD_BUILTIN2:
+ goto builtin2;
+ }
+ }
+#endif
+ builtin_descriptor *breplace;
+ breplace = find_builtin(opcode);
+
if (breplace && opcode == breplace->opcode) {
iptr[0].opc = breplace->icmd;
iptr[0].op1 = breplace->type_d;
#if !SUPPORT_DIVISION
iptr[0].opc = ICMD_BUILTIN2;
iptr[0].op1 = TYPE_INT;
- iptr[0].val.a = (functionptr) asm_builtin_idiv;
+ iptr[0].val.a = BUILTIN_idiv;
isleafmethod = false;
goto builtin2;
#endif
#if !SUPPORT_DIVISION
iptr[0].opc = ICMD_BUILTIN2;
iptr[0].op1 = TYPE_INT;
- iptr[0].val.a = (functionptr) asm_builtin_irem;
+ iptr[0].val.a = BUILTIN_irem;
isleafmethod = false;
goto builtin2;
#endif
#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
iptr[0].opc = ICMD_BUILTIN2;
iptr[0].op1 = TYPE_LNG;
- iptr[0].val.a = (functionptr) asm_builtin_ldiv;
+ iptr[0].val.a = BUILTIN_ldiv;
isleafmethod = false;
goto builtin2;
#endif
#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
iptr[0].opc = ICMD_BUILTIN2;
iptr[0].op1 = TYPE_LNG;
- iptr[0].val.a = (functionptr) asm_builtin_lrem;
+ iptr[0].val.a = BUILTIN_lrem;
isleafmethod = false;
goto builtin2;
#endif
char *icmd_builtin_name(functionptr bptr)
{
builtin_descriptor *bdesc = builtin_desc;
- while ((bdesc->bptr != NULL) && (bdesc->bptr != bptr))
+ while ((bdesc->opcode != 0) && (bdesc->builtin != bptr))
bdesc++;
- return bdesc->name;
+ return (bdesc->opcode) ? bdesc->name : "<NOT IN TABLE>";
}
case ICMD_PUTSTATIC:
case ICMD_GETSTATIC:
printf(" ");
+ utf_fprint(stdout,
+ ((fieldinfo *) iptr->val.a)->class->name);
+ printf(".");
utf_fprint(stdout,
((fieldinfo *) iptr->val.a)->name);
+ printf(" (type ");
+ utf_fprint(stdout,
+ ((fieldinfo *) iptr->val.a)->descriptor);
+ printf(")");
break;
case ICMD_IINC:
printf(" %d + %d", iptr->op1, iptr->val.i);
((classinfo *) iptr->val.a)->name);
}
break;
+ case ICMD_MULTIANEWARRAY:
+ {
+ vftbl *vft;
+ printf(" %d ",iptr->op1);
+ vft = (vftbl *)iptr->val.a;
+ if (vft)
+ utf_fprint(stdout,vft->class->name);
+ else
+ printf("<null>");
+ }
+ break;
case ICMD_CHECKCAST:
case ICMD_INSTANCEOF:
if (iptr->op1) {
Authors: Edwin Steiner
- $Id: typecheck.c 726 2003-12-10 15:41:07Z edwin $
+ $Id: typecheck.c 727 2003-12-11 10:52:40Z edwin $
*/
#define TYPECHECK_FLT(sp) TYPECHECK_STACK(sp,TYPE_FLT)
#define TYPECHECK_DBL(sp) TYPECHECK_STACK(sp,TYPE_DBL)
+#define TYPECHECK_ARGS1(t1) \
+ do {TYPECHECK_STACK(curstack,t1);} while (0)
+#define TYPECHECK_ARGS2(t1,t2) \
+ do {TYPECHECK_ARGS1(t1); \
+ TYPECHECK_STACK(curstack->prev,t2);} while (0)
+#define TYPECHECK_ARGS3(t1,t2,t3) \
+ do {TYPECHECK_ARGS2(t1,t2); \
+ TYPECHECK_STACK(curstack->prev->prev,t3);} while (0)
+
/* TYPECHECK_COPYVARS: copy the types and typeinfos of the current local
* variables to the local variables of the target block.
* Input:
bool maythrow; /* true if this instruction may throw */
utf *name_init; /* "<init>" */
bool initmethod; /* true if this is an "<init>" method */
+ builtin_descriptor *builtindesc;
#ifdef TYPECHECK_STATISTICS
int count_iterations = 0;
if (TYPEINFO_IS_ARRAY(curstack->prev->typeinfo)) /* XXX arraystub */
panic("illegal instruction: PUTFIELD on array");
-
- /* XXX */
+ /* check if the value is assignable to the field */
+ {
+ fieldinfo *fi = (fieldinfo*) iptr[0].val.a;
+
+ if (!TYPEINFO_IS_NULLTYPE(curstack->prev->typeinfo)) {
+ cls = fi->class;
+ /* XXX treat uinitialized objects specially? */
+ if (!class_issubclass(curstack->prev->typeinfo.typeclass,
+ cls))
+ panic("PUTFIELD reference type does not support field");
+ }
+
+ /* XXX check flags */
+
+ /* XXX ---> unify with ICMD_PUTSTATIC? */
+
+ /* XXX check access rights */
+
+ if (curstack->type != fi->type)
+ panic("PUTFIELD type mismatch");
+ if (fi->type == TYPE_ADR) {
+ TYPEINFO_INIT_FROM_FIELDINFO(rinfo,fi);
+ if (!typeinfo_is_assignable(&(curstack->typeinfo),
+ &rinfo))
+ panic("PUTFIELD reference type not assignable");
+ }
+ }
maythrow = true;
break;
case ICMD_PUTSTATIC:
- /* XXX */
+ /* check if the value is assignable to the field */
+ {
+ fieldinfo *fi = (fieldinfo*) iptr[0].val.a;
+
+ /* check flags */
+ /* XXX check access rights */
+
+ if (curstack->type != fi->type)
+ panic("PUTSTATIC type mismatch");
+ if (fi->type == TYPE_ADR) {
+ TYPEINFO_INIT_FROM_FIELDINFO(rinfo,fi);
+ if (!typeinfo_is_assignable(&(curstack->typeinfo),
+ &rinfo))
+ panic("PUTSTATIC reference type not assignable");
+ }
+ }
maythrow = true;
break;
{
fieldinfo *fi = (fieldinfo *)(iptr->val.a);
- /* XXX check non-static? */
+
+ if (!TYPEINFO_IS_NULLTYPE(curstack->typeinfo)) {
+ cls = fi->class;
+ if (!class_issubclass(curstack->typeinfo.typeclass,
+ cls))
+ panic("GETFIELD reference type does not support field");
+ }
+
+ /* XXX check flags */
+ /* XXX check access rights */
if (dst->type == TYPE_ADR) {
TYPEINFO_INIT_FROM_FIELDINFO(dst->typeinfo,fi);
}
case ICMD_GETSTATIC:
{
fieldinfo *fi = (fieldinfo *)(iptr->val.a);
- /* XXX check static? */
+ /* XXX check flags */
+ /* XXX check access rights */
if (dst->type == TYPE_ADR) {
TYPEINFO_INIT_FROM_FIELDINFO(dst->typeinfo,fi);
}
break;
case ICMD_MULTIANEWARRAY:
- /* check the array lengths on the stack */
- i = iptr[0].op1;
- if (i<1) panic("MULTIANEWARRAY with dimensions < 1");
- srcstack = curstack;
- while (i--) {
- if (!srcstack)
- panic("MULTIANEWARRAY missing array length");
- if (srcstack->type != TYPE_INT)
- panic("MULTIANEWARRAY using non-int as array length");
- srcstack = srcstack->prev;
- }
-
- /* set the array type of the result */
- TYPEINFO_INIT_CLASSINFO(dst->typeinfo,((vftbl *)iptr[0].val.a)->class);
+ {
+ vftbl *arrayvftbl;
+ arraydescriptor *desc;
+
+ /* check the array lengths on the stack */
+ i = iptr[0].op1;
+ if (i<1) panic("MULTIANEWARRAY with dimensions < 1");
+ srcstack = curstack;
+ while (i--) {
+ if (!srcstack)
+ panic("MULTIANEWARRAY missing array length");
+ if (srcstack->type != TYPE_INT)
+ panic("MULTIANEWARRAY using non-int as array length");
+ srcstack = srcstack->prev;
+ }
+
+ /* check array descriptor */
+ arrayvftbl = (vftbl*) iptr[0].val.a;
+ if (!arrayvftbl)
+ panic("MULTIANEWARRAY with unlinked class");
+ if ((desc = arrayvftbl->arraydesc) == NULL)
+ panic("MULTIANEWARRAY with non-array class");
+ if (desc->dimension < iptr[0].op1)
+ panic("MULTIANEWARRAY dimension to high");
+
+ /* set the array type of the result */
+ TYPEINFO_INIT_CLASSINFO(dst->typeinfo,arrayvftbl->class);
+ }
maythrow = true;
break;
case ICMD_BUILTIN3:
- if (ISBUILTIN(asm_builtin_aastore)) {
+ if (ISBUILTIN(BUILTIN_aastore)) {
TYPECHECK_ADR(curstack);
TYPECHECK_INT(curstack->prev);
TYPECHECK_ADR(curstack->prev->prev);
panic("illegal instruction: AASTORE to incompatible type");
*/
}
- /* XXX check for missed builtins in debug mode? */
+ else {
+ builtindesc = builtin_desc;
+ while (builtindesc->opcode && builtindesc->builtin
+ != (functionptr) iptr->val.a) builtindesc++;
+ if (!builtindesc->opcode) {
+ dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+ panic("Internal error: builtin not found in table");
+ }
+ TYPECHECK_ARGS3(builtindesc->type_s3,builtindesc->type_s2,builtindesc->type_s1);
+ }
maythrow = true; /* XXX better safe than sorry */
break;
case ICMD_BUILTIN2:
- if (
-#if defined(__I386__)
- ISBUILTIN(asm_builtin_newarray)
-#else
- ISBUILTIN(builtin_newarray)
-#endif
- )
+ /* XXX use BUILTIN_ macros */
+ if (ISBUILTIN(BUILTIN_newarray))
{
+ vftbl *vft;
TYPECHECK_INT(curstack->prev);
if (iptr[-1].opc != ICMD_ACONST)
panic("illegal instruction: builtin_newarray without classinfo");
- TYPEINFO_INIT_CLASSINFO(dst->typeinfo,((vftbl *)iptr[-1].val.a)->class);
+ vft = (vftbl *)iptr[-1].val.a;
+ if (!vft)
+ panic("ANEWARRAY with unlinked class");
+ if (!vft->arraydesc)
+ panic("ANEWARRAY with non-array class");
+ TYPEINFO_INIT_CLASSINFO(dst->typeinfo,vft->class);
}
- else if (ISBUILTIN(asm_builtin_checkarraycast)) {
+ else if (ISBUILTIN(BUILTIN_arrayinstanceof))
+ {
+ vftbl *vft;
+ TYPECHECK_ADR(curstack->prev);
+ if (iptr[-1].opc != ICMD_ACONST)
+ panic("illegal instruction: builtin_arrayinstanceof without classinfo");
+ vft = (vftbl *)iptr[-1].val.a;
+ if (!vft)
+ panic("INSTANCEOF with unlinked class");
+ if (!vft->arraydesc)
+ panic("internal error: builtin_arrayinstanceof with non-array class");
+ }
+ else if (ISBUILTIN(BUILTIN_checkarraycast)) {
+ vftbl *vft;
TYPECHECK_ADR(curstack->prev);
if (iptr[-1].opc != ICMD_ACONST)
- panic("illegal instruction: asm_builtin_checkarraycast without classinfo");
- TYPEINFO_INIT_CLASSINFO(dst->typeinfo,((vftbl *)iptr[-1].val.a)->class);
+ panic("illegal instruction: BUILTIN_checkarraycast without classinfo");
+ vft = (vftbl *)iptr[-1].val.a;
+ if (!vft)
+ panic("CHECKCAST with unlinked class");
+ if (!vft->arraydesc)
+ panic("internal error: builtin_checkarraycast with non-array class");
+ TYPEINFO_INIT_CLASSINFO(dst->typeinfo,vft->class);
}
- /* XXX check for missed builtins in debug mode? */
+ else {
+ builtindesc = builtin_desc;
+ while (builtindesc->opcode && builtindesc->builtin
+ != (functionptr) iptr->val.a) builtindesc++;
+ if (!builtindesc->opcode) {
+ dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+ panic("Internal error: builtin not found in table");
+ }
+ TYPECHECK_ARGS2(builtindesc->type_s2,builtindesc->type_s1);
+ }
maythrow = true; /* XXX better safe than sorry */
break;
case ICMD_BUILTIN1:
- if (ISBUILTIN(builtin_new)) {
+ if (ISBUILTIN(BUILTIN_new)) {
if (iptr[-1].opc != ICMD_ACONST)
panic("illegal instruction: builtin_new without classinfo");
TYPEINFO_INIT_NEWOBJECT(dst->typeinfo,iptr);
}
/* XXX unify the following cases */
- else if (ISBUILTIN(builtin_newarray_boolean)) {
+ else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_BOOLEAN);
}
- else if (ISBUILTIN(builtin_newarray_char)) {
+ else if (ISBUILTIN(BUILTIN_newarray_char)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_CHAR);
}
- else if (ISBUILTIN(builtin_newarray_float)) {
+ else if (ISBUILTIN(BUILTIN_newarray_float)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_FLOAT);
}
- else if (ISBUILTIN(builtin_newarray_double)) {
+ else if (ISBUILTIN(BUILTIN_newarray_double)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_DOUBLE);
}
- else if (ISBUILTIN(builtin_newarray_byte)) {
+ else if (ISBUILTIN(BUILTIN_newarray_byte)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_BYTE);
}
- else if (ISBUILTIN(builtin_newarray_short)) {
+ else if (ISBUILTIN(BUILTIN_newarray_short)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_SHORT);
}
- else if (ISBUILTIN(builtin_newarray_int)) {
+ else if (ISBUILTIN(BUILTIN_newarray_int)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_INT);
}
- else if (ISBUILTIN(builtin_newarray_long)) {
+ else if (ISBUILTIN(BUILTIN_newarray_long)) {
TYPECHECK_INT(curstack);
TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_LONG);
}
- /* XXX check for missed builtins in debug mode? */
+ else {
+ builtindesc = builtin_desc;
+ while (builtindesc->opcode && builtindesc->builtin
+ != (functionptr) iptr->val.a) builtindesc++;
+ if (!builtindesc->opcode) {
+ dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+ panic("Internal error: builtin not found in table");
+ }
+ TYPECHECK_ARGS1(builtindesc->type_s1);
+ }
maythrow = true; /* XXX better safe than sorry */
break;
for (i=0; i<block_count; ++i) {
if (block[i].flags != BBDELETED
&& block[i].flags != BBUNDEF
- && block[i].flags != BBFINISHED)
+ && block[i].flags != BBFINISHED
+ && block[i].flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
+ * some exception handlers,
+ * that's ok. */
{
LOG2("block L%03d has invalid flags after typecheck: %d",
block[i].debug_nr,block[i].flags);
}
}
#endif
-
+
+ /* Reset blocks we never reached */
+ for (i=0; i<block_count; ++i) {
+ if (block[i].flags == BBTYPECHECK_UNDEF)
+ block[i].flags = BBFINISHED;
+ }
+
LOGimp("exiting typecheck");
}
Mark Probst
Edwin Steiner
- $Id: loader.c 726 2003-12-10 15:41:07Z edwin $
+ $Id: loader.c 727 2003-12-11 10:52:40Z edwin $
*/
static u1 *classbuf_pos; /* current position in classfile buffer */
static int classbuffer_size; /* size of classfile-data */
-#define ASSERT_LEFT(len) \
- do {if (((classbuffer + classbuffer_size) - classbuf_pos - 1) < (len)) \
+/* assert that at least <len> bytes are left to read */
+/* <len> is limited to the range of non-negative s4 values */
+#define ASSERT_LEFT(len) \
+ do {if ( ((s4)(len)) < 0 \
+ || ((classbuffer + classbuffer_size) - classbuf_pos - 1) < (len)) \
panic("Unexpected end of classfile"); } while(0)
/* transfer block of classfile data into a buffer */
f -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8); /* JavaVM descriptor */
f -> type = jtype = desc_to_type (f->descriptor); /* data type */
f -> offset = 0; /* offset from start of object */
+ f -> class = c;
f->xta = NULL;
switch (f->type) {
- the heap
- additional support functions
- $Id: tables.c 724 2003-12-09 18:56:11Z edwin $
+ $Id: tables.c 727 2003-12-11 10:52:40Z edwin $
*/
{
char buf[MAXLOGTEXT];
utf_sprint(buf,u);
- dolog(buf);
+ dolog("%s",buf);
}
/********************** function: log_plain_utf ******************************
{
char buf[MAXLOGTEXT];
utf_sprint(buf,u);
- dolog_plain(buf);
+ dolog_plain("%s",buf);
}
/************************ function: utf_sprint *******************************
- the heap
- additional support functions
- $Id: tables.c 724 2003-12-09 18:56:11Z edwin $
+ $Id: tables.c 727 2003-12-11 10:52:40Z edwin $
*/
{
char buf[MAXLOGTEXT];
utf_sprint(buf,u);
- dolog(buf);
+ dolog("%s",buf);
}
/********************** function: log_plain_utf ******************************
{
char buf[MAXLOGTEXT];
utf_sprint(buf,u);
- dolog_plain(buf);
+ dolog_plain("%s",buf);
}
/************************ function: utf_sprint *******************************