#include "native/jni.h"
#include "native/llni.h"
+#include "native/localref.h"
#include "native/native.h"
#include "native/include/java_lang_Object.h" /* required by j.l.C */
#include "toolbox/logging.h"
+#include "vm/array.h"
#include "vm/builtin.h"
#include "vm/exceptions.h"
#include "vm/finalizer.h"
#include "vm/jit/argument.h"
#include "vm/jit/asmpart.h"
+
+#if defined(ENABLE_DISASSEMBLER)
+# include "vm/jit/disass.h"
+#endif
+
#include "vm/jit/jit.h"
#include "vm/jit/md.h"
if (!vm_create(_vm_args))
goto error;
-#if defined(ENABLE_JNI)
- /* setup the local ref table (must be created after vm_create) */
-
- /* XXX this one will never get freed for the main thread;
- call localref_table_destroy() if you want to do it! */
-
- if (!localref_table_init())
- goto error;
-#endif
-
/* now return the values */
*p_vm = (JavaVM *) vm;
vm_abort("vm_create: jni_init failed");
#endif
+#if defined(ENABLE_JNI) || defined(ENABLE_HANDLES)
+ /* Initialize the local reference table for the main thread. */
+ /* BEFORE: threads_init */
+
+ if (!localref_table_init())
+ vm_abort("vm_create: localref_table_init failed");
+#endif
+
#if defined(ENABLE_THREADS)
if (!threads_init())
vm_abort("vm_create: threads_init failed");
u = utf_new_char(vm_args->options[opt_index + i].optionString);
s = javastring_new(u);
- LLNI_objectarray_element_set(oa, i, s);
+ array_objectarray_element_set(oa, i, s);
}
#ifdef TYPEINFO_DEBUG_TEST
}
+/* vm_abort_disassemble ********************************************************
+
+ Prints an error message, disassemble the given code range (if
+ enabled) and aborts the VM.
+
+ IN:
+ pc.......PC to disassemble
+ count....number of instructions to disassemble
+
+*******************************************************************************/
+
+void vm_abort_disassemble(void *pc, int count, const char *text, ...)
+{
+ va_list ap;
+#if defined(ENABLE_DISASSEMBLER)
+ int i;
+#endif
+
+ /* Print debug message. */
+
+ log_start();
+
+ va_start(ap, text);
+ log_vprint(text, ap);
+ va_end(ap);
+
+ log_finish();
+
+ /* Print the PC. */
+
+#if SIZEOF_VOID_P == 8
+ log_println("PC=0x%016lx", pc);
+#else
+ log_println("PC=0x%08x", pc);
+#endif
+
+#if defined(ENABLE_DISASSEMBLER)
+ log_println("machine instructions at PC:");
+
+ /* Disassemble the given number of instructions. */
+
+ for (i = 0; i < count; i++)
+ pc = disassinstr(pc);
+#endif
+
+ vm_abort("Aborting...");
+}
+
+
/* vm_get_mainclass_from_jar ***************************************************
Gets the name of the main class from a JAR's manifest file.
return value; \
}
-VM_CALL_ARRAY(, java_handle_t *)
+static java_handle_t *vm_call_array(methodinfo *m, uint64_t *array)
+{
+ methoddesc *md;
+ void *pv;
+ java_object_t *o;
+
+ assert(m->code != NULL);
+
+ md = m->parseddesc;
+ pv = m->code->entrypoint;
+
+ STATISTICS(count_calls_native_to_java++);
+
+ o = asm_vm_call_method(pv, array, md->memuse);
+
+ if (md->returntype.type == TYPE_VOID)
+ o = NULL;
+
+ return LLNI_WRAP(o);
+}
+
VM_CALL_ARRAY(_int, int32_t)
VM_CALL_ARRAY(_long, int64_t)
VM_CALL_ARRAY(_float, float)
array = argument_vmarray_from_objectarray(m, o, params);
- /* The array can be NULL if we don't have any arguments to pass
- and the architecture does not have any argument registers
- (e.g. i386). In that case we additionally check for an
- exception thrown. */
-
- if ((array == NULL) && (exceptions_get_exception() != NULL)) {
+ if (array == NULL) {
/* release dump area */
dump_release(dumpsize);
THREAD_NATIVEWORLD_ENTER;
+ exceptions_throw_illegalargumentexception();
+
return NULL;
}
switch (m->parseddesc->returntype.decltype) {
- case TYPE_VOID:
- (void) vm_call_array(m, array);
- ro = NULL;
+ case PRIMITIVETYPE_VOID:
+ value.a = vm_call_array(m, array);
break;
case PRIMITIVETYPE_BOOLEAN:
case PRIMITIVETYPE_SHORT:
case PRIMITIVETYPE_INT:
value.i = vm_call_int_array(m, array);
- ro = primitive_box(m->parseddesc->returntype.decltype, value);
break;
case PRIMITIVETYPE_LONG:
value.l = vm_call_long_array(m, array);
- ro = primitive_box(m->parseddesc->returntype.decltype, value);
break;
case PRIMITIVETYPE_FLOAT:
value.f = vm_call_float_array(m, array);
- ro = primitive_box(m->parseddesc->returntype.decltype, value);
break;
case PRIMITIVETYPE_DOUBLE:
value.d = vm_call_double_array(m, array);
- ro = primitive_box(m->parseddesc->returntype.decltype, value);
break;
case TYPE_ADR:
break;
default:
- vm_abort("_Jv_jni_invokeNative: invalid return type %d", m->parseddesc->returntype.decltype);
+ vm_abort("vm_call_method_objectarray: invalid return type %d", m->parseddesc->returntype.decltype);
}
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ /* enter the nativeworld again */
+
+ THREAD_NATIVEWORLD_ENTER;
+
+ /* box the return value if necesarry */
+
+ if (m->parseddesc->returntype.decltype != TYPE_ADR)
+ ro = primitive_box(m->parseddesc->returntype.decltype, value);
+
+ /* check for an exception */
+
xptr = exceptions_get_exception();
if (xptr != NULL) {
exceptions_throw_invocationtargetexception(xptr);
}
- /* release dump area */
-
- dump_release(dumpsize);
-
- /* enter the nativeworld again */
-
- THREAD_NATIVEWORLD_ENTER;
-
return ro;
}