Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/core/IronPython.Modules/ModuleOps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ public static uint GetUnsignedInt(object value, object type) {

public static long GetSignedLong(object value, object type) {
if (TryToIntStrict(value, out BigInteger bi)) {
return unchecked((long)(ulong)(bi & uint.MaxValue));
return unchecked((long)(ulong)(bi & (TypecodeOps.IsCLong32Bit ? uint.MaxValue : ulong.MaxValue)));
}

if (PythonOps.TryGetBoundAttr(value, "_as_parameter_", out object asParam)) {
Expand All @@ -388,7 +388,7 @@ public static long GetSignedLong(object value, object type) {

public static ulong GetUnsignedLong(object value, object type) {
if (TryToIntStrict(value, out BigInteger bi)) {
return (ulong)(bi & uint.MaxValue);
return (ulong)(bi & (TypecodeOps.IsCLong32Bit ? uint.MaxValue : ulong.MaxValue));
}

if (PythonOps.TryGetBoundAttr(value, "_as_parameter_", out object asParam)) {
Expand Down
39 changes: 29 additions & 10 deletions src/core/IronPython.Modules/_ctypes/SimpleType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,11 @@ int INativeType.Size {
return 2;
case SimpleTypeKind.SignedInt:
case SimpleTypeKind.UnsignedInt:
case SimpleTypeKind.SignedLong:
case SimpleTypeKind.UnsignedLong:
case SimpleTypeKind.Single:
return 4;
case SimpleTypeKind.SignedLong:
case SimpleTypeKind.UnsignedLong:
return TypecodeOps.IsCLong32Bit ? 4 : 8;
case SimpleTypeKind.UnsignedLongLong:
case SimpleTypeKind.SignedLongLong:
case SimpleTypeKind.Double:
Expand Down Expand Up @@ -220,8 +221,8 @@ object INativeType.GetValue(MemoryHolder/*!*/ owner, object readingFrom, int off
case SimpleTypeKind.UnsignedShort: res = GetIntReturn((ushort)owner.ReadInt16(offset, _swap)); break;
case SimpleTypeKind.SignedInt: res = GetIntReturn(owner.ReadInt32(offset, _swap)); break;
case SimpleTypeKind.UnsignedInt: res = GetIntReturn((uint)owner.ReadInt32(offset, _swap)); break;
case SimpleTypeKind.SignedLong: res = GetIntReturn(owner.ReadInt32(offset, _swap)); break;
case SimpleTypeKind.UnsignedLong: res = GetIntReturn((uint)owner.ReadInt32(offset, _swap)); break;
case SimpleTypeKind.SignedLong: if (TypecodeOps.IsCLong32Bit) goto case SimpleTypeKind.SignedInt; else goto case SimpleTypeKind.SignedLongLong;
case SimpleTypeKind.UnsignedLong: if (TypecodeOps.IsCLong32Bit) goto case SimpleTypeKind.UnsignedInt; else goto case SimpleTypeKind.UnsignedLongLong;
case SimpleTypeKind.SignedLongLong: res = GetIntReturn(owner.ReadInt64(offset, _swap)); break;
case SimpleTypeKind.UnsignedLongLong: res = GetIntReturn((ulong)owner.ReadInt64(offset, _swap)); break;
case SimpleTypeKind.Single: res = GetSingleReturn(owner.ReadInt32(offset, _swap)); break;
Expand Down Expand Up @@ -259,8 +260,20 @@ object INativeType.SetValue(MemoryHolder/*!*/ owner, int offset, object value) {
case SimpleTypeKind.UnsignedShort: owner.WriteInt16(offset, unchecked((short)ModuleOps.GetUnsignedShort(value, this)), _swap); break;
case SimpleTypeKind.SignedInt: owner.WriteInt32(offset, ModuleOps.GetSignedInt(value, this), _swap); break;
case SimpleTypeKind.UnsignedInt: owner.WriteInt32(offset, unchecked((int)ModuleOps.GetUnsignedInt(value, this)), _swap); break;
case SimpleTypeKind.SignedLong: owner.WriteInt32(offset, unchecked((int)ModuleOps.GetSignedLong(value, this)), _swap); break;
case SimpleTypeKind.UnsignedLong: owner.WriteInt32(offset, unchecked((int)ModuleOps.GetUnsignedLong(value, this)), _swap); break;
case SimpleTypeKind.SignedLong:
if (TypecodeOps.IsCLong32Bit) {
owner.WriteInt32(offset, unchecked((int)ModuleOps.GetSignedLong(value, this)), _swap);
} else {
owner.WriteInt64(offset, ModuleOps.GetSignedLong(value, this), _swap);
}
break;
case SimpleTypeKind.UnsignedLong:
if (TypecodeOps.IsCLong32Bit) {
owner.WriteInt32(offset, unchecked((int)ModuleOps.GetUnsignedLong(value, this)), _swap);
} else {
owner.WriteInt64(offset, unchecked((long)ModuleOps.GetUnsignedLong(value, this)), _swap);
}
break;
case SimpleTypeKind.UnsignedLongLong: owner.WriteInt64(offset, unchecked((long)ModuleOps.GetUnsignedLongLong(value, this)), _swap); break;
case SimpleTypeKind.SignedLongLong: owner.WriteInt64(offset, ModuleOps.GetSignedLongLong(value, this), _swap); break;
case SimpleTypeKind.Single: owner.WriteInt32(offset, ModuleOps.GetSingleBits(value), _swap); break;
Expand Down Expand Up @@ -301,11 +314,13 @@ object INativeType.SetValue(MemoryHolder/*!*/ owner, int offset, object value) {
case SimpleTypeKind.UnsignedShort:
return typeof(ushort);
case SimpleTypeKind.SignedInt:
case SimpleTypeKind.SignedLong:
return typeof(int);
case SimpleTypeKind.UnsignedInt:
case SimpleTypeKind.UnsignedLong:
return typeof(uint);
case SimpleTypeKind.SignedLong:
return TypecodeOps.IsCLong32Bit ? typeof(int) : typeof(long);
case SimpleTypeKind.UnsignedLong:
return TypecodeOps.IsCLong32Bit ? typeof(uint) : typeof(ulong);
case SimpleTypeKind.SignedLongLong:
return typeof(long);
case SimpleTypeKind.UnsignedLongLong:
Expand Down Expand Up @@ -589,8 +604,9 @@ private Type GetPythonTypeWorker() {
case SimpleTypeKind.SignedShort:
case SimpleTypeKind.UnsignedShort:
case SimpleTypeKind.SignedInt:
case SimpleTypeKind.SignedLong:
return typeof(int);
case SimpleTypeKind.SignedLong:
return TypecodeOps.IsCLong32Bit ? typeof(int) : typeof(object);
case SimpleTypeKind.UnsignedInt:
case SimpleTypeKind.UnsignedLong:
case SimpleTypeKind.UnsignedLongLong:
Expand Down Expand Up @@ -618,7 +634,6 @@ void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, Li
break;
case SimpleTypeKind.Boolean:
case SimpleTypeKind.SignedInt:
case SimpleTypeKind.SignedLong:
break;
case SimpleTypeKind.Single:
method.Emit(OpCodes.Conv_R8);
Expand All @@ -630,6 +645,10 @@ void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, Li
case SimpleTypeKind.UnsignedLongLong:
EmitUIntToObject(method, value);
break;
case SimpleTypeKind.SignedLong:
if (TypecodeOps.IsCLong32Bit) break; // no conversion needed
EmitInt64ToObject(method, value);
break;
case SimpleTypeKind.SignedLongLong:
EmitInt64ToObject(method, value);
break;
Expand Down
2 changes: 1 addition & 1 deletion src/core/IronPython.Modules/_ctypes/_ctypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ public static int set_last_error(int errorCode) {
}

public static int @sizeof(PythonType/*!*/ type) {
if (!(type is INativeType simpleType)) {
if (type is not INativeType simpleType) {
throw PythonOps.TypeError("this type has no size");
}

Expand Down
81 changes: 63 additions & 18 deletions src/core/IronPython.Modules/_struct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,25 @@ public void __init__(CodeContext/*!*/ context, object fmt) {
break;
case FormatType.UnsignedInt:
for (int j = 0; j < curFormat.Count; j++) {
WriteUInt(res, _isLittleEndian, GetULongValue(context, curObj++, values));
WriteUInt(res, _isLittleEndian, GetUIntValue(context, curObj++, values));
}
break;
case FormatType.Long:
for (int j = 0; j < curFormat.Count; j++) {
if (_isStandardized || TypecodeOps.IsCLong32Bit) {
WriteInt(res, _isLittleEndian, GetIntValue(context, curObj++, values));
} else {
WriteLong(res, _isLittleEndian, GetLongValue(context, curObj++, values));
}
}
break;
case FormatType.UnsignedLong:
for (int j = 0; j < curFormat.Count; j++) {
WriteUInt(res, _isLittleEndian, GetULongValue(context, curObj++, values));
if (_isStandardized || TypecodeOps.IsCLong32Bit) {
WriteUInt(res, _isLittleEndian, GetUIntValue(context, curObj++, values));
} else {
WriteULong(res, _isLittleEndian, GetULongValue(context, curObj++, values));
}
}
break;
case FormatType.LongLong:
Expand Down Expand Up @@ -310,11 +323,28 @@ public void pack_into(CodeContext/*!*/ context, [NotNone] IBufferProtocol/*!*/ b
}
break;
case FormatType.UnsignedInt:
case FormatType.UnsignedLong:
for (int j = 0; j < curFormat.Count; j++) {
res[res_idx++] = BigIntegerOps.__int__(CreateUIntValue(context, ref curIndex, _isLittleEndian, data));
}
break;
case FormatType.Long:
for (int j = 0; j < curFormat.Count; j++) {
if (_isStandardized || TypecodeOps.IsCLong32Bit) {
res[res_idx++] = CreateIntValue(context, ref curIndex, _isLittleEndian, data);
} else {
res[res_idx++] = BigIntegerOps.__int__(CreateLongValue(context, ref curIndex, _isLittleEndian, data));
}
}
break;
case FormatType.UnsignedLong:
for (int j = 0; j < curFormat.Count; j++) {
if (_isStandardized || TypecodeOps.IsCLong32Bit) {
res[res_idx++] = BigIntegerOps.__int__(CreateUIntValue(context, ref curIndex, _isLittleEndian, data));
} else {
res[res_idx++] = BigIntegerOps.__int__(CreateULongValue(context, ref curIndex, _isLittleEndian, data));
}
}
break;
case FormatType.LongLong:
for (int j = 0; j < curFormat.Count; j++) {
res[res_idx++] = BigIntegerOps.__int__(CreateLongValue(context, ref curIndex, _isLittleEndian, data));
Expand Down Expand Up @@ -472,14 +502,17 @@ private static Struct CompileAndCache(CodeContext/*!*/ context, string/*!*/ fmt)
count = 1;
break;
case 'i': // int
case 'l': // long
res.Add(new Format(FormatType.Int, count));
count = 1;
break;
case 'I': // unsigned int
res.Add(new Format(FormatType.UnsignedInt, count));
count = 1;
break;
case 'l': // long
res.Add(new Format(FormatType.Long, count));
count = 1;
break;
case 'L': // unsigned long
res.Add(new Format(FormatType.UnsignedLong, count));
count = 1;
Expand Down Expand Up @@ -624,7 +657,7 @@ private void InitCountAndSize() {
encodingSize = Align(encodingSize, format.NativeSize);
}

encodingSize += GetNativeSize(format.Type) * format.Count;
encodingSize += GetNativeSize(format.Type, _isStandardized) * format.Count;
}
_encodingCount = encodingCount;
_encodingSize = encodingSize;
Expand Down Expand Up @@ -729,6 +762,7 @@ private enum FormatType {

Int,
UnsignedInt,
Long,
UnsignedLong,
Float,

Expand All @@ -747,7 +781,7 @@ private enum FormatType {
SizeT,
}

private static int GetNativeSize(FormatType c) {
private static int GetNativeSize(FormatType c, bool isStandardized) {
switch (c) {
case FormatType.Char:
case FormatType.SignedChar:
Expand All @@ -765,11 +799,13 @@ private static int GetNativeSize(FormatType c) {
return 2;
case FormatType.Int:
case FormatType.UnsignedInt:
case FormatType.UnsignedLong:
case FormatType.Float:
case FormatType.SignedSizeT:
case FormatType.SizeT:
return 4;
case FormatType.Long:
case FormatType.UnsignedLong:
return isStandardized || TypecodeOps.IsCLong32Bit ? 4 : 8;
case FormatType.LongLong:
case FormatType.UnsignedLongLong:
case FormatType.Double:
Expand All @@ -786,16 +822,11 @@ private static int GetNativeSize(FormatType c) {
/// <summary>
/// Struct used to store the format and the number of times it should be repeated.
/// </summary>
private readonly struct Format {
public readonly FormatType Type;
public readonly int Count;

public Format(FormatType type, int count) {
Type = type;
Count = count;
}
private readonly struct Format(FormatType type, int count) {
public readonly FormatType Type = type;
public readonly int Count = count;

public int NativeSize => GetNativeSize(Type);
public int NativeSize => GetNativeSize(Type, isStandardized: false);
}

#endregion
Expand Down Expand Up @@ -1106,19 +1137,33 @@ internal static int GetIntValue(CodeContext/*!*/ context, int index, object[] ar
return res;
}

internal static uint GetULongValue(CodeContext/*!*/ context, int index, object[] args) {
internal static uint GetUIntValue(CodeContext/*!*/ context, int index, object[] args) {
BigInteger val = GetIntegerValue(context, index, args);
if (!val.AsUInt32(out uint res))
throw Error(context, "argument out of range");
return res;
}

internal static long GetLongValue(CodeContext/*!*/ context, int index, object[] args) {
BigInteger val = GetIntegerValue(context, index, args);
if (!val.AsInt64(out long res))
throw Error(context, "argument out of range");
return res;
}

internal static ulong GetULongValue(CodeContext/*!*/ context, int index, object[] args) {
BigInteger val = GetIntegerValue(context, index, args);
if (!val.AsUInt64(out ulong res))
throw Error(context, "argument out of range");
return res;
}

internal static int GetSignedSizeT(CodeContext/*!*/ context, int index, object[] args) {
return GetIntValue(context, index, args);
}

internal static uint GetSizeT(CodeContext/*!*/ context, int index, object[] args) {
return GetULongValue(context, index, args);
return GetUIntValue(context, index, args);
}

internal static ulong GetPointer(CodeContext/*!*/ context, int index, object[] args) {
Expand Down
Loading