Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cbe1dd2

Browse files
committed
refactored conditional ClassBase slot initialization
1 parent e7ab071 commit cbe1dd2

3 files changed

Lines changed: 38 additions & 52 deletions

File tree

src/runtime/classbase.cs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
using System.Runtime.InteropServices;
88
using System.Runtime.Serialization;
99

10+
using Python.Runtime.Slots;
11+
1012
namespace Python.Runtime
1113
{
1214
/// <summary>
@@ -211,7 +213,7 @@ public static NewReference tp_richcompare(BorrowedReference ob, BorrowedReferenc
211213
/// allows natural iteration over objects that either are IEnumerable
212214
/// or themselves support IEnumerator directly.
213215
/// </summary>
214-
public static NewReference tp_iter(BorrowedReference ob)
216+
static NewReference tp_iter_impl(BorrowedReference ob)
215217
{
216218
var co = GetManagedObject(ob) as CLRObject;
217219
if (co == null)
@@ -410,7 +412,7 @@ protected override void OnLoad(BorrowedReference ob, InterDomainContext context)
410412
/// <summary>
411413
/// Implements __getitem__ for reflected classes and value types.
412414
/// </summary>
413-
public static NewReference mp_subscript(BorrowedReference ob, BorrowedReference idx)
415+
static NewReference mp_subscript_impl(BorrowedReference ob, BorrowedReference idx)
414416
{
415417
BorrowedReference tp = Runtime.PyObject_TYPE(ob);
416418
var cls = (ClassBase)GetManagedObject(tp)!;
@@ -440,7 +442,7 @@ public static NewReference mp_subscript(BorrowedReference ob, BorrowedReference
440442
/// <summary>
441443
/// Implements __setitem__ for reflected classes and value types.
442444
/// </summary>
443-
public static int mp_ass_subscript(BorrowedReference ob, BorrowedReference idx, BorrowedReference v)
445+
static int mp_ass_subscript_impl(BorrowedReference ob, BorrowedReference idx, BorrowedReference v)
444446
{
445447
BorrowedReference tp = Runtime.PyObject_TYPE(ob);
446448
var cls = (ClassBase)GetManagedObject(tp)!;
@@ -528,10 +530,32 @@ public virtual void InitializeSlots(BorrowedReference pyType, SlotsHolder slotsH
528530
{
529531
if (!this.type.Valid) return;
530532

531-
if (GetCallImplementations(this.type.Value).Any()
532-
&& !slotsHolder.IsHolding(TypeOffset.tp_call))
533+
if (GetCallImplementations(this.type.Value).Any())
534+
{
535+
TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.tp_call, new Interop.BBB_N(tp_call_impl), slotsHolder);
536+
}
537+
538+
if (indexer is not null)
539+
{
540+
if (indexer.CanGet)
541+
{
542+
TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.mp_subscript, new Interop.BB_N(mp_subscript_impl), slotsHolder);
543+
}
544+
if (indexer.CanSet)
545+
{
546+
TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.mp_ass_subscript, new Interop.BBB_I32(mp_ass_subscript_impl), slotsHolder);
547+
}
548+
}
549+
550+
if (typeof(IEnumerable).IsAssignableFrom(type.Value)
551+
|| typeof(IEnumerator).IsAssignableFrom(type.Value))
552+
{
553+
TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.tp_iter, new Interop.B_N(tp_iter_impl), slotsHolder);
554+
}
555+
556+
if (mp_length_slot.CanAssign(type.Value))
533557
{
534-
TypeManager.InitializeSlot(pyType, TypeOffset.tp_call, new Interop.BBB_N(tp_call_impl), slotsHolder);
558+
TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.mp_length, new Interop.B_P(mp_length_slot.impl), slotsHolder);
535559
}
536560
}
537561

src/runtime/slots/mp_length.cs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,6 @@ namespace Python.Runtime.Slots
99
{
1010
internal static class mp_length_slot
1111
{
12-
private static MethodInfo? _lengthMethod;
13-
public static MethodInfo Method
14-
{
15-
get
16-
{
17-
if (_lengthMethod != null)
18-
{
19-
return _lengthMethod;
20-
}
21-
_lengthMethod = typeof(mp_length_slot).GetMethod(
22-
nameof(mp_length_slot.mp_length),
23-
BindingFlags.Static | BindingFlags.NonPublic);
24-
Debug.Assert(_lengthMethod != null);
25-
return _lengthMethod!;
26-
}
27-
}
28-
2912
public static bool CanAssign(Type clrType)
3013
{
3114
if (typeof(ICollection).IsAssignableFrom(clrType))
@@ -47,7 +30,7 @@ public static bool CanAssign(Type clrType)
4730
/// Implements __len__ for classes that implement ICollection
4831
/// (this includes any IList implementer or Array subclass)
4932
/// </summary>
50-
private static nint mp_length(BorrowedReference ob)
33+
internal static nint impl(BorrowedReference ob)
5134
{
5235
var co = ManagedType.GetManagedObject(ob) as CLRObject;
5336
if (co == null)

src/runtime/typemanager.cs

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ internal static void RestoreRuntimeData(TypeManagerState storage)
9393
Debug.Assert(type == _slotsImpls[type]);
9494
InitializeSlots(entry.Value, _slotsImpls[type], holder);
9595
Runtime.PyType_Modified(entry.Value);
96-
// FIXME: mp_length_slot.CanAssgin(clrType)
9796
}
9897
}
9998

@@ -290,31 +289,7 @@ internal static void InitializeClass(PyType type, ClassBase impl, Type clrType)
290289
SlotsHolder slotsHolder = CreateSlotsHolder(type);
291290
InitializeSlots(type, impl.GetType(), slotsHolder);
292291

293-
if (!slotsHolder.IsHolding(TypeOffset.mp_length) && mp_length_slot.CanAssign(clrType))
294-
{
295-
InitializeSlot(type, TypeOffset.mp_length, mp_length_slot.Method, slotsHolder);
296-
}
297-
298-
if (!typeof(IEnumerable).IsAssignableFrom(clrType) &&
299-
!typeof(IEnumerator).IsAssignableFrom(clrType))
300-
{
301-
// The tp_iter slot should only be set for enumerable types.
302-
Util.WriteIntPtr(type, TypeOffset.tp_iter, IntPtr.Zero);
303-
}
304-
305-
306-
// Only set mp_subscript and mp_ass_subscript for types with indexers
307-
if (!(impl is ArrayObject))
308-
{
309-
if (impl.indexer == null || !impl.indexer.CanGet)
310-
{
311-
Util.WriteIntPtr(type, TypeOffset.mp_subscript, IntPtr.Zero);
312-
}
313-
if (impl.indexer == null || !impl.indexer.CanSet)
314-
{
315-
Util.WriteIntPtr(type, TypeOffset.mp_ass_subscript, IntPtr.Zero);
316-
}
317-
}
292+
impl.InitializeSlots(type, slotsHolder);
318293

319294
OperatorMethod.FixupSlots(type, clrType);
320295
// Leverage followup initialization from the Python runtime. Note
@@ -331,8 +306,6 @@ internal static void InitializeClass(PyType type, ClassBase impl, Type clrType)
331306
using (var mod = Runtime.PyString_FromString(mn))
332307
Runtime.PyDict_SetItem(dict, PyIdentifier.__module__, mod.Borrow());
333308

334-
impl.InitializeSlots(type, slotsHolder);
335-
336309
Runtime.PyType_Modified(type.Reference);
337310

338311
#if DEBUG
@@ -716,6 +689,12 @@ internal static void InitializeSlot(BorrowedReference type, int slotOffset, Dele
716689
InitializeSlot(type, slotOffset, thunk, slotsHolder);
717690
}
718691

692+
internal static void InitializeSlotIfEmpty(BorrowedReference type, int slotOffset, Delegate impl, SlotsHolder slotsHolder)
693+
{
694+
if (slotsHolder.IsHolding(slotOffset)) return;
695+
InitializeSlot(type, slotOffset, impl, slotsHolder);
696+
}
697+
719698
static void InitializeSlot(BorrowedReference type, int slotOffset, ThunkInfo thunk, SlotsHolder slotsHolder)
720699
{
721700
Util.WriteIntPtr(type, slotOffset, thunk.Address);

0 commit comments

Comments
 (0)