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

Skip to content

Commit 14949fb

Browse files
committed
fixed thunk loading for slots, that use new reference types
1 parent 6fa2004 commit 14949fb

File tree

4 files changed

+88
-164
lines changed

4 files changed

+88
-164
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
4+
5+
namespace Python.Runtime.Reflection;
6+
7+
[Serializable]
8+
struct ParameterHelper : IEquatable<ParameterInfo>
9+
{
10+
public readonly string TypeName;
11+
public readonly ParameterModifier Modifier;
12+
13+
public ParameterHelper(ParameterInfo tp)
14+
{
15+
TypeName = tp.ParameterType.AssemblyQualifiedName;
16+
Modifier = ParameterModifier.None;
17+
18+
if (tp.IsIn && tp.ParameterType.IsByRef)
19+
{
20+
Modifier = ParameterModifier.In;
21+
}
22+
else if (tp.IsOut && tp.ParameterType.IsByRef)
23+
{
24+
Modifier = ParameterModifier.Out;
25+
}
26+
else if (tp.ParameterType.IsByRef)
27+
{
28+
Modifier = ParameterModifier.Ref;
29+
}
30+
}
31+
32+
public bool Equals(ParameterInfo other)
33+
{
34+
return this.Equals(new ParameterHelper(other));
35+
}
36+
37+
public bool Matches(ParameterInfo other) => this.Equals(other);
38+
}
39+
40+
enum ParameterModifier
41+
{
42+
None,
43+
In,
44+
Out,
45+
Ref
46+
}

src/runtime/StateSerialization/MaybeMethodBase.cs

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using System.Runtime.Serialization;
44
using System.Linq;
55

6+
using Python.Runtime.Reflection;
7+
68
namespace Python.Runtime
79
{
810
[Serializable]
@@ -17,43 +19,6 @@ internal struct MaybeMethodBase<T> : ISerializable where T: MethodBase
1719
const string SerializationIsCtor = "c";
1820
const string SerializationMethodName = "n";
1921

20-
[Serializable]
21-
struct ParameterHelper : IEquatable<ParameterInfo>
22-
{
23-
public enum TypeModifier
24-
{
25-
None,
26-
In,
27-
Out,
28-
Ref
29-
}
30-
public readonly string Name;
31-
public readonly TypeModifier Modifier;
32-
33-
public ParameterHelper(ParameterInfo tp)
34-
{
35-
Name = tp.ParameterType.AssemblyQualifiedName;
36-
Modifier = TypeModifier.None;
37-
38-
if (tp.IsIn && tp.ParameterType.IsByRef)
39-
{
40-
Modifier = TypeModifier.In;
41-
}
42-
else if (tp.IsOut && tp.ParameterType.IsByRef)
43-
{
44-
Modifier = TypeModifier.Out;
45-
}
46-
else if (tp.ParameterType.IsByRef)
47-
{
48-
Modifier = TypeModifier.Ref;
49-
}
50-
}
51-
52-
public bool Equals(ParameterInfo other)
53-
{
54-
return this.Equals(new ParameterHelper(other));
55-
}
56-
}
5722
public static implicit operator MaybeMethodBase<T> (T ob) => new MaybeMethodBase<T>(ob);
5823

5924
string name;
@@ -119,7 +84,7 @@ internal MaybeMethodBase(SerializationInfo serializationInfo, StreamingContext c
11984
bool hasRefType = false;
12085
for (int i = 0; i < param.Length; i++)
12186
{
122-
var paramTypeName = param[i].Name;
87+
var paramTypeName = param[i].TypeName;
12388
types[i] = Type.GetType(paramTypeName);
12489
if (types[i] == null)
12590
{

src/runtime/interop.cs

Lines changed: 38 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
using System;
2-
using System.Collections;
32
using System.Collections.Generic;
43
using System.Diagnostics;
4+
using System.Linq;
55
using System.Runtime.InteropServices;
6+
using Python.Runtime.Reflection;
67
using System.Reflection;
7-
using System.Text;
88

99
namespace Python.Runtime
1010
{
@@ -120,110 +120,38 @@ public enum TypeFlags: int
120120

121121
internal class Interop
122122
{
123-
private static Hashtable pmap;
123+
static readonly Dictionary<MethodInfo, Type> delegateTypes = new();
124124

125-
static Interop()
125+
internal static Type GetPrototype(MethodInfo method)
126126
{
127-
// Here we build a mapping of PyTypeObject slot names to the
128-
// appropriate prototype (delegate) type to use for the slot.
127+
if (delegateTypes.TryGetValue(method, out var delegateType))
128+
return delegateType;
129129

130-
Type[] items = typeof(Interop).GetNestedTypes();
131-
Hashtable p = new Hashtable();
130+
var parameters = method.GetParameters().Select(p => new ParameterHelper(p)).ToArray();
132131

133-
for (int i = 0; i < items.Length; i++)
132+
foreach (var candidate in typeof(Interop).GetNestedTypes())
134133
{
135-
Type item = items[i];
136-
p[item.Name] = item;
137-
}
134+
if (!typeof(Delegate).IsAssignableFrom(candidate))
135+
continue;
138136

139-
pmap = new Hashtable();
140-
141-
pmap["tp_dealloc"] = p["DestructorFunc"];
142-
pmap["tp_print"] = p["PrintFunc"];
143-
pmap["tp_getattr"] = p["BinaryFunc"];
144-
pmap["tp_setattr"] = p["ObjObjArgFunc"];
145-
pmap["tp_compare"] = p["ObjObjFunc"];
146-
pmap["tp_repr"] = p["UnaryFunc"];
147-
pmap["tp_hash"] = p["UnaryFunc"];
148-
pmap["tp_call"] = p["TernaryFunc"];
149-
pmap["tp_str"] = p["UnaryFunc"];
150-
pmap["tp_getattro"] = p["BinaryFunc"];
151-
pmap["tp_setattro"] = p["ObjObjArgFunc"];
152-
pmap["tp_traverse"] = p["ObjObjArgFunc"];
153-
pmap["tp_clear"] = p["InquiryFunc"];
154-
pmap["tp_richcompare"] = p["RichCmpFunc"];
155-
pmap["tp_iter"] = p["UnaryFunc"];
156-
pmap["tp_iternext"] = p["UnaryFunc"];
157-
pmap["tp_descr_get"] = p["TernaryFunc"];
158-
pmap["tp_descr_set"] = p["ObjObjArgFunc"];
159-
pmap["tp_init"] = p["ObjObjArgFunc"];
160-
pmap["tp_alloc"] = p["IntArgFunc"];
161-
pmap["tp_new"] = p["TernaryFunc"];
162-
pmap["tp_free"] = p["DestructorFunc"];
163-
pmap["tp_is_gc"] = p["InquiryFunc"];
164-
165-
pmap["nb_add"] = p["BinaryFunc"];
166-
pmap["nb_subtract"] = p["BinaryFunc"];
167-
pmap["nb_multiply"] = p["BinaryFunc"];
168-
pmap["nb_remainder"] = p["BinaryFunc"];
169-
pmap["nb_divmod"] = p["BinaryFunc"];
170-
pmap["nb_power"] = p["TernaryFunc"];
171-
pmap["nb_negative"] = p["UnaryFunc"];
172-
pmap["nb_positive"] = p["UnaryFunc"];
173-
pmap["nb_absolute"] = p["UnaryFunc"];
174-
pmap["nb_nonzero"] = p["InquiryFunc"];
175-
pmap["nb_invert"] = p["UnaryFunc"];
176-
pmap["nb_lshift"] = p["BinaryFunc"];
177-
pmap["nb_rshift"] = p["BinaryFunc"];
178-
pmap["nb_and"] = p["BinaryFunc"];
179-
pmap["nb_xor"] = p["BinaryFunc"];
180-
pmap["nb_or"] = p["BinaryFunc"];
181-
pmap["nb_coerce"] = p["ObjObjFunc"];
182-
pmap["nb_int"] = p["UnaryFunc"];
183-
pmap["nb_long"] = p["UnaryFunc"];
184-
pmap["nb_float"] = p["UnaryFunc"];
185-
pmap["nb_oct"] = p["UnaryFunc"];
186-
pmap["nb_hex"] = p["UnaryFunc"];
187-
pmap["nb_inplace_add"] = p["BinaryFunc"];
188-
pmap["nb_inplace_subtract"] = p["BinaryFunc"];
189-
pmap["nb_inplace_multiply"] = p["BinaryFunc"];
190-
pmap["nb_inplace_remainder"] = p["BinaryFunc"];
191-
pmap["nb_inplace_power"] = p["TernaryFunc"];
192-
pmap["nb_inplace_lshift"] = p["BinaryFunc"];
193-
pmap["nb_inplace_rshift"] = p["BinaryFunc"];
194-
pmap["nb_inplace_and"] = p["BinaryFunc"];
195-
pmap["nb_inplace_xor"] = p["BinaryFunc"];
196-
pmap["nb_inplace_or"] = p["BinaryFunc"];
197-
pmap["nb_floor_divide"] = p["BinaryFunc"];
198-
pmap["nb_true_divide"] = p["BinaryFunc"];
199-
pmap["nb_inplace_floor_divide"] = p["BinaryFunc"];
200-
pmap["nb_inplace_true_divide"] = p["BinaryFunc"];
201-
pmap["nb_index"] = p["UnaryFunc"];
202-
203-
pmap["sq_length"] = p["InquiryFunc"];
204-
pmap["sq_concat"] = p["BinaryFunc"];
205-
pmap["sq_repeat"] = p["IntArgFunc"];
206-
pmap["sq_item"] = p["IntArgFunc"];
207-
pmap["sq_slice"] = p["IntIntArgFunc"];
208-
pmap["sq_ass_item"] = p["IntObjArgFunc"];
209-
pmap["sq_ass_slice"] = p["IntIntObjArgFunc"];
210-
pmap["sq_contains"] = p["ObjObjFunc"];
211-
pmap["sq_inplace_concat"] = p["BinaryFunc"];
212-
pmap["sq_inplace_repeat"] = p["IntArgFunc"];
213-
214-
pmap["mp_length"] = p["InquiryFunc"];
215-
pmap["mp_subscript"] = p["BinaryFunc"];
216-
pmap["mp_ass_subscript"] = p["ObjObjArgFunc"];
217-
218-
pmap["bf_getreadbuffer"] = p["IntObjArgFunc"];
219-
pmap["bf_getwritebuffer"] = p["IntObjArgFunc"];
220-
pmap["bf_getsegcount"] = p["ObjObjFunc"];
221-
pmap["bf_getcharbuffer"] = p["IntObjArgFunc"];
222-
}
137+
MethodInfo invoke = candidate.GetMethod("Invoke");
138+
var candiateParameters = invoke.GetParameters();
139+
if (candiateParameters.Length != parameters.Length)
140+
continue;
223141

224-
internal static Type GetPrototype(string name)
225-
{
226-
return pmap[name] as Type;
142+
var parametersMatch = parameters.Zip(candiateParameters,
143+
(expected, actual) => expected.Matches(actual))
144+
.All(matches => matches);
145+
146+
if (!parametersMatch) continue;
147+
148+
if (invoke.ReturnType != method.ReturnType) continue;
149+
150+
delegateTypes.Add(method, candidate);
151+
return candidate;
152+
}
153+
154+
throw new NotImplementedException(method.ToString());
227155
}
228156

229157

@@ -235,7 +163,7 @@ internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null)
235163
if (funcType != null)
236164
dt = typeof(Interop).GetNestedType(funcType) as Type;
237165
else
238-
dt = GetPrototype(method.Name);
166+
dt = GetPrototype(method);
239167

240168
if (dt == null)
241169
{
@@ -252,53 +180,38 @@ internal static ThunkInfo GetThunk(Delegate @delegate)
252180
return info;
253181
}
254182

255-
256-
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
257-
public delegate IntPtr UnaryFunc(IntPtr ob);
258-
259183
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
260-
public delegate IntPtr BinaryFunc(IntPtr ob, IntPtr arg);
184+
public delegate NewReference B_N(BorrowedReference ob);
261185

262186
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
263-
public delegate IntPtr TernaryFunc(IntPtr ob, IntPtr a1, IntPtr a2);
187+
public delegate NewReference BB_N(BorrowedReference ob, BorrowedReference a);
264188

265189
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
266190
public delegate NewReference BBB_N(BorrowedReference ob, BorrowedReference a1, BorrowedReference a2);
267-
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
268-
public delegate int BBB_I32(BorrowedReference ob, BorrowedReference a1, BorrowedReference a2);
269-
270-
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
271-
public delegate int InquiryFunc(IntPtr ob);
272-
273-
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
274-
public delegate IntPtr IntArgFunc(IntPtr ob, int arg);
275191

276192
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
277-
public delegate IntPtr IntIntArgFunc(IntPtr ob, int a1, int a2);
193+
public delegate int B_I32(BorrowedReference ob);
278194

279195
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
280-
public delegate int IntObjArgFunc(IntPtr ob, int a1, IntPtr a2);
281-
282-
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
283-
public delegate int IntIntObjArgFunc(IntPtr o, int a, int b, IntPtr c);
196+
public delegate int BBB_I32(BorrowedReference ob, BorrowedReference a1, BorrowedReference a2);
284197

285198
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
286-
public delegate int ObjObjArgFunc(IntPtr o, IntPtr a, IntPtr b);
199+
public delegate int BP_I32(BorrowedReference ob, IntPtr arg);
287200

288201
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
289-
public delegate int ObjObjFunc(IntPtr ob, IntPtr arg);
202+
public delegate IntPtr B_P(BorrowedReference ob);
290203

291204
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
292-
public delegate int BP_I32(BorrowedReference ob, IntPtr arg);
205+
public delegate NewReference BBI32_N(BorrowedReference ob, BorrowedReference a1, int a2);
293206

294207
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
295-
public delegate void DestructorFunc(IntPtr ob);
208+
public delegate NewReference BP_N(BorrowedReference ob, IntPtr arg);
296209

297210
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
298-
public delegate int PrintFunc(IntPtr ob, IntPtr a, int b);
211+
public delegate void N_V(NewReference ob);
299212

300213
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
301-
public delegate IntPtr RichCmpFunc(IntPtr ob, IntPtr a, int b);
214+
public delegate int BPP_I32(BorrowedReference ob, IntPtr a1, IntPtr a2);
302215
}
303216

304217

src/runtime/metatype.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ public static NewReference tp_new(BorrowedReference tp, BorrowedReference args,
178178
}
179179

180180

181-
public static NewReference tp_alloc(BorrowedReference mt, int n)
181+
public static NewReference tp_alloc(BorrowedReference mt, nint n)
182182
=> Runtime.PyType_GenericAlloc(mt, n);
183183

184184

0 commit comments

Comments
 (0)