diff --git a/src/runtime/typemanager.cs b/src/runtime/typemanager.cs
index 127e82eaa..9a98e9ebb 100644
--- a/src/runtime/typemanager.cs
+++ b/src/runtime/typemanager.cs
@@ -512,12 +512,8 @@ public static NativeCode Active
return I386;
case MachineType.x86_64:
return X86_64;
- case MachineType.armv7l:
- return Armv7l;
- case MachineType.armv8:
- return Armv8;
default:
- throw new NotImplementedException($"No support for {Runtime.MachineName}");
+ return null;
}
}
}
@@ -552,34 +548,6 @@ public static NativeCode Active
///
///
public static readonly NativeCode I386 = X86_64;
-
- public static readonly NativeCode Armv7l = new NativeCode()
- {
- Return0 = 0,
- Return1 = 0x08,
- Code = new byte[]
- {
- 0xe3, 0xa0, 0x00, 0x00, // mov r0, #0
- 0xe1, 0x2f, 0xff, 0x1e, // bx lr
-
- 0xe3, 0xa0, 0x00, 0x01, // mov r0, #1
- 0xe1, 0x2f, 0xff, 0x1e, // bx lr
- }
- };
-
- public static readonly NativeCode Armv8 = new NativeCode()
- {
- Return0 = 0,
- Return1 = 0x08,
- Code = new byte[]
- {
- 0x52, 0x80, 0x00, 0x00, // mov w0, #0x0
- 0xd6, 0x5f, 0x03, 0xc0, // ret
-
- 0x52, 0x80, 0x00, 0x20, // mov w0, #0x1
- 0xd6, 0x5f, 0x03, 0xc0, // ret
- }
- };
}
///
@@ -702,7 +670,7 @@ internal static void InitializeNativeCodePage()
Marshal.Copy(NativeCode.Active.Code, 0, NativeCodePage, codeLength);
mapper.SetReadExec(NativeCodePage, codeLength);
}
-#endregion
+ #endregion
///
/// Given a newly allocated Python type object and a managed Type that
@@ -745,21 +713,40 @@ internal static void InitializeSlots(IntPtr type, Type impl)
impl = impl.BaseType;
}
- // See the TestDomainReload test: there was a crash related to
- // the gc-related slots. They always return 0 or 1 because we don't
- // really support gc:
+ var native = NativeCode.Active;
+
+ // The garbage collection related slots always have to return 1 or 0
+ // since .NET objects don't take part in Python's gc:
// tp_traverse (returns 0)
// tp_clear (returns 0)
// tp_is_gc (returns 1)
- // We can't do without: python really wants those slots to exist.
- // We can't implement those in C# because the application domain
- // can be shut down and the memory released.
- InitializeNativeCodePage();
- InitializeSlot(type, NativeCodePage + NativeCode.Active.Return0, "tp_traverse");
- InitializeSlot(type, NativeCodePage + NativeCode.Active.Return0, "tp_clear");
- InitializeSlot(type, NativeCodePage + NativeCode.Active.Return1, "tp_is_gc");
+ // These have to be defined, though, so by default we fill these with
+ // static C# functions from this class.
+
+ var ret0 = Interop.GetThunk(((Func)Return0).Method);
+ var ret1 = Interop.GetThunk(((Func)Return1).Method);
+
+ if (native != null)
+ {
+ // If we want to support domain reload, the C# implementation
+ // cannot be used as the assembly may get released before
+ // CPython calls these functions. Instead, for amd64 and x86 we
+ // load them into a separate code page that is leaked
+ // intentionally.
+ InitializeNativeCodePage();
+ ret1 = NativeCodePage + native.Return1;
+ ret0 = NativeCodePage + native.Return0;
+ }
+
+ InitializeSlot(type, ret0, "tp_traverse");
+ InitializeSlot(type, ret0, "tp_clear");
+ InitializeSlot(type, ret1, "tp_is_gc");
}
+ static int Return1(IntPtr _) => 1;
+
+ static int Return0(IntPtr _) => 0;
+
///
/// Helper for InitializeSlots.
///