public override void DestroyGenericArgumentState(Single value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var r = state.ReferenceValue; JniObjectReference.Dispose(ref r); state = new JniValueMarshalerState(); }
ConstructorInfo GetPeerConstructor(JniObjectReference instance, Type fallbackType) { var klass = JniEnvironment.Types.GetObjectClass(instance); var jniTypeName = JniEnvironment.Types.GetJniTypeNameFromClass(klass); Type type = null; while (jniTypeName != null) { type = Runtime.TypeManager.GetType(JniTypeSignature.Parse(jniTypeName)); if (type != null) { var ctor = GetActivationConstructor(type); if (ctor != null) { JniObjectReference.Dispose(ref klass); return(ctor); } } var super = JniEnvironment.Types.GetSuperclass(klass); jniTypeName = super.IsValid ? JniEnvironment.Types.GetJniTypeNameFromClass(super) : null; JniObjectReference.Dispose(ref klass, JniObjectReferenceOptions.CopyAndDispose); klass = super; } JniObjectReference.Dispose(ref klass, JniObjectReferenceOptions.CopyAndDispose); return(GetActivationConstructor(fallbackType)); }
public object CreateValue(ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null) { if (!reference.IsValid) { return(null); } if (targetType != null && typeof(IJavaPeerable).GetTypeInfo().IsAssignableFrom(targetType.GetTypeInfo())) { return(JavaPeerableValueMarshaler.Instance.CreateGenericValue(ref reference, options, targetType)); } var boxed = PeekBoxedObject(reference); if (boxed != null) { JniObjectReference.Dispose(ref reference, options); if (targetType != null) { return(Convert.ChangeType(boxed, targetType)); } return(boxed); } targetType = targetType ?? GetRuntimeType(reference); if (targetType == null) { // Let's hope this is an IJavaPeerable! return(JavaPeerableValueMarshaler.Instance.CreateGenericValue(ref reference, options, targetType)); } var marshaler = GetValueMarshaler(targetType); return(marshaler.CreateValue(ref reference, options, targetType)); }
public object GetValue(ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null) { if (!reference.IsValid) { return(null); } var existing = PeekValue(reference); if (existing != null && (targetType == null || targetType.GetTypeInfo().IsAssignableFrom(existing.GetType().GetTypeInfo()))) { JniObjectReference.Dispose(ref reference, options); return(existing); } if (targetType != null && typeof(IJavaPeerable).GetTypeInfo().IsAssignableFrom(targetType.GetTypeInfo())) { return(JavaPeerableValueMarshaler.Instance.CreateGenericValue(ref reference, options, targetType)); } targetType = targetType ?? GetRuntimeType(reference); if (targetType == null) { // Let's hope this is an IJavaPeerable! return(JavaPeerableValueMarshaler.Instance.CreateGenericValue(ref reference, options, targetType)); } var marshaler = GetValueMarshaler(targetType); return(marshaler.CreateValue(ref reference, options, targetType)); }
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 override object CreateGenericValue(ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) { var jvm = JniEnvironment.Runtime; if (targetType == null || targetType == typeof(object)) { targetType = jvm.ValueManager.GetRuntimeType(reference); } if (targetType != null) { var vm = jvm.ValueManager.GetValueMarshaler(targetType); if (vm != Instance) { return(vm.CreateValue(ref reference, options, targetType)); } } var target = jvm.ValueManager.PeekValue(reference); if (target != null) { JniObjectReference.Dispose(ref reference, options); return(target); } // Punt! Hope it's a java.lang.Object return(jvm.ValueManager.CreatePeer(ref reference, options, targetType)); }
unsafe string _GetJavaStack(JniObjectReference handle) { using (var StringWriter_class = new JniType("java/io/StringWriter")) using (var PrintWriter_class = new JniType("java/io/PrintWriter")) { var StringWriter_init = StringWriter_class.GetConstructor("()V"); var PrintWriter_init = PrintWriter_class.GetConstructor("(Ljava/io/Writer;)V"); var swriter = StringWriter_class.NewObject(StringWriter_init, null); try { var pwriter_args = stackalloc JniArgumentValue [1]; pwriter_args [0] = new JniArgumentValue(swriter); var pwriter = PrintWriter_class.NewObject(PrintWriter_init, pwriter_args); try { var pst = _members.InstanceMethods.GetMethodInfo("printStackTrace.(Ljava/io/PrintWriter;)V"); var pst_args = stackalloc JniArgumentValue [1]; pst_args [0] = new JniArgumentValue(pwriter); JniEnvironment.InstanceMethods.CallVoidMethod(handle, pst, pst_args); var s = JniEnvironment.Object.ToString(swriter); return(JniEnvironment.Strings.ToString(ref s, JniObjectReferenceOptions.CopyAndDispose)); } finally { JniObjectReference.Dispose(ref pwriter, JniObjectReferenceOptions.CopyAndDispose); } } finally { JniObjectReference.Dispose(ref swriter, JniObjectReferenceOptions.CopyAndDispose); } } }
public override void AddPeer(IJavaPeerable value) { if (RegisteredInstances == null) { throw new ObjectDisposedException(nameof(MonoRuntimeValueManager)); } var r = value.PeerReference; if (!r.IsValid) { throw new ObjectDisposedException(value.GetType().FullName); } var o = PeekPeer(value.PeerReference); if (o != null) { return; } if (r.Type != JniObjectReferenceType.Global) { value.SetPeerReference(r.NewGlobalRef()); JniObjectReference.Dispose(ref r, JniObjectReferenceOptions.CopyAndDispose); } int key = value.JniIdentityHashCode; lock (RegisteredInstances) { List <IJavaPeerable> peers; if (!RegisteredInstances.TryGetValue(key, out peers)) { peers = new List <IJavaPeerable> () { value, }; RegisteredInstances.Add(key, peers); return; } for (int i = peers.Count - 1; i >= 0; i--) { var p = peers [i]; if (!JniEnvironment.Types.IsSameObject(p.PeerReference, value.PeerReference)) { continue; } if (Replaceable(p)) { peers [i] = value; } else { WarnNotReplacing(key, value, p); } return; } peers.Add(value); } }
public void Construct(IJavaPeerable peer, ref JniObjectReference reference, JniObjectReferenceOptions options) { if (peer == null) { throw new ArgumentNullException(nameof(peer)); } var newRef = peer.PeerReference; if (newRef.IsValid) { // Activation! See ManagedPeer.RunConstructor peer.SetJniManagedPeerState(peer.JniManagedPeerState | JniManagedPeerStates.Activatable); JniObjectReference.Dispose(ref reference, options); newRef = newRef.NewGlobalRef(); } else if (options == JniObjectReferenceOptions.None) { // `reference` is likely *InvalidJniObjectReference, and can't be touched return; } else if (!reference.IsValid) { throw new ArgumentException("JNI Object Reference is invalid.", nameof(reference)); } else { newRef = reference; if ((options & JniObjectReferenceOptions.Copy) == JniObjectReferenceOptions.Copy) { newRef = reference.NewGlobalRef(); } JniObjectReference.Dispose(ref reference, options); } peer.SetPeerReference(newRef); peer.SetJniIdentityHashCode(JniSystem.IdentityHashCode(newRef)); var o = Runtime.ObjectReferenceManager; if (o.LogGlobalReferenceMessages) { o.WriteGlobalReferenceLine("Created PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}, Java.Type={4}", newRef.ToString(), peer.JniIdentityHashCode.ToString("x"), RuntimeHelpers.GetHashCode(peer).ToString("x"), peer.GetType().FullName, JniEnvironment.Types.GetJniTypeNameFromInstance(newRef)); } if ((options & DoNotRegisterTarget) != DoNotRegisterTarget) { Add(peer); } }
internal static Int64 GetValueFromJni(ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) { Debug.Assert(targetType == null || targetType == typeof(Int64), "Expected targetType==typeof(Int64); was: " + targetType); TypeRef.GetCachedInstanceMethod(ref longValue, "longValue", "()J"); try { return(JniEnvironment.InstanceMethods.CallLongMethod(self, longValue)); } finally { JniObjectReference.Dispose(ref self, transfer); } }
internal static Char GetValueFromJni(ref JniObjectReference self, JniObjectReferenceOptions transfer, Type?targetType) { Debug.Assert(targetType == null || targetType == typeof(Char), "Expected targetType==typeof(Char); was: " + targetType); TypeRef.GetCachedInstanceMethod(ref charValue, "charValue", "()C"); try { return(JniEnvironment.InstanceMethods.CallCharMethod(self, charValue)); } finally { JniObjectReference.Dispose(ref self, transfer); } }
internal static Boolean GetValueFromJni(ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) { Debug.Assert(targetType == null || targetType == typeof(Boolean), "Expected targetType==typeof(Boolean); was: " + targetType); TypeRef.GetCachedInstanceMethod(ref booleanValue, "booleanValue", "()Z"); try { return(JniEnvironment.InstanceMethods.CallBooleanMethod(self, booleanValue)); } finally { JniObjectReference.Dispose(ref self, transfer); } }
internal static Single GetValueFromJni(ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) { Debug.Assert(targetType == null || targetType == typeof(Single), "Expected targetType==typeof(Single); was: " + targetType); TypeRef.GetCachedInstanceMethod(ref floatValue, "floatValue", "()F"); try { return(JniEnvironment.InstanceMethods.CallFloatMethod(self, floatValue)); } finally { JniObjectReference.Dispose(ref self, transfer); } }
internal static void Collect() { var runtime = JavaLangRuntime.GetRuntime(); try { JavaLangRuntime.GC(runtime); } finally { JniObjectReference.Dispose(ref runtime); } }
public static string GetJniTypeNameFromInstance(JniObjectReference instance) { var lref = GetObjectClass(instance); try { return(GetJniTypeNameFromClass(lref)); } finally { JniObjectReference.Dispose(ref lref, JniObjectReferenceOptions.CopyAndDispose); } }
void Initialize(ref JniObjectReference peerReference, JniObjectReferenceOptions transfer) { if (!peerReference.IsValid) { throw new ArgumentException("handle must be valid.", nameof(peerReference)); } try { this.peerReference = peerReference.NewGlobalRef(); } finally { JniObjectReference.Dispose(ref peerReference, transfer); } }
/// <summary> /// Try to garbage collect <paramref name="value"/>. /// </summary> /// <returns> /// <c>true</c>, if <paramref name="value"/> was collected and /// <paramref name="handle"/> is invalid; otherwise <c>false</c>. /// </returns> /// <param name="value"> /// The <see cref="T:Java.Interop.IJavaPeerable"/> instance to collect. /// </param> /// <param name="handle"> /// The <see cref="T:Java.Interop.JniObjectReference"/> of <paramref name="value"/>. /// This value may be updated, and <see cref="P:Java.Interop.IJavaObject.PeerReference"/> /// will be updated with this value. /// </param> internal protected virtual bool TryGC(IJavaPeerable value, ref JniObjectReference handle) { if (!handle.IsValid) { return(true); } var wgref = handle.NewWeakGlobalRef(); JniObjectReference.Dispose(ref handle); JniGC.Collect(); handle = wgref.NewGlobalRef(); JniObjectReference.Dispose(ref wgref); return(!handle.IsValid); }
public override void DestroyGenericArgumentState(object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var vm = state.Extra as JniValueMarshaler; if (vm != null) { vm.DestroyArgumentState(value, ref state, synchronize); return; } var r = state.ReferenceValue; JniObjectReference.Dispose(ref r); state = new JniValueMarshalerState(); }
public void Dispose() { if (!PeerReference.IsValid) { return; } if (registered) { JniEnvironment.Runtime.UnTrack(PeerReference.Handle); } if (methods != null) { UnregisterNativeMethods(); } JniObjectReference.Dispose(ref peerReference); }
public unsafe JavaException(string message, Exception innerException) : base(message, innerException) { const string signature = "(Ljava/lang/String;)V"; var native_message = JniEnvironment.Strings.NewString(message); try { var args = stackalloc JniArgumentValue [1]; args [0] = new JniArgumentValue(native_message); var peer = JniPeerMembers.InstanceMethods.StartCreateInstance(signature, GetType(), args); Construct(ref peer, JniObjectReferenceOptions.CopyAndDispose); JniPeerMembers.InstanceMethods.FinishCreateInstance(signature, this, args); } finally { JniObjectReference.Dispose(ref native_message, JniObjectReferenceOptions.CopyAndDispose); } javaStackTrace = _GetJavaStack(PeerReference); }
protected void SetPeerReference(ref JniObjectReference reference, JniObjectReferenceOptions options) { if (options == JniObjectReferenceOptions.None) { ((IJavaPeerable)this).SetPeerReference(new JniObjectReference()); return; } #if FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES this.reference = reference; #endif // FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES #if FEATURE_JNIOBJECTREFERENCE_INTPTRS this.handle = reference.Handle; this.handle_type = reference.Type; #endif // FEATURE_JNIOBJECTREFERENCE_INTPTRS JniObjectReference.Dispose(ref reference, options); }
public T CreateValue <T> (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null) { if (disposed) { throw new ObjectDisposedException(GetType().Name); } if (!reference.IsValid) { return(default(T)); } if (targetType != null && !typeof(T).GetTypeInfo().IsAssignableFrom(targetType.GetTypeInfo())) { throw new ArgumentException( string.Format("Requested runtime '{0}' value of '{1}' is not compatible with requested compile-time type T of '{2}'.", nameof(targetType), targetType, typeof(T)), nameof(targetType)); } var boxed = PeekBoxedObject(reference); if (boxed != null) { JniObjectReference.Dispose(ref reference, options); return((T)Convert.ChangeType(boxed, targetType ?? typeof(T))); } targetType = targetType ?? typeof(T); if (typeof(IJavaPeerable).GetTypeInfo().IsAssignableFrom(targetType.GetTypeInfo())) { return((T)JavaPeerableValueMarshaler.Instance.CreateGenericValue(ref reference, options, targetType)); } var marshaler = GetValueMarshaler <T> (); return(marshaler.CreateGenericValue(ref reference, options, targetType)); }
public override void FinalizePeer(IJavaPeerable value) { var h = value.PeerReference; var o = Runtime.ObjectReferenceManager; // MUST NOT use SafeHandle.ReferenceType: local refs are tied to a JniEnvironment // and the JniEnvironment's corresponding thread; it's a thread-local value. // Accessing SafeHandle.ReferenceType won't kill anything (so far...), but // instead it always returns JniReferenceType.Invalid. if (!h.IsValid || h.Type == JniObjectReferenceType.Local) { if (o.LogGlobalReferenceMessages) { o.WriteGlobalReferenceLine("Finalizing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}", h.ToString(), value.JniIdentityHashCode.ToString("x"), RuntimeHelpers.GetHashCode(value).ToString("x"), value.GetType().ToString()); } RemovePeer(value); value.SetPeerReference(new JniObjectReference()); value.Finalized(); return; } RemovePeer(value); if (o.LogGlobalReferenceMessages) { o.WriteGlobalReferenceLine("Finalizing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}", h.ToString(), value.JniIdentityHashCode.ToString("x"), RuntimeHelpers.GetHashCode(value).ToString("x"), value.GetType().ToString()); } value.SetPeerReference(new JniObjectReference()); JniObjectReference.Dispose(ref h); value.Finalized(); }
static IntPtr ToString(IntPtr jnienv, IntPtr n_self) { var envp = new JniTransition(jnienv); try { var self = (JavaProxyObject?)JniEnvironment.Runtime.ValueManager.PeekPeer(new JniObjectReference(n_self)); var s = self?.ToString(); var r = JniEnvironment.Strings.NewString(s); try { return(JniEnvironment.References.NewReturnToJniRef(r)); } finally { JniObjectReference.Dispose(ref r); } } catch (Exception e) when(JniEnvironment.Runtime.ExceptionShouldTransitionToJni(e)) { envp.SetPendingException(e); return(IntPtr.Zero); } finally { envp.Dispose(); } }
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 }
public override void AddPeer(IJavaPeerable value) { var r = value.PeerReference; if (!r.IsValid) { throw new ObjectDisposedException(value.GetType().FullName); } var o = PeekPeer(value.PeerReference); if (o != null) { return; } if (r.Type != JniObjectReferenceType.Global) { value.SetPeerReference(r.NewGlobalRef()); JniObjectReference.Dispose(ref r, JniObjectReferenceOptions.CopyAndDispose); } int key = value.JniIdentityHashCode; lock (RegisteredInstances) { List <WeakReference <IJavaPeerable> > peers; if (!RegisteredInstances.TryGetValue(key, out peers)) { peers = new List <WeakReference <IJavaPeerable> > () { new WeakReference <IJavaPeerable>(value, trackResurrection: true), }; RegisteredInstances.Add(key, peers); return; } for (int i = peers.Count - 1; i >= 0; i--) { var wp = peers [i]; IJavaPeerable p; if (!wp.TryGetTarget(out p)) { // Peer was collected peers.RemoveAt(i); continue; } if (!JniEnvironment.Types.IsSameObject(p.PeerReference, value.PeerReference)) { continue; } if (Replaceable(p)) { peers [i] = new WeakReference <IJavaPeerable>(value, trackResurrection: true); } else { WarnNotReplacing(key, value, p); } return; } peers.Add(new WeakReference <IJavaPeerable> (value, trackResurrection: true)); } }