Esempio n. 1
0
        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
        }
Esempio n. 2
0
            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);
            }
Esempio n. 3
0
        public JniTransition(IntPtr environmentPointer)
        {
            disposed         = false;
            pendingException = null;

            JniEnvironment.SetEnvironmentPointer(environmentPointer);
#if FEATURE_JNIENVIRONMENT_SAFEHANDLES
            JniEnvironment.PushLocalReferenceFrame();
#endif  // FEATURE_JNIENVIRONMENT_SAFEHANDLES
        }
Esempio n. 4
0
        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));
        }
Esempio n. 5
0
        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));
        }
Esempio n. 6
0
            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));
                }
            }
Esempio n. 7
0
        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));
            }
Esempio n. 9
0
 internal JniLocalReference()
 {
     JniEnvironment.AddLocalReference(this);
 }
Esempio n. 10
0
 protected override bool ReleaseHandle()
 {
     JniEnvironment.DeleteLocalReference(this, handle);
     return(true);
 }
Esempio n. 11
0
            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
            }
Esempio n. 12
0
            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
            }