From 555280cb0cbd2421f0636ece1a78ca34d38c1fc1 Mon Sep 17 00:00:00 2001 From: jfrijters Date: Fri, 23 Apr 2004 11:34:32 +0000 Subject: [PATCH] *** empty log message *** --- IK.VM.JNI/jni.h | 4 ++ IK.VM.JNI/jnienv.cpp | 99 ++++++++++++++++++++++----------------- IK.VM.NET/JniInterface.cs | 9 ++++ 3 files changed, 70 insertions(+), 42 deletions(-) diff --git a/IK.VM.JNI/jni.h b/IK.VM.JNI/jni.h index b4cee3e2..0945e5cd 100644 --- a/IK.VM.JNI/jni.h +++ b/IK.VM.JNI/jni.h @@ -148,4 +148,8 @@ public: { return JniHelper::GetClassFromType(type); } + static Object* AllocObject(Object* clazz) + { + return JniHelper::AllocObject(clazz); + } }; diff --git a/IK.VM.JNI/jnienv.cpp b/IK.VM.JNI/jnienv.cpp index 14545020..58fc1b57 100644 --- a/IK.VM.JNI/jnienv.cpp +++ b/IK.VM.JNI/jnienv.cpp @@ -234,19 +234,15 @@ jclass JNIEnv::FindClass(const char *utf) { return (jclass)(void*)pLocalRefs->MakeLocalRef(VM::FindClass(StringFromUTF8(utf))); } -#pragma unmanaged jobject JNIEnv::AllocObject(jclass cls) { // wicked, I just realized that serialization should have a facility to construct uninitialized objects // this can be implemented using FormatterServices.GetUninitializedObject, the only hitch is that this // won't supports strings, so we may have to figure out a workaround for that, or decide just not to support it - assert(false); - _asm int 3 + return (jobject)(void*)pLocalRefs->MakeLocalRef(VM::AllocObject(UnwrapRef(cls))); } -#pragma managed - jmethodID JNIEnv::FindMethodID(jclass cls, const char* name, const char* sig, bool isstatic) { jmethodID mid = (jmethodID)(void*)VM::GetMethodCookie(UnwrapRef(cls), StringFromUTF8(name), StringFromUTF8(sig), isstatic); @@ -864,15 +860,15 @@ GET_SET_ARRAY_REGION(Long, jlong, __int64) GET_SET_ARRAY_REGION(Float, jfloat, float) GET_SET_ARRAY_REGION(Double, jdouble, double) - #define GET_SET_ARRAY_ELEMENTS(Type,type,cpptype) \ type* JNIEnv::Get##Type##ArrayElements(type##Array array, jboolean *isCopy)\ {\ cpptype ar __gc[] = __try_cast(UnwrapRef(array));\ type* p = new type[ar->Length];\ - for(int i = 0; i < ar->Length; i++)\ + if(ar->Length)\ {\ - p[i] = ar[i];\ + cpptype __pin* par = &ar[0];\ + memcpy(p, par, ar->Length * sizeof(cpptype));\ }\ if(isCopy)\ {\ @@ -882,24 +878,16 @@ type* JNIEnv::Get##Type##ArrayElements(type##Array array, jboolean *isCopy)\ }\ void JNIEnv::Release##Type##ArrayElements(type##Array array, type *elems, jint mode)\ {\ - if(mode == 0)\ + if(mode == 0 || mode == JNI_COMMIT)\ {\ cpptype ar __gc[] = __try_cast(UnwrapRef(array));\ - for(int i = 0; i < ar->Length; i++)\ + if(ar->Length)\ {\ - ar[i] = elems[i];\ - }\ - delete[] elems;\ - }\ - else if(mode == JNI_COMMIT)\ - {\ - cpptype ar __gc[] = __try_cast(UnwrapRef(array));\ - for(int i = 0; i < ar->Length; i++)\ - {\ - ar[i] = elems[i];\ + cpptype __pin* p = &ar[0];\ + memcpy(p, elems, ar->Length * sizeof(cpptype));\ }\ }\ - else if(mode == JNI_ABORT)\ + if(mode == 0 || mode == JNI_ABORT)\ {\ delete[] elems;\ }\ @@ -1051,36 +1039,46 @@ jint JNICALL JNIEnv::GetJavaVM(JavaVM **vm) } #pragma managed +static jsize GetPrimitiveArrayElementSize(Array* ar) +{ + Type* type = ar->GetType()->GetElementType(); + if(type == __typeof(System::SByte) || type == __typeof(System::Boolean)) + { + return 1; + } + else if(type == __typeof(System::Int16) || type == __typeof(System::Char)) + { + return 2; + } + else if(type == __typeof(System::Int32) || type == __typeof(System::Single)) + { + return 4; + } + else if(type == __typeof(System::Int64) || type == __typeof(System::Double)) + { + return 8; + } + else + { + assert(false); + return 1; + } +} + void* JNICALL JNIEnv::GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) { Array* ar = __try_cast(UnwrapRef(array)); + int len = ar->Length * GetPrimitiveArrayElementSize(ar); GCHandle h = GCHandle::Alloc(ar, GCHandleType::Pinned); try { - int len; - Type* type = ar->GetType()->GetElementType(); - if(type == __typeof(System::SByte) || type == __typeof(System::Boolean)) - { - len = ar->Length; - } - else if(type == __typeof(System::Int16) || type == __typeof(System::Char)) - { - len = ar->Length * 2; - } - else if(type == __typeof(System::Int32) || type == __typeof(System::Single)) - { - len = ar->Length * 4; - } - else if(type == __typeof(System::Int64) || type == __typeof(System::Double)) - { - len = ar->Length * 8; - } - else + char* buf = new char[len]; + if(!buf) { + // TODO throw OutOfMemoryError assert(false); return 0; } - char* buf = new char[len]; memcpy(buf, (void*)h.AddrOfPinnedObject(), len); if(isCopy) { @@ -1096,7 +1094,24 @@ void* JNICALL JNIEnv::GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) void JNICALL JNIEnv::ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) { - delete[] (char*)carray; + if(mode == 0 || mode == JNI_COMMIT) + { + Array* ar = __try_cast(UnwrapRef(array)); + int len = ar->Length * GetPrimitiveArrayElementSize(ar); + GCHandle h = GCHandle::Alloc(ar, GCHandleType::Pinned); + try + { + memcpy((void*)h.AddrOfPinnedObject(), carray, len); + } + __finally + { + h.Free(); + } + } + if(mode == 0 || mode == JNI_ABORT) + { + delete[] (char*)carray; + } } #pragma unmanaged diff --git a/IK.VM.NET/JniInterface.cs b/IK.VM.NET/JniInterface.cs index b926107a..ba693870 100644 --- a/IK.VM.NET/JniInterface.cs +++ b/IK.VM.NET/JniInterface.cs @@ -113,6 +113,7 @@ public sealed class JniHelper public static object FindClass(string javaName) { + // TODO instead of using the bootstrap class loader, we need to use the system (aka application) class loader TypeWrapper wrapper = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(javaName.Replace('/', '.')); wrapper.Finish(); return NativeCode.java.lang.VMClass.getClassFromWrapper(wrapper); @@ -127,6 +128,14 @@ public sealed class JniHelper { return NativeCode.java.lang.VMClass.getClassFromType(type); } + + public static object AllocObject(object clazz) + { + TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(clazz); + wrapper.Finish(); + // TODO if we're instantiating a remapping type, we need to use TypeAsBaseType (except for String) + return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(wrapper.TypeAsTBD); + } } public interface IJniProvider