Example #1
0
        static unsafe void InitializeCoreCLRBridge(InitializationOptions *options)
        {
            if (options->xamarin_objc_msgsend != IntPtr.Zero)
            {
                ObjectiveCMarshal.SetMessageSendCallback(ObjectiveCMarshal.MessageSendFunction.MsgSend, options->xamarin_objc_msgsend);
            }

            if (options->xamarin_objc_msgsend_super != IntPtr.Zero)
            {
                ObjectiveCMarshal.SetMessageSendCallback(ObjectiveCMarshal.MessageSendFunction.MsgSendSuper, options->xamarin_objc_msgsend_super);
            }

            if (options->xamarin_objc_msgsend_stret != IntPtr.Zero)
            {
                ObjectiveCMarshal.SetMessageSendCallback(ObjectiveCMarshal.MessageSendFunction.MsgSendStret, options->xamarin_objc_msgsend_stret);
            }

            if (options->xamarin_objc_msgsend_super_stret != IntPtr.Zero)
            {
                ObjectiveCMarshal.SetMessageSendCallback(ObjectiveCMarshal.MessageSendFunction.MsgSendSuperStret, options->xamarin_objc_msgsend_super_stret);
            }

            delegate * unmanaged <void> beginEndCallback            = (delegate * unmanaged <void>)options->reference_tracking_begin_end_callback;
            delegate * unmanaged <IntPtr, int> isReferencedCallback = (delegate * unmanaged <IntPtr, int>)options->reference_tracking_is_referenced_callback;
            delegate * unmanaged <IntPtr, void> trackedObjectEnteredFinalization = (delegate * unmanaged <IntPtr, void>)options->reference_tracking_tracked_object_entered_finalization;
            ObjectiveCMarshal.Initialize(beginEndCallback, isReferencedCallback, trackedObjectEnteredFinalization, UnhandledExceptionPropagationHandler);
        }
Example #2
0
        static unsafe void SetPendingException(MonoObject *exception_obj)
        {
            var exc = (Exception)GetMonoObjectTarget(exception_obj);

            log_coreclr($"Runtime.SetPendingException ({exc})");
            ObjectiveCMarshal.SetMessageSendPendingException(exc);
        }
Example #3
0
        private static void ValidateSetMessageSendPendingExceptionImpl(MessageSendFunction msgSend)
        {
            if (!LibObjC.SupportedOnPlatform(msgSend))
            {
                return;
            }

            IntPtr func = msgSend switch
            {
                MessageSendFunction.MsgSend => (IntPtr)(delegate * unmanaged <IntPtr, IntPtr, IntPtr>) & MsgSend,
                MessageSendFunction.MsgSendFpret => (IntPtr)(delegate * unmanaged <IntPtr, IntPtr, IntPtr>) & MsgSendFpret,
                MessageSendFunction.MsgSendStret => (IntPtr)(delegate * unmanaged <IntPtr *, IntPtr, IntPtr, void>) & MsgSendStret,
                MessageSendFunction.MsgSendSuper => (IntPtr)(delegate * unmanaged <IntPtr, IntPtr, IntPtr>) & MsgSendSuper,
                MessageSendFunction.MsgSendSuperStret => (IntPtr)(delegate * unmanaged <IntPtr *, IntPtr, IntPtr, void>) & MsgSendSuperStret,
                _ => throw new Exception($"Unknown {nameof(MessageSendFunction)}"),
            };

            // Override message send function
            //
            // We are using the overriding mechanism to enable validating in the Libraries test suite.
            // Technically any Objective-C code that is entered via msgSend could call the managed SetMessageSendPendingException()
            // and it would be thrown when returning from the P/Invoke. This approach avoids us having to
            // create a pure Objective-C library for testing this behavior.
            ObjectiveCMarshal.SetMessageSendCallback(msgSend, func);

            // Call message send function through P/Invoke
            IntPtr inst = IntPtr.Zero;
            IntPtr sel  = IntPtr.Zero;

            Exception ex = Assert.Throws <PendingException>(() => LibObjC.CallPInvoke(msgSend, inst, sel));

            Assert.Equal(msgSend.ToString(), ex.Message);
        }
Example #4
0
        static void Validate_ReferenceTrackingAPIs_InvalidArgs()
        {
            Console.WriteLine($"Running {nameof(Validate_ReferenceTrackingAPIs_InvalidArgs)}...");

            delegate * unmanaged <void> beginEndCallback;
            delegate * unmanaged <IntPtr, int> isReferencedCallback;
            delegate * unmanaged <IntPtr, void> trackedObjectEnteredFinalization;
            NativeObjCMarshalTests.GetExports(out beginEndCallback, out isReferencedCallback, out trackedObjectEnteredFinalization);

            Assert.Throws <ArgumentNullException>(
                () =>
            {
                ObjectiveCMarshal.Initialize(null, isReferencedCallback, trackedObjectEnteredFinalization, OnUnhandledExceptionPropagationHandler);
            });
            Assert.Throws <ArgumentNullException>(
                () =>
            {
                ObjectiveCMarshal.Initialize(beginEndCallback, null, trackedObjectEnteredFinalization, OnUnhandledExceptionPropagationHandler);
            });
            Assert.Throws <ArgumentNullException>(
                () =>
            {
                ObjectiveCMarshal.Initialize(beginEndCallback, isReferencedCallback, null, OnUnhandledExceptionPropagationHandler);
            });
            Assert.Throws <ArgumentNullException>(
                () =>
            {
                ObjectiveCMarshal.Initialize(beginEndCallback, isReferencedCallback, trackedObjectEnteredFinalization, null);
            });
            Assert.Throws <ArgumentNullException>(
                () =>
            {
                ObjectiveCMarshal.CreateReferenceTrackingHandle(null, out _);
            });
        }
Example #5
0
        // See  "Toggle-ref support for CoreCLR" in coreclr-bridge.m for more information.
        internal static void RegisterToggleReferenceCoreCLR(NSObject obj, IntPtr handle, bool isCustomType)
        {
            var gchandle = ObjectiveCMarshal.CreateReferenceTrackingHandle(obj, out var info);

            unsafe {
                TrackedObjectInfo *tracked_info;

                fixed(void *ptr = info)
                tracked_info = (TrackedObjectInfo *)ptr;

                tracked_info->Handle      = handle;
                tracked_info->Flags       = obj.FlagsInternal;
                obj.tracked_object_info   = tracked_info;
                obj.tracked_object_handle = gchandle;

                log_coreclr($"RegisterToggleReferenceCoreCLR ({obj.GetType ().FullName}, 0x{handle.ToString ("x")}, {isCustomType}) => Info=0x{((IntPtr) tracked_info).ToString ("x")} Flags={tracked_info->Flags}");
            }

            // Make sure the GCHandle we have is a weak one for custom types.
            if (isCustomType)
            {
                xamarin_switch_gchandle(handle, true);
            }
        }
Example #6
0
 private static IntPtr SetPendingException([CallerMemberName] string callerName = "")
 {
     ObjectiveCMarshal.SetMessageSendPendingException(new PendingException(callerName));
     return(IntPtr.Zero);
 }