예제 #1
0
		internal static void SetObjectArrayElement(JNIEnv* pEnv, jarray array, jsize index, jobject val)
		{
			try
			{
				// we want to support (non-primitive) value types so we can't cast to object[]
				((Array)pEnv->UnwrapRef(array)).SetValue(pEnv->UnwrapRef(val), index);
			}
			catch(IndexOutOfRangeException)
			{
				SetPendingException(pEnv, new java.lang.ArrayIndexOutOfBoundsException());
			}
		}
예제 #2
0
		internal static jobject NewDirectByteBuffer(JNIEnv* pEnv, IntPtr address, jlong capacity)
		{
			try
			{
				if(capacity < 0 || capacity > int.MaxValue)
				{
					SetPendingException(pEnv, new java.lang.IllegalArgumentException("capacity"));
					return IntPtr.Zero;
				}
				return pEnv->MakeLocalRef(JVM.NewDirectByteBuffer(address.ToInt64(), (int)capacity));
			}
			catch(Exception x)
			{
				SetPendingException(pEnv, ikvm.runtime.Util.mapException(x));
				return IntPtr.Zero;
			}
		}
예제 #3
0
		internal static jlong GetDirectBufferCapacity(JNIEnv* pEnv, jobject buf)
		{
			try
			{
				return (jlong)(long)((java.nio.Buffer)pEnv->UnwrapRef(buf)).capacity();
			}
			catch(Exception x)
			{
				SetPendingException(pEnv, ikvm.runtime.Util.mapException(x));
				return 0;
			}
		}
예제 #4
0
		internal static void ReleaseStringCritical(JNIEnv* pEnv, jstring str, jchar* cstring)
		{
			Marshal.FreeHGlobal((IntPtr)(void*)cstring);
		}
예제 #5
0
		internal static void DeleteWeakGlobalRef(JNIEnv* pEnv, jweak obj)
		{
			int i = obj.ToInt32();
			if(i < 0)
			{
				i = -i;
				i -= (1 << 30);
				lock(GlobalRefs.weakRefLock)
				{
					GlobalRefs.weakRefs[i].Free();
				}
			}
			if(i > 0)
			{
				Debug.Assert(false, "local ref passed to DeleteWeakGlobalRef");
			}
		}
예제 #6
0
		internal static void GetStringUTFRegion(JNIEnv* pEnv, IntPtr str, int start, int len, IntPtr buf)
		{
			string s = (string)pEnv->UnwrapRef(str);
			if(s != null)
			{
				if(start < 0 || start > s.Length || s.Length - start < len)
				{
					SetPendingException(pEnv, new java.lang.StringIndexOutOfBoundsException());
					return;
				}
				else
				{
					byte* p = (byte*)(void*)buf;
					for(int i = 0; i < len; i++)
					{
						char ch = s[start + i];
						if((ch != 0) && (ch <= 0x7F))
						{
							*p++ = (byte)ch;
						}
						else if(ch <= 0x7FF)
						{
							*p++ = (byte)((ch >> 6) | 0xC0);
							*p++ = (byte)((ch & 0x3F) | 0x80);
						}
						else
						{
							*p++ = (byte)((ch >> 12) | 0xE0);
							*p++ = (byte)(((ch >> 6) & 0x3F) | 0x80);
							*p++ = (byte)((ch & 0x3F) | 0x80);
						}
					}
					return;
				}
			}
			else
			{
				SetPendingException(pEnv, new java.lang.NullPointerException());
			}
		}
예제 #7
0
		internal static void ReleasePrimitiveArrayCritical(JNIEnv* pEnv, jarray array, void* carray, jint mode)
		{
			Array ar = (Array)pEnv->UnwrapRef(array);
			if(pEnv->criticalArrayHandle1.Target == ar
				&& (void*)pEnv->criticalArrayHandle1.AddrOfPinnedObject() == carray)
			{
				if(mode == 0 || mode == JNI_ABORT)
				{
					pEnv->criticalArrayHandle1.Target = null;
				}
				return;
			}
			if(pEnv->criticalArrayHandle2.Target == ar
				&& (void*)pEnv->criticalArrayHandle2.AddrOfPinnedObject() == carray)
			{
				if(mode == 0 || mode == JNI_ABORT)
				{
					pEnv->criticalArrayHandle2.Target = null;
				}
				return;
			}
			if(mode == 0 || mode == JNI_COMMIT)
			{
				// TODO not 64-bit safe (len can overflow)
				int len = ar.Length * GetPrimitiveArrayElementSize(ar);
				GCHandle h = GCHandle.Alloc(ar, GCHandleType.Pinned);
				try
				{
					byte* pdst = (byte*)(void*)h.AddrOfPinnedObject();
					byte* psrc = (byte*)(void*)carray;
					// TODO isn't there a managed memcpy?
					for(int i = 0; i < len; i++)
					{
						*pdst++ = *psrc++;
					}
				}
				finally
				{
					h.Free();
				}
			}
			if(mode == 0 || mode == JNI_ABORT)
			{
				JniMem.Free((IntPtr)carray);
			}
		}
예제 #8
0
		internal static void ReleaseByteArrayElements(JNIEnv* pEnv, jbyteArray array, jbyte* elems, jint mode)
		{
			if(mode == 0 || mode == JNI_COMMIT)
			{
				byte[] b = (byte[])pEnv->UnwrapRef(array);
				for(int i = 0; i < b.Length; i++)
				{
					b[i] = (byte)elems[i];
				}
			}
			if(mode == 0 || mode == JNI_ABORT)
			{
				JniMem.Free((IntPtr)(void*)elems);
			}
		}
예제 #9
0
		internal static void ReleaseDoubleArrayElements(JNIEnv* pEnv, jdoubleArray array, jdouble* elems, jint mode)
		{
			if(mode == 0 || mode == JNI_COMMIT)
			{
				double[] b = (double[])pEnv->UnwrapRef(array);
				Marshal.Copy((IntPtr)(void*)elems, b, 0, b.Length);
			}
			if(mode == 0 || mode == JNI_ABORT)
			{
				JniMem.Free((IntPtr)(void*)elems);
			}
		}
예제 #10
0
		internal static jfloat* GetFloatArrayElements(JNIEnv* pEnv, jfloatArray array, jboolean* isCopy)
		{
			float[] b = (float[])pEnv->UnwrapRef(array);
			IntPtr buf = JniMem.Alloc(b.Length * 4);
			Marshal.Copy(b, 0, buf, b.Length);
			if(isCopy != null)
			{
				*isCopy = JNI_TRUE;
			}
			return (jfloat*)(void*)buf;
		}
예제 #11
0
		internal static jdouble* GetDoubleArrayElements(JNIEnv* pEnv, jdoubleArray array, jboolean* isCopy)
		{
			double[] b = (double[])pEnv->UnwrapRef(array);
			IntPtr buf = JniMem.Alloc(b.Length * 8);
			Marshal.Copy(b, 0, buf, b.Length);
			if(isCopy != null)
			{
				*isCopy = JNI_TRUE;
			}
			return (jdouble*)(void*)buf;
		}
예제 #12
0
		internal static jchar* GetCharArrayElements(JNIEnv* pEnv, jcharArray array, jboolean* isCopy)
		{
			char[] b = (char[])pEnv->UnwrapRef(array);
			IntPtr buf = JniMem.Alloc(b.Length * 2);
			Marshal.Copy(b, 0, buf, b.Length);
			if(isCopy != null)
			{
				*isCopy = JNI_TRUE;
			}
			return (jchar*)(void*)buf;
		}
예제 #13
0
		internal static jbyte* GetByteArrayElements(JNIEnv* pEnv, jbyteArray array, jboolean* isCopy)
		{
			byte[] b = (byte[])pEnv->UnwrapRef(array);
			jbyte* p = (jbyte*)(void*)JniMem.Alloc(b.Length * 1);
			for(int i = 0; i < b.Length; i++)
			{
				p[i] = (jbyte)b[i];
			}
			if(isCopy != null)
			{
				*isCopy = JNI_TRUE;
			}
			return p;
		}
예제 #14
0
		internal static jdoubleArray NewDoubleArray(JNIEnv* pEnv, jsize len)
		{
			try
			{
				return pEnv->MakeLocalRef(new double[len]);
			}
			catch(Exception x)
			{
				SetPendingException(pEnv, x);
				return IntPtr.Zero;
			}
		}
예제 #15
0
		internal static int GetJavaVM(JNIEnv* pEnv, JavaVM **ppJavaVM)
		{
			*ppJavaVM = JavaVM.pJavaVM;
			return JNI_OK;
		}
예제 #16
0
		internal static void GetBooleanArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
		{
			try
			{
				bool[] b = (bool[])pEnv->UnwrapRef(array);
				sbyte* p = (sbyte*)(void*)buf;
				for(int i = 0; i < len; i++)
				{
					*p++ = b[start + i] ? JNI_TRUE : JNI_FALSE;
				}
			}
			catch(IndexOutOfRangeException)
			{
				SetPendingException(pEnv, new java.lang.ArrayIndexOutOfBoundsException());
			}
		}
예제 #17
0
		internal static void GetStringRegion(JNIEnv* pEnv, IntPtr str, int start, int len, IntPtr buf)
		{
			string s = (string)pEnv->UnwrapRef(str);
			if(s != null)
			{
				if(start < 0 || start > s.Length || s.Length - start < len)
				{
					SetPendingException(pEnv, new java.lang.StringIndexOutOfBoundsException());
					return;
				}
				else
				{
					char* p = (char*)(void*)buf;
					// TODO isn't there a managed memcpy?
					for(int i = 0; i < len; i++)
					{
						*p++ = s[start + i];
					}
					return;
				}
			}
			else
			{
				SetPendingException(pEnv, new java.lang.NullPointerException());
			}
		}
예제 #18
0
		internal static void SetByteArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
		{
			try
			{
				byte[] b = (byte[])pEnv->UnwrapRef(array);
				byte* p = (byte*)(void*)buf;
				for(int i = 0; i < len; i++)
				{
					b[start + i] = *p++;
				}
			}
			catch(IndexOutOfRangeException)
			{
				SetPendingException(pEnv, new java.lang.ArrayIndexOutOfBoundsException());
			}
		}
예제 #19
0
		internal static void* GetPrimitiveArrayCritical(JNIEnv* pEnv, jarray array, jboolean* isCopy)
		{
			Array ar = (Array)pEnv->UnwrapRef(array);
			if(pEnv->criticalArrayHandle1.Target == null)
			{
				pEnv->criticalArrayHandle1.Target = ar;
				if(isCopy != null)
				{
					*isCopy = JNI_FALSE;
				}
				return (void*)pEnv->criticalArrayHandle1.AddrOfPinnedObject();
			}
			if(pEnv->criticalArrayHandle2.Target == null)
			{
				pEnv->criticalArrayHandle2.Target = ar;
				if(isCopy != null)
				{
					*isCopy = JNI_FALSE;
				}
				return (void*)pEnv->criticalArrayHandle2.AddrOfPinnedObject();
			}
			// TODO not 64-bit safe (len can overflow)
			int len = ar.Length * GetPrimitiveArrayElementSize(ar);
			GCHandle h = GCHandle.Alloc(ar, GCHandleType.Pinned);
			try
			{
				IntPtr hglobal = JniMem.Alloc(len);
				byte* pdst = (byte*)(void*)hglobal;
				byte* psrc = (byte*)(void*)h.AddrOfPinnedObject();
				// TODO isn't there a managed memcpy?
				for(int i = 0; i < len; i++)
				{
					*pdst++ = *psrc++;
				}
				if(isCopy != null)
				{
					*isCopy = JNI_TRUE;
				}
				return (void*)hglobal;
			}
			finally
			{
				h.Free();
			}		
		}
예제 #20
0
		internal static void SetDoubleArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
		{
			try
			{
				double[] b = (double[])pEnv->UnwrapRef(array);
				Marshal.Copy(buf, b, start, len);
			}
			catch(ArgumentOutOfRangeException)
			{
				SetPendingException(pEnv, new java.lang.ArrayIndexOutOfBoundsException());
			}
		}
예제 #21
0
		internal static jchar* GetStringCritical(JNIEnv* pEnv, jstring str, jboolean* isCopy)
		{
			string s = (string)pEnv->UnwrapRef(str);
			if(s != null)
			{
				if(isCopy != null)
				{
					*isCopy = JNI_TRUE;
				}
				return (jchar*)(void*)Marshal.StringToHGlobalUni(s);		
			}
			SetPendingException(pEnv, new java.lang.NullPointerException());
			return null;
		}
예제 #22
0
		internal static int RegisterNatives(JNIEnv* pEnv, IntPtr clazz, JNINativeMethod* methods, int nMethods)
		{
			try
			{
				TypeWrapper wrapper = TypeWrapper.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz));
				wrapper.Finish();
				for(int i = 0; i < nMethods; i++)
				{
					string methodName = StringFromUTF8(methods[i].name);
					string methodSig = StringFromUTF8(methods[i].signature);
					Tracer.Info(Tracer.Jni, "Registering native method: {0}.{1}{2}, fnPtr = 0x{3:X}", wrapper.Name, methodName, methodSig, ((IntPtr)methods[i].fnPtr).ToInt64());
					FieldInfo fi = null;
					// don't allow dotted names!
					if(methodSig.IndexOf('.') < 0)
					{
						// TODO this won't work when we're putting the JNI methods in jniproxy.dll
						fi = wrapper.TypeAsTBD.GetField(JNI.METHOD_PTR_FIELD_PREFIX + methodName + methodSig, BindingFlags.Static | BindingFlags.NonPublic);
					}
					if(fi == null)
					{
						Tracer.Error(Tracer.Jni, "Failed to register native method: {0}.{1}{2}", wrapper.Name, methodName, methodSig);
						SetPendingException(pEnv, new java.lang.NoSuchMethodError(methodName));
						return JNI_ERR;
					}
					fi.SetValue(null, (IntPtr)methods[i].fnPtr);
				}
				return JNI_OK;
			}
			catch(RetargetableJavaException x)
			{
				SetPendingException(pEnv, x.ToJava());
				return JNI_ERR;
			}
			catch(Exception x)
			{
				SetPendingException(pEnv, x);
				return JNI_ERR;
			}
		}
예제 #23
0
		internal static jweak NewWeakGlobalRef(JNIEnv* pEnv, jobject obj)
		{
			object o = pEnv->UnwrapRef(obj);
			if(o == null)
			{
				return IntPtr.Zero;
			}
			lock(GlobalRefs.weakRefLock)
			{
				for(int i = 0; i < GlobalRefs.weakRefs.Length; i++)
				{
					if(!GlobalRefs.weakRefs[i].IsAllocated)
					{
						GlobalRefs.weakRefs[i] = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection);
						return (IntPtr)(- (i | (1 << 30)));
					}
				}
				int len = GlobalRefs.weakRefs.Length;
				GCHandle[] tmp = new GCHandle[len * 2];
				Array.Copy(GlobalRefs.weakRefs, 0, tmp, 0, len);
				tmp[len] = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection);
				GlobalRefs.weakRefs = tmp;
				return (IntPtr)(- (len | (1 << 30)));
			}
		}
예제 #24
0
		internal static int UnregisterNatives(JNIEnv* pEnv, IntPtr clazz)
		{
			try
			{
				TypeWrapper wrapper = TypeWrapper.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz));
				wrapper.Finish();
				// TODO this won't work when we're putting the JNI methods in jniproxy.dll
				foreach(FieldInfo fi in wrapper.TypeAsTBD.GetFields(BindingFlags.Static | BindingFlags.NonPublic))
				{
					string name = fi.Name;
					if(name.StartsWith(JNI.METHOD_PTR_FIELD_PREFIX))
					{
						Tracer.Info(Tracer.Jni, "Unregistering native method: {0}.{1}", wrapper.Name, name.Substring(JNI.METHOD_PTR_FIELD_PREFIX.Length));
						fi.SetValue(null, IntPtr.Zero);
					}
				}
				return JNI_OK;
			}
			catch(RetargetableJavaException x)
			{
				SetPendingException(pEnv, x.ToJava());
				return JNI_ERR;
			}
			catch(Exception x)
			{
				SetPendingException(pEnv, x);
				return JNI_ERR;
			}
		}
예제 #25
0
		internal static jboolean ExceptionCheck(JNIEnv* pEnv)
		{
			ManagedJNIEnv env = pEnv->GetManagedJNIEnv();
			return env.pendingException != null ? JNI_TRUE : JNI_FALSE;
		}
예제 #26
0
		internal static int MonitorEnter(JNIEnv* pEnv, IntPtr obj)
		{
			try
			{
				// on .NET 4.0 Monitor.Enter has been marked obsolete,
				// but in this case the alternative adds no value
#pragma warning disable 618
				System.Threading.Monitor.Enter(pEnv->UnwrapRef(obj));
#pragma warning restore 618
				return JNI_OK;
			}
			catch(Exception x)
			{
				SetPendingException(pEnv, x);
				return JNI_ERR;
			}
		}
예제 #27
0
		internal static IntPtr GetDirectBufferAddress(JNIEnv* pEnv, jobject buf)
		{
			try
			{
				return (IntPtr)((sun.nio.ch.DirectBuffer)pEnv->UnwrapRef(buf)).address();
			}
			catch(Exception x)
			{
				SetPendingException(pEnv, ikvm.runtime.Util.mapException(x));
				return IntPtr.Zero;
			}
		}
예제 #28
0
		internal static int MonitorExit(JNIEnv* pEnv, IntPtr obj)
		{
			try
			{
				System.Threading.Monitor.Exit(pEnv->UnwrapRef(obj));
				return JNI_OK;
			}
			catch(Exception x)
			{
				SetPendingException(pEnv, x);
				return JNI_ERR;
			}
		}
예제 #29
0
		internal static int GetObjectRefType(JNIEnv* pEnv, jobject obj)
		{
			int i = obj.ToInt32();
			if(i >= 0)
			{
				return JNILocalRefType;
			}
			i = -i;
			if((i & (1 << 30)) != 0)
			{
				return JNIWeakGlobalRefType;
			}
			else
			{
				return JNIGlobalRefType;
			}
		}
예제 #30
0
		internal static jobject GetObjectArrayElement(JNIEnv* pEnv, jarray array, jsize index)
		{
			try
			{
				// we want to support (non-primitive) value types so we can't cast to object[]
				return pEnv->MakeLocalRef(((Array)pEnv->UnwrapRef(array)).GetValue(index));
			}
			catch(IndexOutOfRangeException)
			{
				SetPendingException(pEnv, new java.lang.ArrayIndexOutOfBoundsException());
				return IntPtr.Zero;
			}
		}