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

Skip to content

Commit c88b1f6

Browse files
committed
Move ptr construction to ClassObject
1 parent 004232f commit c88b1f6

File tree

3 files changed

+103
-53
lines changed

3 files changed

+103
-53
lines changed

src/runtime/Converter.cs

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -298,36 +298,6 @@ internal static bool ToManagedValue(BorrowedReference value, Type obType,
298298
{
299299
case CLRObject co:
300300
object tmp = co.inst;
301-
if (obType == typeof(IntPtr))
302-
{
303-
switch (tmp)
304-
{
305-
case nint val:
306-
result = new IntPtr(val);
307-
return true;
308-
case Int64 val:
309-
result = new IntPtr(val);
310-
return true;
311-
case Int32 val:
312-
result = new IntPtr(val);
313-
return true;
314-
}
315-
}
316-
if (obType == typeof(UIntPtr))
317-
{
318-
switch (tmp)
319-
{
320-
case nuint val:
321-
result = new UIntPtr(val);
322-
return true;
323-
case UInt64 val:
324-
result = new UIntPtr(val);
325-
return true;
326-
case UInt32 val:
327-
result = new UIntPtr(val);
328-
return true;
329-
}
330-
}
331301
if (obType.IsInstanceOfType(tmp))
332302
{
333303
result = tmp;
@@ -391,7 +361,7 @@ internal static bool ToManagedValue(BorrowedReference value, Type obType,
391361
// conversions (Python string -> managed string).
392362
if (obType == objectType)
393363
{
394-
if (Runtime.IsStringType(value))
364+
if (Runtime.PyString_Check(value))
395365
{
396366
return ToPrimitive(value, stringType, out result, setError);
397367
}

src/runtime/Runtime.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,13 +1281,6 @@ internal static bool PyFloat_Check(BorrowedReference ob)
12811281
//====================================================================
12821282
// Python string API
12831283
//====================================================================
1284-
internal static bool IsStringType(BorrowedReference op)
1285-
{
1286-
BorrowedReference t = PyObject_TYPE(op);
1287-
return (t == PyStringType)
1288-
|| (t == PyUnicodeType);
1289-
}
1290-
12911284
internal static bool PyString_Check(BorrowedReference ob)
12921285
{
12931286
return PyObject_TYPE(ob) == PyStringType;

src/runtime/Types/ClassObject.cs

Lines changed: 102 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,9 @@ static NewReference tp_new_impl(BorrowedReference tp, BorrowedReference args, Bo
7070
// Primitive types do not have constructors, but they look like
7171
// they do from Python. If the ClassObject represents one of the
7272
// convertible primitive types, just convert the arg directly.
73-
if (type.IsPrimitive || type == typeof(string))
73+
if (type.IsPrimitive)
7474
{
75-
if (Runtime.PyTuple_Size(args) != 1)
76-
{
77-
Exceptions.SetError(Exceptions.TypeError, "no constructors match given arguments");
78-
return default;
79-
}
80-
81-
BorrowedReference op = Runtime.PyTuple_GetItem(args, 0);
82-
83-
if (!Converter.ToManaged(op, type, out var result, true))
84-
{
85-
return default;
86-
}
87-
88-
return CLRObject.GetReference(result!, tp);
75+
return NewPrimitive(tp, args, type);
8976
}
9077

9178
if (type.IsAbstract)
@@ -99,6 +86,11 @@ static NewReference tp_new_impl(BorrowedReference tp, BorrowedReference args, Bo
9986
return NewEnum(type, args, tp);
10087
}
10188

89+
if (type == typeof(string))
90+
{
91+
return NewString(args, tp);
92+
}
93+
10294
if (IsGenericNullable(type))
10395
{
10496
// Nullable<T> has special handling in .NET runtime.
@@ -112,6 +104,101 @@ static NewReference tp_new_impl(BorrowedReference tp, BorrowedReference args, Bo
112104
return self.NewObjectToPython(obj, tp);
113105
}
114106

107+
/// <summary>
108+
/// Construct a new .NET String object from Python args
109+
/// </summary>
110+
private static NewReference NewString(BorrowedReference args, BorrowedReference tp)
111+
{
112+
if (Runtime.PyTuple_Size(args) == 1)
113+
{
114+
BorrowedReference ob = Runtime.PyTuple_GetItem(args, 0);
115+
if (Runtime.PyString_Check(ob))
116+
{
117+
if (Runtime.GetManagedString(ob) is string val)
118+
return CLRObject.GetReference(val, tp);
119+
}
120+
121+
// TODO: Initialise using constructors instead
122+
123+
Exceptions.SetError(Exceptions.TypeError, "no constructors match given arguments");
124+
return default;
125+
}
126+
127+
return default;
128+
}
129+
130+
/// <summary>
131+
/// Create a new Python object for a primitive type
132+
///
133+
/// The primitive types are Boolean, Byte, SByte, Int16, UInt16,
134+
/// Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double,
135+
/// and Single.
136+
///
137+
/// All numeric types and Boolean can be handled by a simple
138+
/// conversion, (U)IntPtr has to be handled separately as we
139+
/// do not want to convert them automically to/from integers.
140+
/// </summary>
141+
/// <param name="type">.NET type to construct</param>
142+
/// <param name="tp">Corresponding Python type</param>
143+
/// <param name="args">Constructor arguments</param>
144+
private static NewReference NewPrimitive(BorrowedReference tp, BorrowedReference args, Type type)
145+
{
146+
// TODO: Handle IntPtr
147+
if (Runtime.PyTuple_Size(args) != 1)
148+
{
149+
Exceptions.SetError(Exceptions.TypeError, "no constructors match given arguments");
150+
return default;
151+
}
152+
153+
BorrowedReference op = Runtime.PyTuple_GetItem(args, 0);
154+
object? result = null;
155+
156+
if (type == typeof(IntPtr))
157+
{
158+
if (ManagedType.GetManagedObject(op) is CLRObject clrObject)
159+
{
160+
switch (clrObject.inst)
161+
{
162+
case nint val:
163+
result = new IntPtr(val);
164+
break;
165+
case Int64 val:
166+
result = new IntPtr(val);
167+
break;
168+
case Int32 val:
169+
result = new IntPtr(val);
170+
break;
171+
}
172+
}
173+
}
174+
175+
if (type == typeof(UIntPtr))
176+
{
177+
if (ManagedType.GetManagedObject(op) is CLRObject clrObject)
178+
{
179+
switch (clrObject.inst)
180+
{
181+
case nuint val:
182+
result = new UIntPtr(val);
183+
break;
184+
case UInt64 val:
185+
result = new UIntPtr(val);
186+
break;
187+
case UInt32 val:
188+
result = new UIntPtr(val);
189+
break;
190+
}
191+
}
192+
}
193+
194+
if (result == null && !Converter.ToManaged(op, type, out result, true))
195+
{
196+
return default;
197+
}
198+
199+
return CLRObject.GetReference(result!, tp);
200+
}
201+
115202
protected virtual void SetTypeNewSlot(BorrowedReference pyType, SlotsHolder slotsHolder)
116203
{
117204
TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.tp_new, new Interop.BBB_N(tp_new_impl), slotsHolder);

0 commit comments

Comments
 (0)