Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement C long as 64-bit on POSIX #1918

Merged
merged 2 commits into from
Feb 23, 2025
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