internal static void AssertSelf(IJavaPeerable self) { if (self == null) { throw new ArgumentNullException(nameof(self)); } var peer = self.PeerReference; if (!peer.IsValid) { throw new ObjectDisposedException(self.GetType().FullName); } #if FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES var lref = peer.SafeHandle as JniLocalReference; if (lref != null && !JniEnvironment.IsHandleValid(lref)) { var t = self.GetType().FullName; throw new NotSupportedException( "You've created a " + t + " in one thread and are using it " + "from another thread without calling IJavaPeerable.Register(). " + "Passing JNI local references between threads is not supported; " + "call IJavaObject.RegisterWithVM() if sharing between threads is required."); } #endif // FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES }
void Dispose(JniObjectReference h, IJavaPeerable value) { value.Disposed(); Remove(value); var o = Runtime.ObjectReferenceManager; if (o.LogGlobalReferenceMessages) { o.WriteGlobalReferenceLine("Disposing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3} Java.Type={4}", h.ToString(), value.JniIdentityHashCode.ToString("x"), RuntimeHelpers.GetHashCode(value).ToString("x"), value.GetType().ToString(), JniEnvironment.Types.GetJniTypeNameFromInstance(h)); } #if FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES var lref = value.PeerReference.SafeHandle as JniLocalReference; if (lref != null && !JniEnvironment.IsHandleValid(lref)) { // `lref` was created on another thread, and CANNOT be disposed on this thread. // Just invalidate the reference and move on. lref.SetHandleAsInvalid(); } #endif // FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES JniObjectReference.Dispose(ref h); value.SetPeerReference(new JniObjectReference()); GC.SuppressFinalize(value); }
public JniTransition(IntPtr environmentPointer) { disposed = false; pendingException = null; JniEnvironment.SetEnvironmentPointer(environmentPointer); #if FEATURE_JNIENVIRONMENT_SAFEHANDLES JniEnvironment.PushLocalReferenceFrame(); #endif // FEATURE_JNIENVIRONMENT_SAFEHANDLES }
internal static Exception?GetExceptionForLastThrowable(IntPtr thrown) { if (thrown == IntPtr.Zero) { return(null); } var e = new JniObjectReference(thrown, JniObjectReferenceType.Local); // JniEnvironment.Errors.ExceptionDescribe (); JniEnvironment.Exceptions.ExceptionClear(); JniEnvironment.LogCreateLocalRef(e); return(Runtime.GetExceptionForThrowable(ref e, JniObjectReferenceOptions.CopyAndDispose)); }
internal static Exception?GetExceptionForLastThrowable() { var e = JniEnvironment.Exceptions.ExceptionOccurred(); if (!e.IsValid) { return(null); } // JniEnvironment.Errors.ExceptionDescribe (); JniEnvironment.Exceptions.ExceptionClear(); JniEnvironment.LogCreateLocalRef(e); return(Runtime.GetExceptionForThrowable(ref e, JniObjectReferenceOptions.CopyAndDispose)); }
public static void MonitorExit(JniObjectReference instance) { int r = _MonitorExit(instance); if (r != 0) { var e = JniEnvironment.GetExceptionForLastThrowable(); if (e != null) { ExceptionDispatchInfo.Capture(e).Throw(); } throw new InvalidOperationException(string.Format("Could not exit monitor; JNIEnv::MonitorExit() returned {0}.", r)); } }
public void Dispose() { if (disposed) { return; } disposed = true; if (pendingException != null) { JniEnvironment.Runtime.RaisePendingException(pendingException); pendingException = null; } #if FEATURE_JNIENVIRONMENT_SAFEHANDLES JniEnvironment.PopLocalReferenceFrame(); #endif // FEATURE_JNIENVIRONMENT_SAFEHANDLES }
public static void PushLocalFrame(int capacity) { int r = _PushLocalFrame(capacity); if (r == 0) { return; } var e = JniEnvironment.GetExceptionForLastThrowable(); if (e != null) { ExceptionDispatchInfo.Capture(e).Throw(); } throw new InvalidOperationException(string.Format("Could not push a frame; JNIEnv::PushLocalFrame() returned {0}.", r)); }
internal JniLocalReference() { JniEnvironment.AddLocalReference(this); }
protected override bool ReleaseHandle() { JniEnvironment.DeleteLocalReference(this, handle); return(true); }
public static unsafe JniObjectReference FindClass(string classname) { if (classname == null) { throw new ArgumentNullException("classname"); } if (classname.Length == 0) { throw new ArgumentException("'classname' cannot be a zero-length string.", nameof(classname)); } var info = JniEnvironment.CurrentInfo; #if FEATURE_JNIENVIRONMENT_JI_PINVOKES IntPtr thrown; var c = NativeMethods.java_interop_jnienv_find_class(info.EnvironmentPointer, out thrown, classname); if (thrown == IntPtr.Zero) { var r = new JniObjectReference(c, JniObjectReferenceType.Local); JniEnvironment.LogCreateLocalRef(r); return(r); } NativeMethods.java_interop_jnienv_exception_clear(info.EnvironmentPointer); var e = new JniObjectReference(thrown, JniObjectReferenceType.Local); LogCreateLocalRef(e); var java = info.ToJavaName(classname); var __args = stackalloc JniArgumentValue [1]; __args [0] = new JniArgumentValue(java); IntPtr ignoreThrown; c = NativeMethods.java_interop_jnienv_call_object_method_a(info.EnvironmentPointer, out ignoreThrown, info.Runtime.ClassLoader.Handle, info.Runtime.ClassLoader_LoadClass.ID, (IntPtr)__args); JniObjectReference.Dispose(ref java); if (ignoreThrown == IntPtr.Zero) { JniObjectReference.Dispose(ref e); var r = new JniObjectReference(c, JniObjectReferenceType.Local); JniEnvironment.LogCreateLocalRef(r); return(r); } NativeMethods.java_interop_jnienv_exception_clear(info.EnvironmentPointer); NativeMethods.java_interop_jnienv_delete_local_ref(info.EnvironmentPointer, ignoreThrown); throw info.Runtime.GetExceptionForThrowable(ref e, JniObjectReferenceOptions.CopyAndDispose); #endif // !FEATURE_JNIENVIRONMENT_JI_PINVOKES #if FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES var c = info.Invoker.FindClass(info.EnvironmentPointer, classname); var thrown = info.Invoker.ExceptionOccurred(info.EnvironmentPointer); if (thrown.IsInvalid) { JniEnvironment.LogCreateLocalRef(c); return(new JniObjectReference(c, JniObjectReferenceType.Local)); } info.Invoker.ExceptionClear(info.EnvironmentPointer); LogCreateLocalRef(thrown); var java = info.ToJavaName(classname); var __args = stackalloc JniArgumentValue [1]; __args [0] = new JniArgumentValue(java); c = info.Invoker.CallObjectMethodA(info.EnvironmentPointer, info.Runtime.ClassLoader.SafeHandle, info.Runtime.ClassLoader_LoadClass.ID, __args); JniObjectReference.Dispose(ref java); var ignoreThrown = info.Invoker.ExceptionOccurred(info.EnvironmentPointer); if (ignoreThrown.IsInvalid) { thrown.Dispose(); JniEnvironment.LogCreateLocalRef(c); return(new JniObjectReference(c, JniObjectReferenceType.Local)); } info.Invoker.ExceptionClear(info.EnvironmentPointer); LogCreateLocalRef(ignoreThrown); ignoreThrown.Dispose(); var e = new JniObjectReference(thrown, JniObjectReferenceType.Local); throw info.Runtime.GetExceptionForThrowable(ref e, JniObjectReferenceOptions.CopyAndDispose); #endif // !FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES }
public static unsafe JniObjectReference FindClass(string classname) { if (classname == null) { throw new ArgumentNullException(nameof(classname)); } if (classname.Length == 0) { throw new ArgumentException("'classname' cannot be a zero-length string.", nameof(classname)); } var info = JniEnvironment.CurrentInfo; #if FEATURE_JNIENVIRONMENT_JI_PINVOKES IntPtr thrown; var c = NativeMethods.java_interop_jnienv_find_class(info.EnvironmentPointer, out thrown, classname); if (thrown == IntPtr.Zero) { var r = new JniObjectReference(c, JniObjectReferenceType.Local); JniEnvironment.LogCreateLocalRef(r); return(r); } // If the Java-side exception stack trace is *lost* a'la 89a5a229, // change `false` to `true` and rebuild+re-run. #if false NativeMethods.java_interop_jnienv_exception_describe(info.EnvironmentPointer); #endif NativeMethods.java_interop_jnienv_exception_clear(info.EnvironmentPointer); var findClassThrown = new JniObjectReference(thrown, JniObjectReferenceType.Local); LogCreateLocalRef(findClassThrown); var pendingException = info.Runtime.GetExceptionForThrowable(ref findClassThrown, JniObjectReferenceOptions.CopyAndDispose); if (info.Runtime.ClassLoader_LoadClass != null) { var java = info.ToJavaName(classname); var __args = stackalloc JniArgumentValue [1]; __args [0] = new JniArgumentValue(java); c = NativeMethods.java_interop_jnienv_call_object_method_a(info.EnvironmentPointer, out thrown, info.Runtime.ClassLoader.Handle, info.Runtime.ClassLoader_LoadClass.ID, (IntPtr)__args); JniObjectReference.Dispose(ref java); if (thrown == IntPtr.Zero) { (pendingException as IJavaPeerable)?.Dispose(); var r = new JniObjectReference(c, JniObjectReferenceType.Local); JniEnvironment.LogCreateLocalRef(r); return(r); } NativeMethods.java_interop_jnienv_exception_clear(info.EnvironmentPointer); if (pendingException != null) { NativeMethods.java_interop_jnienv_delete_local_ref(info.EnvironmentPointer, thrown); } else { var loadClassThrown = new JniObjectReference(thrown, JniObjectReferenceType.Local); LogCreateLocalRef(loadClassThrown); pendingException = info.Runtime.GetExceptionForThrowable(ref loadClassThrown, JniObjectReferenceOptions.CopyAndDispose); } } throw pendingException !; #endif // !FEATURE_JNIENVIRONMENT_JI_PINVOKES #if FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES var c = info.Invoker.FindClass(info.EnvironmentPointer, classname); var thrown = info.Invoker.ExceptionOccurred(info.EnvironmentPointer); if (thrown.IsInvalid) { JniEnvironment.LogCreateLocalRef(c); return(new JniObjectReference(c, JniObjectReferenceType.Local)); } info.Invoker.ExceptionClear(info.EnvironmentPointer); var findClassThrown = new JniObjectReference(thrown, JniObjectReferenceType.Local); LogCreateLocalRef(findClassThrown); var pendingException = info.Runtime.GetExceptionForThrowable(ref findClassThrown, JniObjectReferenceOptions.CopyAndDispose); var java = info.ToJavaName(classname); var __args = stackalloc JniArgumentValue [1]; __args [0] = new JniArgumentValue(java); c = info.Invoker.CallObjectMethodA(info.EnvironmentPointer, info.Runtime.ClassLoader.SafeHandle, info.Runtime.ClassLoader_LoadClass.ID, __args); JniObjectReference.Dispose(ref java); thrown = info.Invoker.ExceptionOccurred(info.EnvironmentPointer); if (ignoreThrown.IsInvalid) { (pendingException as IJavaPeerable)?.Dispose(); var r = new JniObjectReference(c, JniObjectReferenceType.Local); JniEnvironment.LogCreateLocalRef(r); return(r); } info.Invoker.ExceptionClear(info.EnvironmentPointer); if (pendingException != null) { thrown.Dispose(); throw pendingException; } var loadClassThrown = new JniObjectReference(thrown, JniObjectReferenceType.Local); LogCreateLocalRef(loadClassThrown); pendingException = info.Runtime.GetExceptionForThrowable(ref loadClassThrown, JniObjectReferenceOptions.CopyAndDispose); throw pendingException !; #endif // !FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES }