Skip to content

Commit 4831b83

Browse files
committed
TypeOffset class no longer depends on target Python version
Instead, for each supported Python version a separate class is generated (e.g. TypeOffset36). Then the Runtime picks the correct class using reflection, and copies only the necessary TypeOffset members over from it. ManagedDataOffsets.Magic is now also read at runtime from tp_basicsize of PyType
1 parent 67c6d11 commit 4831b83

15 files changed

+751
-532
lines changed

pythonnet.15.sln

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "conda.recipe", "conda.recip
4242
conda.recipe\README.md = conda.recipe\README.md
4343
EndProjectSection
4444
EndProject
45+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{BC426F42-8494-4AA5-82C9-5109ACD97BD1}"
46+
ProjectSection(SolutionItems) = preProject
47+
tools\geninterop\geninterop.py = tools\geninterop\geninterop.py
48+
EndProjectSection
49+
EndProject
4550
Global
4651
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4752
Debug|Any CPU = Debug|Any CPU

src/runtime/Python.Runtime.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@
8080
<Compile Include="Codecs\DecoderGroup.cs" />
8181
<Compile Include="Codecs\RawProxyEncoder.cs" />
8282
<Compile Include="Codecs\TupleCodecs.cs" />
83+
<Compile Include="native\ABI.cs" />
84+
<Compile Include="native\GeneratedTypeOffsets.cs" />
85+
<Compile Include="native\ITypeOffsets.cs" />
86+
<Compile Include="native\TypeOffset.cs" />
8387
<Compile Include="converterextensions.cs" />
8488
<Compile Include="finalizer.cs" />
8589
<Compile Include="intern.cs" />

src/runtime/debughelper.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ internal static void DumpType(IntPtr type)
6060
//DebugUtil.Print(" mro: ", op);
6161

6262

63-
FieldInfo[] slots = typeof(TypeOffset).GetFields();
63+
var slots = TypeOffset.GetOffsets();
6464
int size = IntPtr.Size;
6565

66-
for (var i = 0; i < slots.Length; i++)
66+
foreach (var entry in slots)
6767
{
68-
int offset = i * size;
69-
name = slots[i].Name;
68+
int offset = entry.Value;
69+
name = entry.Key;
7070
op = Marshal.ReadIntPtr(type, offset);
7171
Console.WriteLine(" {0}: {1}", name, op);
7272
}

src/runtime/interop.cs

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -70,25 +70,12 @@ public ModulePropertyAttribute()
7070

7171
internal static partial class TypeOffset
7272
{
73-
static TypeOffset()
74-
{
75-
Type type = typeof(TypeOffset);
76-
FieldInfo[] fields = type.GetFields();
77-
int size = IntPtr.Size;
78-
for (int i = 0; i < fields.Length; i++)
79-
{
80-
int offset = i * size;
81-
FieldInfo fi = fields[i];
82-
fi.SetValue(null, offset);
83-
}
84-
}
85-
8673
public static int magic() => ManagedDataOffsets.Magic;
8774
}
8875

8976
internal static class ManagedDataOffsets
9077
{
91-
public static int Magic { get; private set; }
78+
public static int Magic { get; internal set; }
9279
public static readonly Dictionary<string, int> NameMapping = new Dictionary<string, int>();
9380

9481
static class DataOffsets
@@ -108,13 +95,7 @@ static DataOffsets()
10895

10996
static ManagedDataOffsets()
11097
{
111-
Type type = typeof(TypeOffset);
112-
foreach (FieldInfo fi in type.GetFields())
113-
{
114-
NameMapping[fi.Name] = (int)fi.GetValue(null);
115-
}
116-
// XXX: Use the members after PyHeapTypeObject as magic slot
117-
Magic = TypeOffset.members;
98+
NameMapping = TypeOffset.GetOffsets();
11899

119100
FieldInfo[] fields = typeof(DataOffsets).GetFields(BindingFlags.Static | BindingFlags.Public);
120101
size = fields.Length * IntPtr.Size;

src/runtime/interop36.cs

Lines changed: 120 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -2,135 +2,137 @@
22
// Auto-generated by geninterop.py.
33
// DO NOT MODIFY BY HAND.
44

5+
// ReSharper disable InconsistentNaming
6+
// ReSharper disable IdentifierTypo
57

6-
#if PYTHON36
78
using System;
8-
using System.Collections;
9-
using System.Collections.Specialized;
9+
using System.Diagnostics.CodeAnalysis;
1010
using System.Runtime.InteropServices;
11-
using System.Reflection;
12-
using System.Text;
11+
12+
using Python.Runtime.Native;
1313

1414
namespace Python.Runtime
1515
{
16+
[SuppressMessage("Style", "IDE1006:Naming Styles",
17+
Justification = "Following CPython",
18+
Scope = "type")]
1619

1720
[StructLayout(LayoutKind.Sequential)]
18-
internal static partial class TypeOffset
21+
internal class TypeOffset36 : GeneratedTypeOffsets, ITypeOffsets
1922
{
23+
public TypeOffset36() { }
2024
// Auto-generated from PyHeapTypeObject in Python.h
21-
public static int ob_refcnt = 0;
22-
public static int ob_type = 0;
23-
public static int ob_size = 0;
24-
public static int tp_name = 0;
25-
public static int tp_basicsize = 0;
26-
public static int tp_itemsize = 0;
27-
public static int tp_dealloc = 0;
28-
public static int tp_print = 0;
29-
public static int tp_getattr = 0;
30-
public static int tp_setattr = 0;
31-
public static int tp_as_async = 0;
32-
public static int tp_repr = 0;
33-
public static int tp_as_number = 0;
34-
public static int tp_as_sequence = 0;
35-
public static int tp_as_mapping = 0;
36-
public static int tp_hash = 0;
37-
public static int tp_call = 0;
38-
public static int tp_str = 0;
39-
public static int tp_getattro = 0;
40-
public static int tp_setattro = 0;
41-
public static int tp_as_buffer = 0;
42-
public static int tp_flags = 0;
43-
public static int tp_doc = 0;
44-
public static int tp_traverse = 0;
45-
public static int tp_clear = 0;
46-
public static int tp_richcompare = 0;
47-
public static int tp_weaklistoffset = 0;
48-
public static int tp_iter = 0;
49-
public static int tp_iternext = 0;
50-
public static int tp_methods = 0;
51-
public static int tp_members = 0;
52-
public static int tp_getset = 0;
53-
public static int tp_base = 0;
54-
public static int tp_dict = 0;
55-
public static int tp_descr_get = 0;
56-
public static int tp_descr_set = 0;
57-
public static int tp_dictoffset = 0;
58-
public static int tp_init = 0;
59-
public static int tp_alloc = 0;
60-
public static int tp_new = 0;
61-
public static int tp_free = 0;
62-
public static int tp_is_gc = 0;
63-
public static int tp_bases = 0;
64-
public static int tp_mro = 0;
65-
public static int tp_cache = 0;
66-
public static int tp_subclasses = 0;
67-
public static int tp_weaklist = 0;
68-
public static int tp_del = 0;
69-
public static int tp_version_tag = 0;
70-
public static int tp_finalize = 0;
71-
public static int am_await = 0;
72-
public static int am_aiter = 0;
73-
public static int am_anext = 0;
74-
public static int nb_add = 0;
75-
public static int nb_subtract = 0;
76-
public static int nb_multiply = 0;
77-
public static int nb_remainder = 0;
78-
public static int nb_divmod = 0;
79-
public static int nb_power = 0;
80-
public static int nb_negative = 0;
81-
public static int nb_positive = 0;
82-
public static int nb_absolute = 0;
83-
public static int nb_bool = 0;
84-
public static int nb_invert = 0;
85-
public static int nb_lshift = 0;
86-
public static int nb_rshift = 0;
87-
public static int nb_and = 0;
88-
public static int nb_xor = 0;
89-
public static int nb_or = 0;
90-
public static int nb_int = 0;
91-
public static int nb_reserved = 0;
92-
public static int nb_float = 0;
93-
public static int nb_inplace_add = 0;
94-
public static int nb_inplace_subtract = 0;
95-
public static int nb_inplace_multiply = 0;
96-
public static int nb_inplace_remainder = 0;
97-
public static int nb_inplace_power = 0;
98-
public static int nb_inplace_lshift = 0;
99-
public static int nb_inplace_rshift = 0;
100-
public static int nb_inplace_and = 0;
101-
public static int nb_inplace_xor = 0;
102-
public static int nb_inplace_or = 0;
103-
public static int nb_floor_divide = 0;
104-
public static int nb_true_divide = 0;
105-
public static int nb_inplace_floor_divide = 0;
106-
public static int nb_inplace_true_divide = 0;
107-
public static int nb_index = 0;
108-
public static int nb_matrix_multiply = 0;
109-
public static int nb_inplace_matrix_multiply = 0;
110-
public static int mp_length = 0;
111-
public static int mp_subscript = 0;
112-
public static int mp_ass_subscript = 0;
113-
public static int sq_length = 0;
114-
public static int sq_concat = 0;
115-
public static int sq_repeat = 0;
116-
public static int sq_item = 0;
117-
public static int was_sq_slice = 0;
118-
public static int sq_ass_item = 0;
119-
public static int was_sq_ass_slice = 0;
120-
public static int sq_contains = 0;
121-
public static int sq_inplace_concat = 0;
122-
public static int sq_inplace_repeat = 0;
123-
public static int bf_getbuffer = 0;
124-
public static int bf_releasebuffer = 0;
125-
public static int name = 0;
126-
public static int ht_slots = 0;
127-
public static int qualname = 0;
128-
public static int ht_cached_keys = 0;
129-
130-
/* here are optional user slots, followed by the members. */
131-
public static int members = 0;
25+
public int ob_refcnt { get; private set; }
26+
public int ob_type { get; private set; }
27+
public int ob_size { get; private set; }
28+
public int tp_name { get; private set; }
29+
public int tp_basicsize { get; private set; }
30+
public int tp_itemsize { get; private set; }
31+
public int tp_dealloc { get; private set; }
32+
public int tp_print { get; private set; }
33+
public int tp_getattr { get; private set; }
34+
public int tp_setattr { get; private set; }
35+
public int tp_as_async { get; private set; }
36+
public int tp_repr { get; private set; }
37+
public int tp_as_number { get; private set; }
38+
public int tp_as_sequence { get; private set; }
39+
public int tp_as_mapping { get; private set; }
40+
public int tp_hash { get; private set; }
41+
public int tp_call { get; private set; }
42+
public int tp_str { get; private set; }
43+
public int tp_getattro { get; private set; }
44+
public int tp_setattro { get; private set; }
45+
public int tp_as_buffer { get; private set; }
46+
public int tp_flags { get; private set; }
47+
public int tp_doc { get; private set; }
48+
public int tp_traverse { get; private set; }
49+
public int tp_clear { get; private set; }
50+
public int tp_richcompare { get; private set; }
51+
public int tp_weaklistoffset { get; private set; }
52+
public int tp_iter { get; private set; }
53+
public int tp_iternext { get; private set; }
54+
public int tp_methods { get; private set; }
55+
public int tp_members { get; private set; }
56+
public int tp_getset { get; private set; }
57+
public int tp_base { get; private set; }
58+
public int tp_dict { get; private set; }
59+
public int tp_descr_get { get; private set; }
60+
public int tp_descr_set { get; private set; }
61+
public int tp_dictoffset { get; private set; }
62+
public int tp_init { get; private set; }
63+
public int tp_alloc { get; private set; }
64+
public int tp_new { get; private set; }
65+
public int tp_free { get; private set; }
66+
public int tp_is_gc { get; private set; }
67+
public int tp_bases { get; private set; }
68+
public int tp_mro { get; private set; }
69+
public int tp_cache { get; private set; }
70+
public int tp_subclasses { get; private set; }
71+
public int tp_weaklist { get; private set; }
72+
public int tp_del { get; private set; }
73+
public int tp_version_tag { get; private set; }
74+
public int tp_finalize { get; private set; }
75+
public int am_await { get; private set; }
76+
public int am_aiter { get; private set; }
77+
public int am_anext { get; private set; }
78+
public int nb_add { get; private set; }
79+
public int nb_subtract { get; private set; }
80+
public int nb_multiply { get; private set; }
81+
public int nb_remainder { get; private set; }
82+
public int nb_divmod { get; private set; }
83+
public int nb_power { get; private set; }
84+
public int nb_negative { get; private set; }
85+
public int nb_positive { get; private set; }
86+
public int nb_absolute { get; private set; }
87+
public int nb_bool { get; private set; }
88+
public int nb_invert { get; private set; }
89+
public int nb_lshift { get; private set; }
90+
public int nb_rshift { get; private set; }
91+
public int nb_and { get; private set; }
92+
public int nb_xor { get; private set; }
93+
public int nb_or { get; private set; }
94+
public int nb_int { get; private set; }
95+
public int nb_reserved { get; private set; }
96+
public int nb_float { get; private set; }
97+
public int nb_inplace_add { get; private set; }
98+
public int nb_inplace_subtract { get; private set; }
99+
public int nb_inplace_multiply { get; private set; }
100+
public int nb_inplace_remainder { get; private set; }
101+
public int nb_inplace_power { get; private set; }
102+
public int nb_inplace_lshift { get; private set; }
103+
public int nb_inplace_rshift { get; private set; }
104+
public int nb_inplace_and { get; private set; }
105+
public int nb_inplace_xor { get; private set; }
106+
public int nb_inplace_or { get; private set; }
107+
public int nb_floor_divide { get; private set; }
108+
public int nb_true_divide { get; private set; }
109+
public int nb_inplace_floor_divide { get; private set; }
110+
public int nb_inplace_true_divide { get; private set; }
111+
public int nb_index { get; private set; }
112+
public int nb_matrix_multiply { get; private set; }
113+
public int nb_inplace_matrix_multiply { get; private set; }
114+
public int mp_length { get; private set; }
115+
public int mp_subscript { get; private set; }
116+
public int mp_ass_subscript { get; private set; }
117+
public int sq_length { get; private set; }
118+
public int sq_concat { get; private set; }
119+
public int sq_repeat { get; private set; }
120+
public int sq_item { get; private set; }
121+
public int was_sq_slice { get; private set; }
122+
public int sq_ass_item { get; private set; }
123+
public int was_sq_ass_slice { get; private set; }
124+
public int sq_contains { get; private set; }
125+
public int sq_inplace_concat { get; private set; }
126+
public int sq_inplace_repeat { get; private set; }
127+
public int bf_getbuffer { get; private set; }
128+
public int bf_releasebuffer { get; private set; }
129+
public int name { get; private set; }
130+
public int ht_slots { get; private set; }
131+
public int qualname { get; private set; }
132+
public int ht_cached_keys { get; private set; }
132133
}
133134

135+
#if PYTHON36
134136
[StructLayout(LayoutKind.Sequential)]
135137
internal struct PyNumberMethods
136138
{
@@ -221,5 +223,5 @@ internal static partial class SlotTypes
221223
};
222224
}
223225

224-
}
225226
#endif
227+
}

0 commit comments

Comments
 (0)