#include "threads/threads-common.h"
#include "toolbox/logging.h"
+#include "toolbox/list.h"
#include "vm/array.h"
+
+#if defined(ENABLE_ASSERTION)
+#include "vm/assertion.h"
+#endif
+
#include "vm/builtin.h"
#include "vm/exceptions.h"
#include "vm/global.h"
java_lang_Throwable *o;
java_handle_bytearray_t *ba;
-#if PRINTJVM
- log_println("JVM_FillInStackTrace: receiver=%p", receiver);
-#endif
+ TRACEJVMCALLS("JVM_FillInStackTrace(env=%p, receiver=%p)", env, receiver);
o = (java_lang_Throwable *) receiver;
- ba = stacktrace_fillInStackTrace();
+ ba = stacktrace_get();
if (ba == NULL)
return;
- o->backtrace = (java_lang_Object *) ba;
+ LLNI_field_set_ref(o, backtrace, ba);
}
jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)
{
- java_lang_Throwable *o;
+ java_lang_Throwable *t;
java_handle_bytearray_t *ba;
- stacktracebuffer *stb;
+ stacktrace_t *st;
+ int32_t depth;
TRACEJVMCALLS("JVM_GetStackTraceDepth(env=%p, throwable=%p)", env, throwable);
return 0;
}
- o = (java_lang_Throwable *) throwable;
- ba = (java_handle_bytearray_t *) o->backtrace;
+ t = (java_lang_Throwable *) throwable;
+
+ LLNI_field_get_ref(t, backtrace, ba);
if (ba == NULL)
return 0;
- stb = (stacktracebuffer *) LLNI_array_data(ba);
+ /* We need a critical section here as the stacktrace structure is
+ mapped onto a Java byte-array. */
+
+ LLNI_CRITICAL_START;
+
+ st = (stacktrace_t *) LLNI_array_data(ba);
+
+ depth = st->length;
+
+ LLNI_CRITICAL_END;
- return stb->used;
+ return depth;
}
jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
{
- java_lang_Throwable *t;
+ java_lang_Throwable *t;
java_handle_bytearray_t *ba;
- stacktracebuffer *stb;
- stacktrace_entry *ste;
+ stacktrace_t *st;
+ stacktrace_entry_t *ste;
+ codeinfo *code;
+ methodinfo *m;
+ classinfo *c;
java_lang_StackTraceElement *o;
java_lang_String *declaringclass;
java_lang_String *filename;
- s4 linenumber;
+ int32_t linenumber;
-#if PRINTJVM
- log_println("JVM_GetStackTraceElement: throwable=%p, index=%d", throwable, index);
-#endif
+ TRACEJVMCALLS("JVM_GetStackTraceElement(env=%p, throwable=%p, index=%d)", env, throwable, index);
+
+ t = (java_lang_Throwable *) throwable;
- t = (java_lang_Throwable *) throwable;
- ba = (java_handle_bytearray_t *) t->backtrace;
- stb = (stacktracebuffer *) LLNI_array_data(ba);
+ LLNI_field_get_ref(t, backtrace, ba);
- if ((index < 0) || (index >= stb->used)) {
+ /* FIXME critical section */
+
+ st = (stacktrace_t *) LLNI_array_data(ba);
+
+ if ((index < 0) || (index >= st->length)) {
/* XXX This should be an IndexOutOfBoundsException (check this
again). */
return NULL;
}
- ste = &(stb->entries[index]);
+ /* Get the stacktrace entry. */
+
+ ste = &(st->entries[index]);
+
+ /* Get the codeinfo, methodinfo and classinfo. */
+
+ code = ste->code;
+ m = code->m;
+ c = m->class;
/* allocate a new StackTraceElement */
/* get filename */
- if (!(ste->method->flags & ACC_NATIVE)) {
- if (ste->method->class->sourcefile)
- filename = (java_lang_String *) javastring_new(ste->method->class->sourcefile);
+ if (!(m->flags & ACC_NATIVE)) {
+ if (c->sourcefile != NULL)
+ filename = (java_lang_String *) javastring_new(c->sourcefile);
else
filename = NULL;
}
/* get line number */
- if (ste->method->flags & ACC_NATIVE)
+ if (m->flags & ACC_NATIVE) {
linenumber = -2;
- else
- linenumber = (ste->linenumber == 0) ? -1 : ste->linenumber;
+ }
+ else {
+ /* FIXME The linenumbertable_linenumber_for_pc could change
+ the methodinfo pointer when hitting an inlined method. */
+
+ linenumber = linenumbertable_linenumber_for_pc(&m, code, ste->pc);
+ linenumber = (linenumber == 0) ? -1 : linenumber;
+ }
/* get declaring class name */
- declaringclass =
- _Jv_java_lang_Class_getName(LLNI_classinfo_wrap(ste->method->class));
+ declaringclass = _Jv_java_lang_Class_getName(LLNI_classinfo_wrap(c));
/* fill the java.lang.StackTraceElement element */
+ /* FIXME critical section */
+
o->declaringClass = declaringclass;
- o->methodName = (java_lang_String *) javastring_new(ste->method->name);
+ o->methodName = (java_lang_String *) javastring_new(m->name);
o->fileName = filename;
o->lineNumber = linenumber;
jint JVM_IHashCode(JNIEnv* env, jobject handle)
{
-#if PRINTJVM
- log_println("JVM_IHashCode: jobject=%p", handle);
-#endif
+ TRACEJVMCALLS("JVM_IHashCode(env=%p, jobject=%p)", env, handle);
+
return (jint) ((ptrint) handle);
}
jboolean JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls)
{
+#if defined(ENABLE_ASSERTION)
+ assertion_name_t *item;
+ classinfo *c;
+ jboolean status;
+ utf *name;
+
TRACEJVMCALLS("JVM_DesiredAssertionStatus(env=%p, unused=%p, cls=%p)", env, unused, cls);
- /* TODO: Implement this one, but false should be OK. */
+ c = LLNI_classinfo_unwrap(cls);
- return false;
+ if (c->classloader == NULL) {
+ status = (jboolean)assertion_system_enabled;
+ }
+ else {
+ status = (jboolean)assertion_user_enabled;
+ }
+
+ if (list_assertion_names != NULL) {
+ item = (assertion_name_t *)list_first(list_assertion_names);
+ while (item != NULL) {
+ name = utf_new_char(item->name);
+ if (name == c->packagename) {
+ status = (jboolean)item->enabled;
+ }
+ else if (name == c->name) {
+ status = (jboolean)item->enabled;
+ }
+
+ item = (assertion_name_t *)list_next(list_assertion_names, item);
+ }
+ }
+
+ return status;
+#else
+ return (jboolean)false;
+#endif
}
jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
{
- classinfo *c;
- java_lang_AssertionStatusDirectives *o;
- java_handle_objectarray_t *classes;
- java_handle_objectarray_t *packages;
-
- TRACEJVMCALLS("JVM_AssertionStatusDirectives(env=%p, unused=%p): COMPLETE ME!", env, unused);
+ classinfo *c;
+ java_lang_AssertionStatusDirectives *o;
+ java_handle_objectarray_t *classes;
+ java_handle_objectarray_t *packages;
+ java_booleanarray_t *classEnabled;
+ java_booleanarray_t *packageEnabled;
+#if defined(ENABLE_ASSERTION)
+ assertion_name_t *item;
+ java_handle_t *js;
+ s4 i, j;
+#endif
- /* XXX this is not completely implemented */
+ TRACEJVMCALLS("JVM_AssertionStatusDirectives(env=%p, unused=%p)", env, unused);
c = load_class_bootstrap(utf_new_char("java/lang/AssertionStatusDirectives"));
if (o == NULL)
return NULL;
+#if defined(ENABLE_ASSERTION)
+ classes = builtin_anewarray(assertion_class_count, class_java_lang_Object);
+#else
classes = builtin_anewarray(0, class_java_lang_Object);
-
+#endif
if (classes == NULL)
return NULL;
+#if defined(ENABLE_ASSERTION)
+ packages = builtin_anewarray(assertion_package_count, class_java_lang_Object);
+#else
packages = builtin_anewarray(0, class_java_lang_Object);
-
+#endif
if (packages == NULL)
return NULL;
+
+#if defined(ENABLE_ASSERTION)
+ classEnabled = builtin_newarray_boolean(assertion_class_count);
+#else
+ classEnabled = builtin_newarray_boolean(0);
+#endif
+ if (classEnabled == NULL)
+ return NULL;
+
+#if defined(ENABLE_ASSERTION)
+ packageEnabled = builtin_newarray_boolean(assertion_package_count);
+#else
+ packageEnabled = builtin_newarray_boolean(0);
+#endif
+ if (packageEnabled == NULL)
+ return NULL;
+
+#if defined(ENABLE_ASSERTION)
+ /* initialize arrays */
+
+ if (list_assertion_names != NULL) {
+ i = 0;
+ j = 0;
+
+ item = (assertion_name_t *)list_first(list_assertion_names);
+ while (item != NULL) {
+ js = javastring_new_from_ascii(item->name);
+ if (js == NULL) {
+ return NULL;
+ }
+
+ if (item->package == false) {
+ classes->data[i] = js;
+ classEnabled->data[i] = (jboolean) item->enabled;
+ i += 1;
+ }
+ else {
+ packages->data[j] = js;
+ packageEnabled->data[j] = (jboolean) item->enabled;
+ j += 1;
+ }
+
+ item = (assertion_name_t *)list_next(list_assertion_names, item);
+ }
+ }
+#endif
/* set instance fields */
o->classes = classes;
o->packages = packages;
+ o->classEnabled = classEnabled;
+ o->packageEnabled = packageEnabled;
return (jobject) o;
}
jobject JVM_LatestUserDefinedLoader(JNIEnv *env)
{
- log_println("JVM_LatestUserDefinedLoader: IMPLEMENT ME!");
+ classloader *cl;
+
+ TRACEJVMCALLS("JVM_LatestUserDefinedLoader(env=%p)", env);
+
+ cl = stacktrace_first_nonnull_classloader();
+
+ return (jobject) cl;
}
void JVM_UnloadLibrary(void* handle)
{
- log_println("JVM_UnloadLibrary: IMPLEMENT ME!");
+ TRACEJVMCALLS("JVM_UnloadLibrary(handle=%p)", handle);
+
+ native_library_close(handle);
}
/* JVM_GetManagement */
-void* JVM_GetManagement(jint version)
+void *JVM_GetManagement(jint version)
{
- log_println("JVM_GetManagement: IMPLEMENT ME!");
+ TRACEJVMCALLS("JVM_GetManagement(version=%d)", version);
+
+ /* TODO We current don't support the management interface. */
+
+ return NULL;
}
jobjectArray JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass)
{
- log_println("JVM_GetEnclosingMethodInfo: IMPLEMENT ME!");
+ classinfo *c;
+ methodinfo *m;
+ java_handle_objectarray_t *oa;
+
+ TRACEJVMCALLS("JVM_GetEnclosingMethodInfo(env=%p, ofClass=%p)", env, ofClass);
+
+ c = LLNI_classinfo_unwrap(ofClass);
+
+ if ((c == NULL) || class_is_primitive(c))
+ return NULL;
+
+ m = class_get_enclosingmethod(c);
+
+ if (m == NULL)
+ return NULL;
+
+ oa = builtin_anewarray(3, class_java_lang_Object);
+
+ if (oa == NULL)
+ return NULL;
+
+ array_objectarray_element_set(oa, 0, (java_handle_t *) LLNI_classinfo_wrap(m->class));
+ array_objectarray_element_set(oa, 1, javastring_new(m->name));
+ array_objectarray_element_set(oa, 2, javastring_new(m->descriptor));
+
+ return (jobjectArray) oa;
}