Skip to content

Commit 50ddfe3

Browse files
committed
Fix c_void_p for large and negative values.
This fixes mesonbuild arch detection on Windows, where they do kernel32 = ctypes.windll.kernel32 process = ctypes.c_void_p(kernel32.GetCurrentProcess()) GetCurrentProcess() is documented to return -1, and we refused to convert a negative value to a pointer.
1 parent 7f330d9 commit 50ddfe3

File tree

3 files changed

+62
-13
lines changed

3 files changed

+62
-13
lines changed

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_ctypes.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import ctypes
4040
import os.path
4141
import struct
42+
import sys
4243

4344
from tests.cpyext import CPyExtTestCase, CPyExtType
4445

@@ -225,3 +226,27 @@ class MyLargeStruct(ctypes.Structure):
225226
assert result.num7 == 42
226227
finally:
227228
os.chdir(original_cwd)
229+
230+
231+
def test_void_p():
232+
assert ctypes.c_void_p(True).value == ctypes.c_void_p(1).value
233+
assert ctypes.c_void_p(False).value == ctypes.c_void_p(0).value
234+
assert ctypes.c_void_p(2**128 - 1).value == ctypes.c_void_p(2**64 - 1).value
235+
try:
236+
ctypes.c_void_p(2**128 - 1)
237+
except TypeError as e:
238+
assert "cannot be converted to pointer" in str(e)
239+
240+
241+
def test_meson_windows_detect_native_arch() -> str:
242+
if sys.platform != 'win32':
243+
return
244+
process_arch = ctypes.c_ushort()
245+
native_arch = ctypes.c_ushort()
246+
kernel32 = ctypes.windll.kernel32
247+
process = ctypes.c_void_p(kernel32.GetCurrentProcess())
248+
try:
249+
if kernel32.IsWow64Process2(process, ctypes.byref(process_arch), ctypes.byref(native_arch)):
250+
assert native_arch.value == 0x8664, "only amd64 supported by GraalPy on Windows"
251+
except AttributeError as e:
252+
assert "Unknown identifier: IsWow64Process2" in str(e)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CFieldBuiltins.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -725,19 +725,14 @@ static Object Z_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, O
725725
@Specialization(guards = "setfunc == P_set")
726726
static Object P_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, Object value, @SuppressWarnings("unused") int size,
727727
@Bind("this") Node inliningTarget,
728-
@Exclusive @Cached PyLongCheckNode longCheckNode,
729728
@Exclusive @Cached PointerNodes.PointerFromLongNode pointerFromLongNode,
730-
@Exclusive @Cached PointerNodes.WritePointerNode writePointerNode,
731-
@Exclusive @Cached PRaiseNode raiseNode) {
729+
@Exclusive @Cached PointerNodes.WritePointerNode writePointerNode) {
732730
Pointer valuePtr;
733731
if (value == PNone.NONE) {
734732
valuePtr = Pointer.NULL;
735-
} else if (longCheckNode.execute(inliningTarget, value)) {
736-
valuePtr = pointerFromLongNode.execute(inliningTarget, value);
737733
} else {
738-
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_BE_CONVERTED_TO_POINTER);
734+
valuePtr = pointerFromLongNode.execute(inliningTarget, value);
739735
}
740-
741736
writePointerNode.execute(inliningTarget, ptr, valuePtr);
742737
return PNone.NONE;
743738
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/memory/PointerNodes.java

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,12 @@
4141
package com.oracle.graal.python.builtins.modules.ctypes.memory;
4242

4343
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.NotImplementedError;
44+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError;
4445
import static com.oracle.graal.python.builtins.modules.ctypes.CtypesNodes.WCHAR_T_SIZE;
4546
import static com.oracle.graal.python.util.PythonUtils.ARRAY_ACCESSOR;
4647

48+
import java.math.BigInteger;
49+
4750
import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer.ByteArrayStorage;
4851
import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer.LongPointerStorage;
4952
import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer.MemoryBlock;
@@ -58,14 +61,15 @@
5861
import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr;
5962
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes;
6063
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
64+
import com.oracle.graal.python.builtins.objects.ints.PInt;
6165
import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView;
6266
import com.oracle.graal.python.nodes.ErrorMessages;
6367
import com.oracle.graal.python.nodes.PRaiseNode;
64-
import com.oracle.graal.python.nodes.util.CastToJavaUnsignedLongNode;
6568
import com.oracle.graal.python.runtime.PythonContext;
6669
import com.oracle.graal.python.util.PythonUtils;
6770
import com.oracle.truffle.api.CompilerDirectives;
6871
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
72+
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
6973
import com.oracle.truffle.api.dsl.Cached;
7074
import com.oracle.truffle.api.dsl.Fallback;
7175
import com.oracle.truffle.api.dsl.GenerateCached;
@@ -790,11 +794,36 @@ static Pointer doNativeVoidPtr(PythonNativeVoidPtr value) {
790794
return Pointer.nativeMemory(pointerObject);
791795
}
792796

793-
@Fallback
794-
static Pointer doLong(Node inliningTarget, Object value,
795-
@Cached CastToJavaUnsignedLongNode cast) {
796-
long pointer = cast.execute(inliningTarget, value);
797-
return Pointer.nativeMemory(pointer);
797+
@Specialization
798+
static Pointer doBool(Node inliningTarget, boolean value) {
799+
return Pointer.nativeMemory(value ? 1 : 0);
800+
}
801+
802+
@Specialization
803+
static Pointer doLong(Node inliningTarget, long value) {
804+
return Pointer.nativeMemory(value);
805+
}
806+
807+
@Specialization
808+
static Pointer doPInt(Node inliningTarget, PInt value) {
809+
return Pointer.nativeMemory(value.longValue());
810+
}
811+
812+
@Specialization
813+
@TruffleBoundary
814+
@InliningCutoff
815+
static Pointer doGeneric(Node inliningTarget, Object value,
816+
@CachedLibrary(limit = "1") InteropLibrary lib) {
817+
if (lib.fitsInBigInteger(value)) {
818+
BigInteger bi;
819+
try {
820+
bi = lib.asBigInteger(value);
821+
return doLong(inliningTarget, bi.longValue());
822+
} catch (UnsupportedMessageException e) {
823+
// fall through to error
824+
}
825+
}
826+
throw PRaiseNode.raiseStatic(inliningTarget, OverflowError, ErrorMessages.CANNOT_BE_CONVERTED_TO_POINTER);
798827
}
799828
}
800829

0 commit comments

Comments
 (0)