calls instead of machine instructions, using the C calling
convention.
- $Id: builtin.c 782 2003-12-15 15:47:09Z twisti $
+ $Id: builtin.c 921 2004-02-16 04:00:59Z jowenn $
*/
#undef DEBUG /*define DEBUG 1*/
-/* XXX delete? */
-#if 0
-builtin_descriptor builtin_desc[] = {
- {(functionptr) builtin_instanceof, "instanceof"},
- {(functionptr) builtin_checkcast, "checkcast"},
- {(functionptr) asm_builtin_checkcast, "checkcast"},
- {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
-#if defined(__I386__)
- {(functionptr) asm_builtin_arrayinstanceof,"arrayinstanceof"},
-#endif
- {(functionptr) builtin_checkarraycast, "checkarraycast"},
- {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
- {(functionptr) asm_builtin_aastore, "aastore"},
- {(functionptr) builtin_new, "new"},
- {(functionptr) builtin_newarray, "newarray"},
- {(functionptr) builtin_anewarray, "anewarray"},
-#if defined(__I386__)
- /*
- * have 2 parameters (needs stack manipulation)
- */
- {(functionptr) asm_builtin_newarray, "newarray"},
-#endif
- {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
- {(functionptr) builtin_newarray_char, "newarray_char"},
- {(functionptr) builtin_newarray_float, "newarray_float"},
- {(functionptr) builtin_newarray_double, "newarray_double"},
- {(functionptr) builtin_newarray_byte, "newarray_byte"},
- {(functionptr) builtin_newarray_short, "newarray_short"},
- {(functionptr) builtin_newarray_int, "newarray_int"},
- {(functionptr) builtin_newarray_long, "newarray_long"},
- {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
- {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
- {(functionptr) builtin_monitorenter, "monitorenter"},
- {(functionptr) asm_builtin_monitorenter, "monitorenter"},
- {(functionptr) builtin_monitorexit, "monitorexit"},
- {(functionptr) asm_builtin_monitorexit, "monitorexit"},
-#if !SUPPORT_DIVISION
- {(functionptr) builtin_idiv, "idiv"},
- {(functionptr) asm_builtin_idiv, "idiv"},
- {(functionptr) builtin_irem, "irem"},
- {(functionptr) asm_builtin_irem, "irem"},
-#endif
- {(functionptr) builtin_ladd, "ladd"},
- {(functionptr) builtin_lsub, "lsub"},
- {(functionptr) builtin_lmul, "lmul"},
-#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
- {(functionptr) builtin_ldiv, "ldiv"},
- {(functionptr) asm_builtin_ldiv, "ldiv"},
- {(functionptr) builtin_lrem, "lrem"},
- {(functionptr) asm_builtin_lrem, "lrem"},
-#endif
- {(functionptr) builtin_lshl, "lshl"},
- {(functionptr) builtin_lshr, "lshr"},
- {(functionptr) builtin_lushr, "lushr"},
- {(functionptr) builtin_land, "land"},
- {(functionptr) builtin_lor, "lor"},
- {(functionptr) builtin_lxor, "lxor"},
- {(functionptr) builtin_lneg, "lneg"},
- {(functionptr) builtin_lcmp, "lcmp"},
- {(functionptr) builtin_fadd, "fadd"},
- {(functionptr) builtin_fsub, "fsub"},
- {(functionptr) builtin_fmul, "fmul"},
- {(functionptr) builtin_fdiv, "fdiv"},
- {(functionptr) builtin_frem, "frem"},
- {(functionptr) builtin_fneg, "fneg"},
- {(functionptr) builtin_fcmpl, "fcmpl"},
- {(functionptr) builtin_fcmpg, "fcmpg"},
- {(functionptr) builtin_dadd, "dadd"},
- {(functionptr) builtin_dsub, "dsub"},
- {(functionptr) builtin_dmul, "dmul"},
- {(functionptr) builtin_ddiv, "ddiv"},
- {(functionptr) builtin_drem, "drem"},
- {(functionptr) builtin_dneg, "dneg"},
- {(functionptr) builtin_dcmpl, "dcmpl"},
- {(functionptr) builtin_dcmpg, "dcmpg"},
- {(functionptr) builtin_i2l, "i2l"},
- {(functionptr) builtin_i2f, "i2f"},
- {(functionptr) builtin_i2d, "i2d"},
- {(functionptr) builtin_l2i, "l2i"},
- {(functionptr) builtin_l2f, "l2f"},
- {(functionptr) builtin_l2d, "l2d"},
- {(functionptr) builtin_f2i, "f2i"},
- {(functionptr) builtin_f2l, "f2l"},
- {(functionptr) builtin_f2d, "f2d"},
- {(functionptr) builtin_d2i, "d2i"},
- {(functionptr) builtin_d2l, "d2l"},
-#if defined(__I386__)
- {(functionptr) asm_builtin_f2i, "f2i"},
- {(functionptr) asm_builtin_f2l, "f2l"},
- {(functionptr) asm_builtin_d2i, "d2i"},
- {(functionptr) asm_builtin_d2l, "d2l"},
-#endif
- {(functionptr) builtin_d2f, "d2f"},
- {(functionptr) NULL, "unknown"}
-};
-#endif
-
/*****************************************************************************
TYPE CHECKS
return res;
}
-/* XXX inline this? */
s4 builtin_isanysubclass_vftbl(vftbl *sub,vftbl *super)
{
int base;
******************************************************************************/
-/* XXX inline this? */
static s4 builtin_descriptorscompatible(arraydescriptor *desc,arraydescriptor *target)
{
if (desc==target) return 1;
if (desc->arraytype != ARRAYTYPE_OBJECT) return 1;
/* {both arrays are arrays of references} */
- if (desc->dimension == target->dimension)
+ if (desc->dimension == target->dimension) {
+ /* an array which contains elements of interface types is allowed to be casted to Object (JOWENN)*/
+ if ( (desc->elementvftbl->baseval<0) && (target->elementvftbl->baseval==1) ) return 1;
return builtin_isanysubclass_vftbl(desc->elementvftbl,target->elementvftbl);
+ }
if (desc->dimension < target->dimension) return 0;
/* {desc has higher dimension than target} */
}
log_text(logtext);
}
- exceptionptr = local_exceptionptr;
+ *exceptionptr = local_exceptionptr;
return local_exceptionptr;
}
+void builtin_reset_exceptionptr()
+{
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#ifdef HAVE___THREAD
+ _exceptionptr = NULL;
+#else
+ ((nativethread*) pthread_getspecific(tkey_exceptionptr))->_exceptionptr = 0;
+#endif
+#else
+ panic("builtin_reset_exceptionptr should not be used in this configuration");
+#endif
+}
+
/******************* function: builtin_canstore *******************************
/* This is an optimized version where a is guaranteed to be a
* one-dimensional array of a class type */
-/* XXX this could be inlined by the code generator */
s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o)
{
vftbl *elementvftbl;
{
java_objectheader *o;
- class_init(c);
+ if (!c->initialized) {
+ if (initverbose) {
+ char logtext[MAXLOGTEXT];
+ sprintf(logtext, "Initialize class ");
+ utf_sprint(logtext + strlen(logtext), c->name);
+ sprintf(logtext + strlen(logtext), " (from builtin_new)");
+ log_text(logtext);
+ }
+ class_init(c);
+ }
#ifdef SIZE_FROM_CLASSINFO
c->alignedsize = align_size(c->instancesize);
s4 actualsize;
if (size<0) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/NegativeArraySizeException")));
+ *exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/NegativeArraySizeException")));
return NULL;
}
#ifdef SIZE_FROM_CLASSINFO
#endif
if (((u4)actualsize)<((u4)size)) { /* overflow */
- exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/OutOfMemoryError")));
+ *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/OutOfMemoryError")));
return NULL;
}
a = heap_allocate(actualsize,
java_objectarray *builtin_anewarray(s4 size, classinfo *component)
{
+/*
+ printf("builtin_anewarray: classvftbl: %d\n",component->classvftbl);
+ printf("builtin_anewarray: baseval: %d\n",component->vftbl->baseval);
+ utf_display(component->vftbl->class->name);
+ printf("\nbuiltin_anewarray: linked: %d\n",component->linked);
+ utf_display(component->super->name);*/
return (java_objectarray*) builtin_newarray(size, class_array_of(component)->vftbl);
}
/* get the vftbl of the components to create */
componentvftbl = arrayvftbl->arraydesc->componentvftbl;
- if (!componentvftbl) /* XXX the verifier could check this */
- panic ("multianewarray with too many dimensions");
+
+ /* The verifier guarantees this. */
+ /* if (!componentvftbl) */
+ /* panic ("multianewarray with too many dimensions"); */
/* create the component arrays */
for (i = 0; i < size; i++) {
u4 methodindent = 0;
-java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
+java_objectheader *builtin_trace_exception(java_objectheader *_exceptionptr,
methodinfo *method, int *pos,
int noindent)
{
- if (!noindent)
- methodindent--;
+ if (!noindent) {
+ if (methodindent)
+ methodindent--;
+ else
+ log_text("WARNING: unmatched methodindent--");
+ }
if (verbose || runverbose) {
printf("Exception ");
- if (exceptionptr) {
- utf_display (exceptionptr->vftbl->class->name);
- }
- else {
+ if (_exceptionptr) {
+ utf_display(_exceptionptr->vftbl->class->name);
+
+ } else {
printf("Error: <Nullpointer instead of exception>");
if (!proto_java_lang_ClassCastException) printf("%s","proto_java_lang_ClassCastException==0");
if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
}
printf(" thrown in ");
+
if (method) {
- utf_display (method->class->name);
+ utf_display(method->class->name);
printf(".");
- utf_display (method->name);
+ utf_display(method->name);
if (method->flags & ACC_SYNCHRONIZED)
printf("(SYNC)");
else
printf("(NOSYNC)");
printf("(%p) at position %p\n", method->entrypoint, pos);
- }
- else
+
+ } else
printf("call_java_method\n");
fflush (stdout);
}
- return exceptionptr;
+
+ return _exceptionptr;
}
sprintf(logtext + strlen(logtext), ".");
utf_sprint(logtext + strlen(logtext), method->name);
utf_sprint(logtext + strlen(logtext), method->descriptor);
+
+ if ( method->flags & ACC_PUBLIC ) sprintf (logtext + strlen(logtext)," PUBLIC");
+ if ( method->flags & ACC_PRIVATE ) sprintf (logtext + strlen(logtext)," PRIVATE");
+ if ( method->flags & ACC_PROTECTED ) sprintf (logtext + strlen(logtext)," PROTECTED");
+ if ( method->flags & ACC_STATIC ) sprintf (logtext + strlen(logtext)," STATIC");
+ if ( method->flags & ACC_FINAL ) sprintf (logtext + strlen(logtext)," FINAL");
+ if ( method->flags & ACC_SYNCHRONIZED ) sprintf (logtext + strlen(logtext)," SYNCHRONIZED");
+ if ( method->flags & ACC_VOLATILE ) sprintf (logtext + strlen(logtext)," VOLATILE");
+ if ( method->flags & ACC_TRANSIENT ) sprintf (logtext + strlen(logtext)," TRANSIENT");
+ if ( method->flags & ACC_NATIVE ) sprintf (logtext + strlen(logtext)," NATIVE");
+ if ( method->flags & ACC_INTERFACE ) sprintf (logtext + strlen(logtext)," INTERFACE");
+ if ( method->flags & ACC_ABSTRACT ) sprintf (logtext + strlen(logtext)," ABSTRACT");
+
+
sprintf(logtext + strlen(logtext), "(");
switch (method->paramcount) {
sprintf(logtext + strlen(logtext), ".");
utf_sprint(logtext + strlen(logtext), method->name);
utf_sprint(logtext + strlen(logtext), method->descriptor);
+
+ if ( method->flags & ACC_PUBLIC ) sprintf (logtext + strlen(logtext)," PUBLIC");
+ if ( method->flags & ACC_PRIVATE ) sprintf (logtext + strlen(logtext)," PRIVATE");
+ if ( method->flags & ACC_PROTECTED ) sprintf (logtext + strlen(logtext)," PROTECTED");
+ if ( method->flags & ACC_STATIC ) sprintf (logtext + strlen(logtext)," STATIC");
+ if ( method->flags & ACC_FINAL ) sprintf (logtext + strlen(logtext)," FINAL");
+ if ( method->flags & ACC_SYNCHRONIZED ) sprintf (logtext + strlen(logtext)," SYNCHRONIZED");
+ if ( method->flags & ACC_VOLATILE ) sprintf (logtext + strlen(logtext)," VOLATILE");
+ if ( method->flags & ACC_TRANSIENT ) sprintf (logtext + strlen(logtext)," TRANSIENT");
+ if ( method->flags & ACC_NATIVE ) sprintf (logtext + strlen(logtext)," NATIVE");
+ if ( method->flags & ACC_INTERFACE ) sprintf (logtext + strlen(logtext)," INTERFACE");
+ if ( method->flags & ACC_ABSTRACT ) sprintf (logtext + strlen(logtext)," ABSTRACT");
+
log_text(logtext);
methodindent++;
}
char logtext[MAXLOGTEXT];
for (i = 0; i < methodindent; i++)
logtext[i] = '\t';
- methodindent--;
+ if (methodindent)
+ methodindent--;
+ else
+ log_text("WARNING: unmatched methodindent--");
sprintf(logtext + methodindent, "finished: ");
utf_sprint(logtext + strlen(logtext), method->class->name);
sprintf(logtext + strlen(logtext), ".");
*/
void internal_lock_mutex_for_object(java_objectheader *object)
{
-#ifdef USE_THREADS
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
mutexHashEntry *entry;
int hashValue;
*/
void internal_unlock_mutex_for_object (java_objectheader *object)
{
-#ifdef USE_THREADS
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
int hashValue;
mutexHashEntry *entry;
void builtin_monitorenter(java_objectheader *o)
{
-#ifdef USE_THREADS
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
int hashValue;
assert(blockInts == 0);
void builtin_monitorexit (java_objectheader *o)
{
-#ifdef USE_THREADS
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
int hashValue;
assert(blockInts == 0);
return (java_arrayheader *) Java_java_lang_VMObject_clone(0, 0, (java_lang_Cloneable *) o);
}
+s4 builtin_dummy()
+{
+ panic("Internal error: builtin_dummy called (native function is missing)");
+ return 0; /* for the compiler */
+}
+
/*
* These are local overrides for various environment variables in Emacs.