Beispiel #1
0
        public void ResetSlots()
        {
            if (_alreadyReset)
            {
                return;
            }
            _alreadyReset = true;
#if DEBUG
            IntPtr tp_name  = Marshal.ReadIntPtr(_type, TypeOffset.tp_name);
            string typeName = Marshal.PtrToStringAnsi(tp_name);
#endif
            foreach (var offset in _slots.Keys)
            {
                IntPtr ptr = GetDefaultSlot(offset);
#if DEBUG
                //DebugUtil.Print($"Set slot<{TypeOffsetHelper.GetSlotNameByOffset(offset)}> to 0x{ptr.ToString("X")} at {typeName}<0x{_type}>");
#endif
                Marshal.WriteIntPtr(_type, offset, ptr);
            }

            foreach (var action in _deallocators)
            {
                action();
            }

            foreach (var pair in _customResetors)
            {
                int offset  = pair.Key;
                var resetor = pair.Value;
                resetor?.Invoke(_type, offset);
            }

            _customResetors.Clear();
            _slots.Clear();
            _keepalive.Clear();
            _deallocators.Clear();

            // Custom reset
            if (Type != Runtime.CLRMetaType)
            {
                var metatype = Runtime.PyObject_TYPE(Type);
                if (ManagedType.TryGetGCHandle(Type, metatype) is { } handle)
                {
                    if (handle.IsAllocated)
                    {
                        handle.Free();
                    }

                    ManagedType.SetGCHandle(Type, metatype, default);
                }
            }
        }