/* Copyright (c) 2008, Avian Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. There is NO WARRANTY for this software. See license.txt for details. */ #include "jnienv.h" #include "machine.h" #include "util.h" #include "processor.h" #include "constants.h" #include "processor.h" using namespace vm; namespace { const uintptr_t InterfaceMethodID = (static_cast(1) << (BitsPerWord - 1)); const uintptr_t NonVirtualMethodID = (static_cast(1) << (BitsPerWord - 2)); jint JNICALL DestroyJavaVM(Machine* m) { System* s = m->system; Heap* h = m->heap; Processor* p = m->processor; Finder* f = m->finder; Thread* t = m->rootThread; int exitCode = (t->exception ? -1 : 0); enter(t, Thread::ActiveState); t->exit(); m->dispose(); h->disposeFixies(); p->dispose(); h->dispose(); f->dispose(); s->dispose(); return exitCode; } jint JNICALL AttachCurrentThread(Machine* m, Thread** t, void*) { *t = static_cast(m->localThread->get()); if (*t == 0) { *t = m->processor->makeThread(m, 0, m->rootThread); m->localThread->set(*t); } return 0; } jint JNICALL DetachCurrentThread(Machine* m) { Thread* t = static_cast(m->localThread->get()); if (t) { t->exit(); return 0; } else { return -1; } } jint JNICALL GetEnv(Machine* m, Thread** t, jint version) { *t = static_cast(m->localThread->get()); if (*t) { if (version <= JNI_VERSION_1_4) { return JNI_OK; } else { return JNI_EVERSION; } } else { return JNI_EDETACHED; } } jsize JNICALL GetStringUTFLength(Thread* t, jstring s) { ENTER(t, Thread::ActiveState); return stringLength(t, *s); } const char* JNICALL GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy) { ENTER(t, Thread::ActiveState); char* chars = static_cast (t->m->heap->allocate(stringLength(t, *s) + 1, false)); stringChars(t, *s, chars); if (isCopy) *isCopy = true; return chars; } void JNICALL ReleaseStringUTFChars(Thread* t, jstring s, const char* chars) { t->m->heap->free(chars, stringLength(t, *s) + 1, false); } jsize JNICALL GetArrayLength(Thread* t, jarray array) { ENTER(t, Thread::ActiveState); return cast(*array, BytesPerWord); } jstring JNICALL NewString(Thread* t, const jchar* chars, jsize size) { ENTER(t, Thread::ActiveState); object a = 0; if (size) { a = makeCharArray(t, size, false); memcpy(&charArrayBody(t, a, 0), chars, size * sizeof(jchar)); } object s = makeString(t, a, 0, size, 0); return makeLocalReference(t, s); } jstring JNICALL NewStringUTF(Thread* t, const char* chars) { ENTER(t, Thread::ActiveState); object a = 0; unsigned size = strlen(chars); if (size) { a = makeByteArray(t, size, false); memcpy(&byteArrayBody(t, a, 0), chars, size); } object s = makeString(t, a, 0, size, 0); return makeLocalReference(t, s); } void replace(int a, int b, const char* in, int8_t* out) { while (*in) { *out = (*in == a ? b : *in); ++ in; ++ out; } *out = 0; } jclass JNICALL FindClass(Thread* t, const char* name) { ENTER(t, Thread::ActiveState); object n = makeByteArray(t, strlen(name) + 1, false); replace('.', '/', name, &byteArrayBody(t, n, 0)); return makeLocalReference(t, resolveClass(t, n)); } jint JNICALL ThrowNew(Thread* t, jclass c, const char* message) { if (t->exception) { return -1; } ENTER(t, Thread::ActiveState); object m = 0; PROTECT(t, m); if (message) { m = makeString(t, "%s", message); } object trace = makeTrace(t); PROTECT(t, trace); t->exception = make(t, *c); set(t, t->exception, ThrowableMessage, m); set(t, t->exception, ThrowableTrace, trace); return 0; } void JNICALL DeleteLocalRef(Thread* t, jobject r) { ENTER(t, Thread::ActiveState); disposeLocalReference(t, r); } jboolean JNICALL ExceptionCheck(Thread* t) { return t->exception != 0; } jclass JNICALL GetObjectClass(Thread* t, jobject o) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, objectClass(t, *o)); } jboolean JNICALL IsInstanceOf(Thread* t, jobject o, jclass c) { ENTER(t, Thread::ActiveState); return instanceOf(t, *c, *o); } object findMethod(Thread* t, object c, const char* name, const char* spec) { PROTECT(t, c); object n = makeByteArray(t, "%s", name); PROTECT(t, n); object s = makeByteArray(t, "%s", spec); return vm::findMethod(t, c, n, s); } jmethodID JNICALL GetMethodID(Thread* t, jclass c, const char* name, const char* spec) { ENTER(t, Thread::ActiveState); object method = findMethod(t, *c, name, spec); if (UNLIKELY(t->exception)) return 0; if (classFlags(t, *c) & ACC_INTERFACE) { PROTECT(t, method); ACQUIRE(t, t->m->referenceLock); for (unsigned i = 0; i < vectorSize(t, t->m->jniInterfaceTable); ++i) { if (method == vectorBody(t, t->m->jniInterfaceTable, i)) { return i; } } t->m->jniInterfaceTable = vectorAppend(t, t->m->jniInterfaceTable, method); return (vectorSize(t, t->m->jniInterfaceTable) - 1) | InterfaceMethodID; } else if (methodVirtual(t, method)) { return methodOffset(t, method) + 1; } else { return methodOffset(t, method) | NonVirtualMethodID; } } jmethodID JNICALL GetStaticMethodID(Thread* t, jclass c, const char* name, const char* spec) { ENTER(t, Thread::ActiveState); object method = findMethod(t, *c, name, spec); if (UNLIKELY(t->exception)) return 0; return methodOffset(t, method) + 1; } inline object getMethod(Thread* t, object o, jmethodID m) { if (m & InterfaceMethodID) { return vectorBody(t, t->m->jniInterfaceTable, m & (~InterfaceMethodID)); } else if (m & NonVirtualMethodID) { return arrayBody(t, classMethodTable(t, objectClass(t, o)), m & (~NonVirtualMethodID)); } else { return arrayBody(t, classVirtualTable(t, objectClass(t, o)), m - 1); } } jobject JNICALL NewObjectV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object o = make(t, *c); PROTECT(t, o); t->m->processor->invokeList(t, getMethod(t, o, m), o, true, a); return makeLocalReference(t, o); } jobject JNICALL NewObject(Thread* t, jclass c, jmethodID m, ...) { va_list a; va_start(a, m); jobject r = NewObjectV(t, c, m, a); va_end(a); return r; } jobject JNICALL CallObjectMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, t->m->processor->invokeList (t, getMethod(t, *o, m), *o, true, a)); } jobject JNICALL CallObjectMethod(Thread* t, jobject o, jmethodID m, ...) { va_list a; va_start(a, m); jobject r = CallObjectMethodV(t, o, m, a); va_end(a); return r; } jboolean JNICALL CallBooleanMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? false : (intValue(t, r) != 0)); } jboolean JNICALL CallBooleanMethod(Thread* t, jobject o, jmethodID m, ...) { va_list a; va_start(a, m); jboolean r = CallBooleanMethodV(t, o, m, a); va_end(a); return r; } jbyte JNICALL CallByteMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : intValue(t, r)); } jbyte JNICALL CallByteMethod(Thread* t, jobject o, jmethodID m, ...) { va_list a; va_start(a, m); jbyte r = CallByteMethodV(t, o, m, a); va_end(a); return r; } jchar JNICALL CallCharMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : intValue(t, r)); } jchar JNICALL CallCharMethod(Thread* t, jobject o, jmethodID m, ...) { va_list a; va_start(a, m); jchar r = CallCharMethodV(t, o, m, a); va_end(a); return r; } jshort JNICALL CallShortMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : intValue(t, r)); } jshort JNICALL CallShortMethod(Thread* t, jobject o, jmethodID m, ...) { va_list a; va_start(a, m); jshort r = CallShortMethodV(t, o, m, a); va_end(a); return r; } jint JNICALL CallIntMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : intValue(t, r)); } jint JNICALL CallIntMethod(Thread* t, jobject o, jmethodID m, ...) { va_list a; va_start(a, m); jint r = CallIntMethodV(t, o, m, a); va_end(a); return r; } jlong JNICALL CallLongMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : longValue(t, r)); } jlong JNICALL CallLongMethod(Thread* t, jobject o, jmethodID m, ...) { va_list a; va_start(a, m); jlong r = CallLongMethodV(t, o, m, a); va_end(a); return r; } jfloat JNICALL CallFloatMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : bitsToFloat(intValue(t, r))); } jfloat JNICALL CallFloatMethod(Thread* t, jobject o, jmethodID m, ...) { va_list a; va_start(a, m); jfloat r = CallFloatMethodV(t, o, m, a); va_end(a); return r; } jdouble JNICALL CallDoubleMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : bitsToDouble(longValue(t, r))); } jdouble JNICALL CallDoubleMethod(Thread* t, jobject o, jmethodID m, ...) { va_list a; va_start(a, m); jdouble r = CallDoubleMethodV(t, o, m, a); va_end(a); return r; } void JNICALL CallVoidMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); } void JNICALL CallVoidMethod(Thread* t, jobject o, jmethodID m, ...) { va_list a; va_start(a, m); CallVoidMethodV(t, o, m, a); va_end(a); } inline object getStaticMethod(Thread* t, object class_, jmethodID m) { return arrayBody(t, classMethodTable(t, class_), m - 1); } jobject JNICALL CallStaticObjectMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, t->m->processor->invokeList (t, getStaticMethod(t, *c, m), 0, true, a)); } jobject JNICALL CallStaticObjectMethod(Thread* t, jclass c, jmethodID m, ...) { va_list a; va_start(a, m); jobject r = CallStaticObjectMethodV(t, c, m, a); va_end(a); return r; } jboolean JNICALL CallStaticBooleanMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : (intValue(t, r) != 0)); } jboolean JNICALL CallStaticBooleanMethod(Thread* t, jclass c, jmethodID m, ...) { va_list a; va_start(a, m); jboolean r = CallStaticBooleanMethodV(t, c, m, a); va_end(a); return r; } jbyte JNICALL CallStaticByteMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } jbyte JNICALL CallStaticByteMethod(Thread* t, jclass c, jmethodID m, ...) { va_list a; va_start(a, m); jbyte r = CallStaticByteMethodV(t, c, m, a); va_end(a); return r; } jchar JNICALL CallStaticCharMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } jchar JNICALL CallStaticCharMethod(Thread* t, jclass c, jmethodID m, ...) { va_list a; va_start(a, m); jchar r = CallStaticCharMethodV(t, c, m, a); va_end(a); return r; } jshort JNICALL CallStaticShortMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } jshort JNICALL CallStaticShortMethod(Thread* t, jclass c, jmethodID m, ...) { va_list a; va_start(a, m); jshort r = CallStaticShortMethodV(t, c, m, a); va_end(a); return r; } jint JNICALL CallStaticIntMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } jint JNICALL CallStaticIntMethod(Thread* t, jclass c, jmethodID m, ...) { va_list a; va_start(a, m); jint r = CallStaticIntMethodV(t, c, m, a); va_end(a); return r; } jlong JNICALL CallStaticLongMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : longValue(t, r)); } jlong JNICALL CallStaticLongMethod(Thread* t, jclass c, jmethodID m, ...) { va_list a; va_start(a, m); jlong r = CallStaticLongMethodV(t, c, m, a); va_end(a); return r; } jfloat JNICALL CallStaticFloatMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : bitsToFloat(intValue(t, r))); } jfloat JNICALL CallStaticFloatMethod(Thread* t, jclass c, jmethodID m, ...) { va_list a; va_start(a, m); jfloat r = CallStaticFloatMethodV(t, c, m, a); va_end(a); return r; } jdouble JNICALL CallStaticDoubleMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); object r = t->m->processor->invokeList (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : bitsToDouble(longValue(t, r))); } jdouble JNICALL CallStaticDoubleMethod(Thread* t, jclass c, jmethodID m, ...) { va_list a; va_start(a, m); jdouble r = CallStaticDoubleMethodV(t, c, m, a); va_end(a); return r; } void JNICALL CallStaticVoidMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); t->m->processor->invokeList(t, getStaticMethod(t, *c, m), 0, true, a); } void JNICALL CallStaticVoidMethod(Thread* t, jclass c, jmethodID m, ...) { va_list a; va_start(a, m); CallStaticVoidMethodV(t, c, m, a); va_end(a); } object findField(Thread* t, object class_, const char* name, const char* spec) { object n = makeByteArray(t, "%s", name); PROTECT(t, n); object s = makeByteArray(t, "%s", spec); return vm::findField(t, class_, n, s); } jfieldID JNICALL GetFieldID(Thread* t, jclass c, const char* name, const char* spec) { ENTER(t, Thread::ActiveState); object field = findField(t, *c, name, spec); if (UNLIKELY(t->exception)) return 0; return fieldOffset(t, field); } jfieldID JNICALL GetStaticFieldID(Thread* t, jclass c, const char* name, const char* spec) { ENTER(t, Thread::ActiveState); object field = findField(t, *c, name, spec); if (UNLIKELY(t->exception)) return 0; return fieldOffset(t, field); } jobject JNICALL GetObjectField(Thread* t, jobject o, jfieldID field) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, cast(*o, field)); } jboolean JNICALL GetBooleanField(Thread* t, jobject o, jfieldID field) { ENTER(t, Thread::ActiveState); return cast(*o, field); } jbyte JNICALL GetByteField(Thread* t, jobject o, jfieldID field) { ENTER(t, Thread::ActiveState); return cast(*o, field); } jchar JNICALL GetCharField(Thread* t, jobject o, jfieldID field) { ENTER(t, Thread::ActiveState); return cast(*o, field); } jshort JNICALL GetShortField(Thread* t, jobject o, jfieldID field) { ENTER(t, Thread::ActiveState); return cast(*o, field); } jint JNICALL GetIntField(Thread* t, jobject o, jfieldID field) { ENTER(t, Thread::ActiveState); return cast(*o, field); } jlong JNICALL GetLongField(Thread* t, jobject o, jfieldID field) { ENTER(t, Thread::ActiveState); return cast(*o, field); } jfloat JNICALL GetFloatField(Thread* t, jobject o, jfieldID field) { ENTER(t, Thread::ActiveState); return cast(*o, field); } jdouble JNICALL GetDoubleField(Thread* t, jobject o, jfieldID field) { ENTER(t, Thread::ActiveState); return cast(*o, field); } void JNICALL SetObjectField(Thread* t, jobject o, jfieldID field, jobject v) { ENTER(t, Thread::ActiveState); set(t, *o, field, (v ? *v : 0)); } void JNICALL SetBooleanField(Thread* t, jobject o, jfieldID field, jboolean v) { ENTER(t, Thread::ActiveState); cast(*o, field) = v; } void JNICALL SetByteField(Thread* t, jobject o, jfieldID field, jbyte v) { ENTER(t, Thread::ActiveState); cast(*o, field) = v; } void JNICALL SetCharField(Thread* t, jobject o, jfieldID field, jchar v) { ENTER(t, Thread::ActiveState); cast(*o, field) = v; } void JNICALL SetShortField(Thread* t, jobject o, jfieldID field, jshort v) { ENTER(t, Thread::ActiveState); cast(*o, field) = v; } void JNICALL SetIntField(Thread* t, jobject o, jfieldID field, jint v) { ENTER(t, Thread::ActiveState); cast(*o, field) = v; } void JNICALL SetLongField(Thread* t, jobject o, jfieldID field, jlong v) { ENTER(t, Thread::ActiveState); cast(*o, field) = v; } void JNICALL SetFloatField(Thread* t, jobject o, jfieldID field, jfloat v) { ENTER(t, Thread::ActiveState); cast(*o, field) = v; } void JNICALL SetDoubleField(Thread* t, jobject o, jfieldID field, jdouble v) { ENTER(t, Thread::ActiveState); cast(*o, field) = v; } jobject JNICALL GetStaticObjectField(Thread* t, jclass c, jfieldID field) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, arrayBody(t, classStaticTable(t, *c), field)); } jboolean JNICALL GetStaticBooleanField(Thread* t, jclass c, jfieldID field) { ENTER(t, Thread::ActiveState); object v = arrayBody(t, classStaticTable(t, *c), field); return v ? intValue(t, v) != 0 : false; } jbyte JNICALL GetStaticByteField(Thread* t, jclass c, jfieldID field) { ENTER(t, Thread::ActiveState); object v = arrayBody(t, classStaticTable(t, *c), field); return static_cast(v ? intValue(t, v) : 0); } jchar JNICALL GetStaticCharField(Thread* t, jclass c, jfieldID field) { ENTER(t, Thread::ActiveState); object v = arrayBody(t, classStaticTable(t, *c), field); return static_cast(v ? intValue(t, v) : 0); } jshort JNICALL GetStaticShortField(Thread* t, jclass c, jfieldID field) { ENTER(t, Thread::ActiveState); object v = arrayBody(t, classStaticTable(t, *c), field); return static_cast(v ? intValue(t, v) : 0); } jint JNICALL GetStaticIntField(Thread* t, jclass c, jfieldID field) { ENTER(t, Thread::ActiveState); object v = arrayBody(t, classStaticTable(t, *c), field); return v ? intValue(t, v) : 0; } jlong JNICALL GetStaticLongField(Thread* t, jclass c, jfieldID field) { ENTER(t, Thread::ActiveState); object v = arrayBody(t, classStaticTable(t, *c), field); return static_cast(v ? longValue(t, v) : 0); } jfloat JNICALL GetStaticFloatField(Thread* t, jclass c, jfieldID field) { ENTER(t, Thread::ActiveState); object v = arrayBody(t, classStaticTable(t, *c), field); jint i = v ? intValue(t, v) : 0; jfloat f; memcpy(&f, &i, 4); return f; } jdouble JNICALL GetStaticDoubleField(Thread* t, jclass c, jfieldID field) { ENTER(t, Thread::ActiveState); object v = arrayBody(t, classStaticTable(t, *c), field); jlong i = v ? longValue(t, v) : 0; jdouble f; memcpy(&f, &i, 4); return f; } void JNICALL SetStaticObjectField(Thread* t, jclass c, jfieldID field, jobject v) { ENTER(t, Thread::ActiveState); set(t, classStaticTable(t, *c), ArrayBody + (field * BytesPerWord), (v ? *v : 0)); } void JNICALL SetStaticBooleanField(Thread* t, jclass c, jfieldID field, jboolean v) { ENTER(t, Thread::ActiveState); object o = makeInt(t, v ? 1 : 0); set(t, classStaticTable(t, *c), ArrayBody + (field * BytesPerWord), o); } void JNICALL SetStaticByteField(Thread* t, jclass c, jfieldID field, jbyte v) { ENTER(t, Thread::ActiveState); object o = makeInt(t, v); set(t, classStaticTable(t, *c), ArrayBody + (field * BytesPerWord), o); } void JNICALL SetStaticCharField(Thread* t, jclass c, jfieldID field, jchar v) { ENTER(t, Thread::ActiveState); object o = makeInt(t, v); set(t, classStaticTable(t, *c), ArrayBody + (field * BytesPerWord), o); } void JNICALL SetStaticShortField(Thread* t, jclass c, jfieldID field, jshort v) { ENTER(t, Thread::ActiveState); object o = makeInt(t, v); set(t, classStaticTable(t, *c), ArrayBody + (field * BytesPerWord), o); } void JNICALL SetStaticIntField(Thread* t, jclass c, jfieldID field, jint v) { ENTER(t, Thread::ActiveState); object o = makeInt(t, v); set(t, classStaticTable(t, *c), ArrayBody + (field * BytesPerWord), o); } void JNICALL SetStaticLongField(Thread* t, jclass c, jfieldID field, jlong v) { ENTER(t, Thread::ActiveState); object o = makeLong(t, v); set(t, classStaticTable(t, *c), ArrayBody + (field * BytesPerWord), o); } void JNICALL SetStaticFloatField(Thread* t, jclass c, jfieldID field, jfloat v) { ENTER(t, Thread::ActiveState); jint i; memcpy(&i, &v, 4); object o = makeInt(t, i); set(t, classStaticTable(t, *c), ArrayBody + (field * BytesPerWord), o); } void JNICALL SetStaticDoubleField(Thread* t, jclass c, jfieldID field, jdouble v) { ENTER(t, Thread::ActiveState); jlong i; memcpy(&i, &v, 8); object o = makeLong(t, i); set(t, classStaticTable(t, *c), ArrayBody + (field * BytesPerWord), o); } jobject JNICALL NewGlobalRef(Thread* t, jobject o) { ENTER(t, Thread::ActiveState); ACQUIRE(t, t->m->referenceLock); if (o) { Reference* r = new (t->m->heap->allocate(sizeof(Reference), false)) Reference(*o, &(t->m->jniReferences)); return &(r->target); } else { return 0; } } void JNICALL DeleteGlobalRef(Thread* t, jobject r) { ENTER(t, Thread::ActiveState); ACQUIRE(t, t->m->referenceLock); if (r) { dispose(t, reinterpret_cast(r)); } } jthrowable JNICALL ExceptionOccurred(Thread* t) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, t->exception); } void JNICALL ExceptionDescribe(Thread* t) { ENTER(t, Thread::ActiveState); return printTrace(t, t->exception); } void JNICALL ExceptionClear(Thread* t) { ENTER(t, Thread::ActiveState); t->exception = 0; } jobjectArray JNICALL NewObjectArray(Thread* t, jsize length, jclass class_, jobject init) { ENTER(t, Thread::ActiveState); object a = makeObjectArray(t, *class_, length, false); object value = (init ? *init : 0); for (jsize i = 0; i < length; ++i) { set(t, a, ArrayBody + (i * BytesPerWord), value); } return makeLocalReference(t, a); } jobject JNICALL GetObjectArrayElement(Thread* t, jobjectArray array, jsize index) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, objectArrayBody(t, *array, index)); } void JNICALL SetObjectArrayElement(Thread* t, jobjectArray array, jsize index, jobject value) { ENTER(t, Thread::ActiveState); set(t, *array, ArrayBody + (index * BytesPerWord), *value); } jbooleanArray JNICALL NewBooleanArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, makeBooleanArray(t, length, true)); } jbyteArray JNICALL NewByteArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, makeByteArray(t, length, true)); } jcharArray JNICALL NewCharArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, makeCharArray(t, length, true)); } jshortArray JNICALL NewShortArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, makeShortArray(t, length, true)); } jintArray JNICALL NewIntArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, makeIntArray(t, length, true)); } jlongArray JNICALL NewLongArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, makeLongArray(t, length, true)); } jfloatArray JNICALL NewFloatArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, makeFloatArray(t, length, true)); } jdoubleArray JNICALL NewDoubleArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, makeDoubleArray(t, length, true)); } jboolean* JNICALL GetBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* isCopy) { ENTER(t, Thread::ActiveState); unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean); jboolean* p = static_cast(t->m->heap->allocate(size, false)); if (size) { memcpy(p, &booleanArrayBody(t, *array, 0), size); } if (isCopy) { *isCopy = true; } return p; } jbyte* JNICALL GetByteArrayElements(Thread* t, jbyteArray array, jboolean* isCopy) { ENTER(t, Thread::ActiveState); unsigned size = byteArrayLength(t, *array) * sizeof(jbyte); jbyte* p = static_cast(t->m->heap->allocate(size, false)); if (size) { memcpy(p, &byteArrayBody(t, *array, 0), size); } if (isCopy) { *isCopy = true; } return p; } jchar* JNICALL GetCharArrayElements(Thread* t, jcharArray array, jboolean* isCopy) { ENTER(t, Thread::ActiveState); unsigned size = charArrayLength(t, *array) * sizeof(jchar); jchar* p = static_cast(t->m->heap->allocate(size, false)); if (size) { memcpy(p, &charArrayBody(t, *array, 0), size); } if (isCopy) { *isCopy = true; } return p; } jshort* JNICALL GetShortArrayElements(Thread* t, jshortArray array, jboolean* isCopy) { ENTER(t, Thread::ActiveState); unsigned size = shortArrayLength(t, *array) * sizeof(jshort); jshort* p = static_cast(t->m->heap->allocate(size, false)); if (size) { memcpy(p, &shortArrayBody(t, *array, 0), size); } if (isCopy) { *isCopy = true; } return p; } jint* JNICALL GetIntArrayElements(Thread* t, jintArray array, jboolean* isCopy) { ENTER(t, Thread::ActiveState); unsigned size = intArrayLength(t, *array) * sizeof(jint); jint* p = static_cast(t->m->heap->allocate(size, false)); if (size) { memcpy(p, &intArrayBody(t, *array, 0), size); } if (isCopy) { *isCopy = true; } return p; } jlong* JNICALL GetLongArrayElements(Thread* t, jlongArray array, jboolean* isCopy) { ENTER(t, Thread::ActiveState); unsigned size = longArrayLength(t, *array) * sizeof(jlong); jlong* p = static_cast(t->m->heap->allocate(size, false)); if (size) { memcpy(p, &longArrayBody(t, *array, 0), size); } if (isCopy) { *isCopy = true; } return p; } jfloat* JNICALL GetFloatArrayElements(Thread* t, jfloatArray array, jboolean* isCopy) { ENTER(t, Thread::ActiveState); unsigned size = floatArrayLength(t, *array) * sizeof(jfloat); jfloat* p = static_cast(t->m->heap->allocate(size, false)); if (size) { memcpy(p, &floatArrayBody(t, *array, 0), size); } if (isCopy) { *isCopy = true; } return p; } jdouble* JNICALL GetDoubleArrayElements(Thread* t, jdoubleArray array, jboolean* isCopy) { ENTER(t, Thread::ActiveState); unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble); jdouble* p = static_cast(t->m->heap->allocate(size, false)); if (size) { memcpy(p, &doubleArrayBody(t, *array, 0), size); } if (isCopy) { *isCopy = true; } return p; } void JNICALL ReleaseBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* p, jint mode) { ENTER(t, Thread::ActiveState); unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean); if (mode == 0 or mode == JNI_COMMIT) { if (size) { memcpy(&booleanArrayBody(t, *array, 0), p, size); } } if (mode == 0 or mode == JNI_ABORT) { t->m->heap->free(p, size, false); } } void JNICALL ReleaseByteArrayElements(Thread* t, jbyteArray array, jbyte* p, jint mode) { ENTER(t, Thread::ActiveState); unsigned size = byteArrayLength(t, *array) * sizeof(jbyte); if (mode == 0 or mode == JNI_COMMIT) { if (size) { memcpy(&byteArrayBody(t, *array, 0), p, size); } } if (mode == 0 or mode == JNI_ABORT) { t->m->heap->free(p, size, false); } } void JNICALL ReleaseCharArrayElements(Thread* t, jcharArray array, jchar* p, jint mode) { ENTER(t, Thread::ActiveState); unsigned size = charArrayLength(t, *array) * sizeof(jchar); if (mode == 0 or mode == JNI_COMMIT) { if (size) { memcpy(&charArrayBody(t, *array, 0), p, size); } } if (mode == 0 or mode == JNI_ABORT) { t->m->heap->free(p, size, false); } } void JNICALL ReleaseShortArrayElements(Thread* t, jshortArray array, jshort* p, jint mode) { ENTER(t, Thread::ActiveState); unsigned size = shortArrayLength(t, *array) * sizeof(jshort); if (mode == 0 or mode == JNI_COMMIT) { if (size) { memcpy(&shortArrayBody(t, *array, 0), p, size); } } if (mode == 0 or mode == JNI_ABORT) { t->m->heap->free(p, size, false); } } void JNICALL ReleaseIntArrayElements(Thread* t, jintArray array, jint* p, jint mode) { ENTER(t, Thread::ActiveState); unsigned size = intArrayLength(t, *array) * sizeof(jint); if (mode == 0 or mode == JNI_COMMIT) { if (size) { memcpy(&intArrayBody(t, *array, 0), p, size); } } if (mode == 0 or mode == JNI_ABORT) { t->m->heap->free(p, size, false); } } void JNICALL ReleaseLongArrayElements(Thread* t, jlongArray array, jlong* p, jint mode) { ENTER(t, Thread::ActiveState); unsigned size = longArrayLength(t, *array) * sizeof(jlong); if (mode == 0 or mode == JNI_COMMIT) { if (size) { memcpy(&longArrayBody(t, *array, 0), p, size); } } if (mode == 0 or mode == JNI_ABORT) { t->m->heap->free(p, size, false); } } void JNICALL ReleaseFloatArrayElements(Thread* t, jfloatArray array, jfloat* p, jint mode) { ENTER(t, Thread::ActiveState); unsigned size = floatArrayLength(t, *array) * sizeof(jfloat); if (mode == 0 or mode == JNI_COMMIT) { if (size) { memcpy(&floatArrayBody(t, *array, 0), p, size); } } if (mode == 0 or mode == JNI_ABORT) { t->m->heap->free(p, size, false); } } void JNICALL ReleaseDoubleArrayElements(Thread* t, jdoubleArray array, jdouble* p, jint mode) { ENTER(t, Thread::ActiveState); unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble); if (mode == 0 or mode == JNI_COMMIT) { if (size) { memcpy(&doubleArrayBody(t, *array, 0), p, size); } } if (mode == 0 or mode == JNI_ABORT) { t->m->heap->free(p, size, false); } } void JNICALL GetBooleanArrayRegion(Thread* t, jbooleanArray array, jint offset, jint length, jboolean* dst) { ENTER(t, Thread::ActiveState); if (length) { memcpy(dst, &booleanArrayBody(t, *array, offset), length * sizeof(jboolean)); } } void JNICALL GetByteArrayRegion(Thread* t, jbyteArray array, jint offset, jint length, jbyte* dst) { ENTER(t, Thread::ActiveState); if (length) { memcpy(dst, &byteArrayBody(t, *array, offset), length * sizeof(jbyte)); } } void JNICALL GetCharArrayRegion(Thread* t, jcharArray array, jint offset, jint length, jchar* dst) { ENTER(t, Thread::ActiveState); if (length) { memcpy(dst, &charArrayBody(t, *array, offset), length * sizeof(jchar)); } } void JNICALL GetShortArrayRegion(Thread* t, jshortArray array, jint offset, jint length, jshort* dst) { ENTER(t, Thread::ActiveState); if (length) { memcpy(dst, &shortArrayBody(t, *array, offset), length * sizeof(jshort)); } } void JNICALL GetIntArrayRegion(Thread* t, jintArray array, jint offset, jint length, jint* dst) { ENTER(t, Thread::ActiveState); if (length) { memcpy(dst, &intArrayBody(t, *array, offset), length * sizeof(jint)); } } void JNICALL GetLongArrayRegion(Thread* t, jlongArray array, jint offset, jint length, jlong* dst) { ENTER(t, Thread::ActiveState); if (length) { memcpy(dst, &longArrayBody(t, *array, offset), length * sizeof(jlong)); } } void JNICALL GetFloatArrayRegion(Thread* t, jfloatArray array, jint offset, jint length, jfloat* dst) { ENTER(t, Thread::ActiveState); if (length) { memcpy(dst, &floatArrayBody(t, *array, offset), length * sizeof(jfloat)); } } void JNICALL GetDoubleArrayRegion(Thread* t, jdoubleArray array, jint offset, jint length, jdouble* dst) { ENTER(t, Thread::ActiveState); if (length) { memcpy(dst, &doubleArrayBody(t, *array, offset), length * sizeof(jdouble)); } } void JNICALL SetBooleanArrayRegion(Thread* t, jbooleanArray array, jint offset, jint length, const jboolean* src) { ENTER(t, Thread::ActiveState); if (length) { memcpy(&booleanArrayBody(t, *array, offset), src, length * sizeof(jboolean)); } } void JNICALL SetByteArrayRegion(Thread* t, jbyteArray array, jint offset, jint length, const jbyte* src) { ENTER(t, Thread::ActiveState); if (length) { memcpy(&byteArrayBody(t, *array, offset), src, length * sizeof(jbyte)); } } void JNICALL SetCharArrayRegion(Thread* t, jcharArray array, jint offset, jint length, const jchar* src) { ENTER(t, Thread::ActiveState); if (length) { memcpy(&charArrayBody(t, *array, offset), src, length * sizeof(jchar)); } } void JNICALL SetShortArrayRegion(Thread* t, jshortArray array, jint offset, jint length, const jshort* src) { ENTER(t, Thread::ActiveState); if (length) { memcpy(&shortArrayBody(t, *array, offset), src, length * sizeof(jshort)); } } void JNICALL SetIntArrayRegion(Thread* t, jintArray array, jint offset, jint length, const jint* src) { ENTER(t, Thread::ActiveState); if (length) { memcpy(&intArrayBody(t, *array, offset), src, length * sizeof(jint)); } } void JNICALL SetLongArrayRegion(Thread* t, jlongArray array, jint offset, jint length, const jlong* src) { ENTER(t, Thread::ActiveState); if (length) { memcpy(&longArrayBody(t, *array, offset), src, length * sizeof(jlong)); } } void JNICALL SetFloatArrayRegion(Thread* t, jfloatArray array, jint offset, jint length, const jfloat* src) { ENTER(t, Thread::ActiveState); if (length) { memcpy(&floatArrayBody(t, *array, offset), src, length * sizeof(jfloat)); } } void JNICALL SetDoubleArrayRegion(Thread* t, jdoubleArray array, jint offset, jint length, const jdouble* src) { ENTER(t, Thread::ActiveState); if (length) { memcpy(&doubleArrayBody(t, *array, offset), src, length * sizeof(jdouble)); } } void* JNICALL GetPrimitiveArrayCritical(Thread* t, jarray array, jboolean* isCopy) { if ((t->criticalLevel ++) == 0) { enter(t, Thread::ActiveState); } if (isCopy) { *isCopy = true; } return reinterpret_cast(*array) + 2; } void JNICALL ReleasePrimitiveArrayCritical(Thread* t, jarray, void*, jint) { if ((-- t->criticalLevel) == 0) { enter(t, Thread::IdleState); } } jint JNICALL MonitorEnter(Thread* t, jobject o) { ENTER(t, Thread::ActiveState); acquire(t, *o); return 0; } jint JNICALL MonitorExit(Thread* t, jobject o) { ENTER(t, Thread::ActiveState); release(t, *o); return 0; } jint JNICALL GetJavaVM(Thread* t, Machine** m) { *m = t->m; return 0; } jboolean JNICALL IsSameObject(Thread* t, jobject a, jobject b) { ENTER(t, Thread::ActiveState); return *a == *b; } struct JDK1_1InitArgs { jint version; const char** properties; jint checkSource; jint nativeStackSize; jint javaStackSize; jint minHeapSize; jint maxHeapSize; jint verifyMode; const char* classpath; jint (JNICALL *vfprintf)(FILE* fp, const char* format, va_list args); void (JNICALL *exit)(jint code); void (JNICALL *abort)(void); jint enableClassGC; jint enableVerboseGC; jint disableAsyncGC; jint verbose; jboolean debugging; jint debugPort; }; } // namespace namespace vm { void populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable) { memset(vmTable, 0, sizeof(JavaVMVTable)); vmTable->DestroyJavaVM = DestroyJavaVM; vmTable->AttachCurrentThread = AttachCurrentThread; vmTable->DetachCurrentThread = DetachCurrentThread; vmTable->GetEnv = GetEnv; memset(envTable, 0, sizeof(JNIEnvVTable)); envTable->GetStringUTFLength = ::GetStringUTFLength; envTable->GetStringUTFChars = ::GetStringUTFChars; envTable->ReleaseStringUTFChars = ::ReleaseStringUTFChars; envTable->GetArrayLength = ::GetArrayLength; envTable->NewString = ::NewString; envTable->NewStringUTF = ::NewStringUTF; envTable->FindClass = ::FindClass; envTable->ThrowNew = ::ThrowNew; envTable->ExceptionCheck = ::ExceptionCheck; envTable->DeleteLocalRef = ::DeleteLocalRef; envTable->GetObjectClass = ::GetObjectClass; envTable->IsInstanceOf = ::IsInstanceOf; envTable->GetFieldID = ::GetFieldID; envTable->GetMethodID = ::GetMethodID; envTable->GetStaticMethodID = ::GetStaticMethodID; envTable->NewObject = ::NewObject; envTable->NewObjectV = ::NewObjectV; envTable->CallObjectMethodV = ::CallObjectMethodV; envTable->CallObjectMethod = ::CallObjectMethod; envTable->CallBooleanMethodV = ::CallBooleanMethodV; envTable->CallBooleanMethod = ::CallBooleanMethod; envTable->CallByteMethodV = ::CallByteMethodV; envTable->CallByteMethod = ::CallByteMethod; envTable->CallCharMethodV = ::CallCharMethodV; envTable->CallCharMethod = ::CallCharMethod; envTable->CallShortMethodV = ::CallShortMethodV; envTable->CallShortMethod = ::CallShortMethod; envTable->CallIntMethodV = ::CallIntMethodV; envTable->CallIntMethod = ::CallIntMethod; envTable->CallLongMethodV = ::CallLongMethodV; envTable->CallLongMethod = ::CallLongMethod; envTable->CallFloatMethodV = ::CallFloatMethodV; envTable->CallFloatMethod = ::CallFloatMethod; envTable->CallDoubleMethodV = ::CallDoubleMethodV; envTable->CallDoubleMethod = ::CallDoubleMethod; envTable->CallVoidMethodV = ::CallVoidMethodV; envTable->CallVoidMethod = ::CallVoidMethod; envTable->CallStaticObjectMethodV = ::CallStaticObjectMethodV; envTable->CallStaticObjectMethod = ::CallStaticObjectMethod; envTable->CallStaticBooleanMethodV = ::CallStaticBooleanMethodV; envTable->CallStaticBooleanMethod = ::CallStaticBooleanMethod; envTable->CallStaticByteMethodV = ::CallStaticByteMethodV; envTable->CallStaticByteMethod = ::CallStaticByteMethod; envTable->CallStaticCharMethodV = ::CallStaticCharMethodV; envTable->CallStaticCharMethod = ::CallStaticCharMethod; envTable->CallStaticShortMethodV = ::CallStaticShortMethodV; envTable->CallStaticShortMethod = ::CallStaticShortMethod; envTable->CallStaticIntMethodV = ::CallStaticIntMethodV; envTable->CallStaticIntMethod = ::CallStaticIntMethod; envTable->CallStaticLongMethodV = ::CallStaticLongMethodV; envTable->CallStaticLongMethod = ::CallStaticLongMethod; envTable->CallStaticFloatMethodV = ::CallStaticFloatMethodV; envTable->CallStaticFloatMethod = ::CallStaticFloatMethod; envTable->CallStaticDoubleMethodV = ::CallStaticDoubleMethodV; envTable->CallStaticDoubleMethod = ::CallStaticDoubleMethod; envTable->CallStaticVoidMethodV = ::CallStaticVoidMethodV; envTable->CallStaticVoidMethod = ::CallStaticVoidMethod; envTable->GetStaticFieldID = ::GetStaticFieldID; envTable->GetObjectField = ::GetObjectField; envTable->GetBooleanField = ::GetBooleanField; envTable->GetByteField = ::GetByteField; envTable->GetCharField = ::GetCharField; envTable->GetShortField = ::GetShortField; envTable->GetIntField = ::GetIntField; envTable->GetLongField = ::GetLongField; envTable->GetFloatField = ::GetFloatField; envTable->GetDoubleField = ::GetDoubleField; envTable->SetObjectField = ::SetObjectField; envTable->SetBooleanField = ::SetBooleanField; envTable->SetByteField = ::SetByteField; envTable->SetCharField = ::SetCharField; envTable->SetShortField = ::SetShortField; envTable->SetIntField = ::SetIntField; envTable->SetLongField = ::SetLongField; envTable->SetFloatField = ::SetFloatField; envTable->SetDoubleField = ::SetDoubleField; envTable->GetStaticObjectField = ::GetStaticObjectField; envTable->GetStaticBooleanField = ::GetStaticBooleanField; envTable->GetStaticByteField = ::GetStaticByteField; envTable->GetStaticCharField = ::GetStaticCharField; envTable->GetStaticShortField = ::GetStaticShortField; envTable->GetStaticIntField = ::GetStaticIntField; envTable->GetStaticLongField = ::GetStaticLongField; envTable->GetStaticFloatField = ::GetStaticFloatField; envTable->GetStaticDoubleField = ::GetStaticDoubleField; envTable->SetStaticObjectField = ::SetStaticObjectField; envTable->SetStaticBooleanField = ::SetStaticBooleanField; envTable->SetStaticByteField = ::SetStaticByteField; envTable->SetStaticCharField = ::SetStaticCharField; envTable->SetStaticShortField = ::SetStaticShortField; envTable->SetStaticIntField = ::SetStaticIntField; envTable->SetStaticLongField = ::SetStaticLongField; envTable->SetStaticFloatField = ::SetStaticFloatField; envTable->SetStaticDoubleField = ::SetStaticDoubleField; envTable->NewGlobalRef = ::NewGlobalRef; envTable->DeleteGlobalRef = ::DeleteGlobalRef; envTable->ExceptionOccurred = ::ExceptionOccurred; envTable->ExceptionDescribe = ::ExceptionDescribe; envTable->ExceptionClear = ::ExceptionClear; envTable->NewObjectArray = ::NewObjectArray; envTable->GetObjectArrayElement = ::GetObjectArrayElement; envTable->SetObjectArrayElement = ::SetObjectArrayElement; envTable->NewBooleanArray = ::NewBooleanArray; envTable->NewByteArray = ::NewByteArray; envTable->NewCharArray = ::NewCharArray; envTable->NewShortArray = ::NewShortArray; envTable->NewIntArray = ::NewIntArray; envTable->NewLongArray = ::NewLongArray; envTable->NewFloatArray = ::NewFloatArray; envTable->NewDoubleArray = ::NewDoubleArray; envTable->GetBooleanArrayElements = ::GetBooleanArrayElements; envTable->GetByteArrayElements = ::GetByteArrayElements; envTable->GetCharArrayElements = ::GetCharArrayElements; envTable->GetShortArrayElements = ::GetShortArrayElements; envTable->GetIntArrayElements = ::GetIntArrayElements; envTable->GetLongArrayElements = ::GetLongArrayElements; envTable->GetFloatArrayElements = ::GetFloatArrayElements; envTable->GetDoubleArrayElements = ::GetDoubleArrayElements; envTable->ReleaseBooleanArrayElements = ::ReleaseBooleanArrayElements; envTable->ReleaseByteArrayElements = ::ReleaseByteArrayElements; envTable->ReleaseCharArrayElements = ::ReleaseCharArrayElements; envTable->ReleaseShortArrayElements = ::ReleaseShortArrayElements; envTable->ReleaseIntArrayElements = ::ReleaseIntArrayElements; envTable->ReleaseLongArrayElements = ::ReleaseLongArrayElements; envTable->ReleaseFloatArrayElements = ::ReleaseFloatArrayElements; envTable->ReleaseDoubleArrayElements = ::ReleaseDoubleArrayElements; envTable->GetBooleanArrayRegion = ::GetBooleanArrayRegion; envTable->GetByteArrayRegion = ::GetByteArrayRegion; envTable->GetCharArrayRegion = ::GetCharArrayRegion; envTable->GetShortArrayRegion = ::GetShortArrayRegion; envTable->GetIntArrayRegion = ::GetIntArrayRegion; envTable->GetLongArrayRegion = ::GetLongArrayRegion; envTable->GetFloatArrayRegion = ::GetFloatArrayRegion; envTable->GetDoubleArrayRegion = ::GetDoubleArrayRegion; envTable->SetBooleanArrayRegion = ::SetBooleanArrayRegion; envTable->SetByteArrayRegion = ::SetByteArrayRegion; envTable->SetCharArrayRegion = ::SetCharArrayRegion; envTable->SetShortArrayRegion = ::SetShortArrayRegion; envTable->SetIntArrayRegion = ::SetIntArrayRegion; envTable->SetLongArrayRegion = ::SetLongArrayRegion; envTable->SetFloatArrayRegion = ::SetFloatArrayRegion; envTable->SetDoubleArrayRegion = ::SetDoubleArrayRegion; envTable->GetPrimitiveArrayCritical = ::GetPrimitiveArrayCritical; envTable->ReleasePrimitiveArrayCritical = ::ReleasePrimitiveArrayCritical; envTable->MonitorEnter = MonitorEnter; envTable->MonitorExit = MonitorExit; envTable->GetJavaVM = ::GetJavaVM; envTable->IsSameObject = ::IsSameObject; } } // namespace vm extern "C" JNIEXPORT jint JNICALL JNI_GetDefaultJavaVMInitArgs(void* args) { JDK1_1InitArgs* a = static_cast(args); a->maxHeapSize = 128 * 1024 * 1024; a->classpath = "."; a->properties = 0; return 0; } #define BUILTINS_PROPERTY "vm.builtins" extern "C" JNIEXPORT jint JNICALL JNI_CreateJavaVM(Machine** m, Thread** t, void* args) { JDK1_1InitArgs* a = static_cast(args); System* s = makeSystem(); Heap* h = makeHeap(s, a->maxHeapSize); Finder* f = makeFinder(s, a->classpath); Processor* p = makeProcessor(s, h); *m = new (h->allocate(sizeof(Machine), false)) Machine(s, h, f, p); if (a->properties) { for (const char** p = a->properties; *p; ++p) { if (strncmp(*p, BUILTINS_PROPERTY "=", sizeof(BUILTINS_PROPERTY)) == 0) { (*m)->builtins = (*p) + sizeof(BUILTINS_PROPERTY); } } } *t = p->makeThread(*m, 0, 0); enter(*t, Thread::ActiveState); enter(*t, Thread::IdleState); return 0; }