Skip to content

Commit 64828c9

Browse files
authored
Merge pull request #602 from certik/cp1
Implement cpython support in test_c_interop_04
2 parents 1bb7616 + a6a3101 commit 64828c9

File tree

4 files changed

+34
-7
lines changed

4 files changed

+34
-7
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ RUN(NAME test_c_interop_02 LABELS cpython llvm c
156156
EXTRAFILES test_c_interop_02b.c)
157157
RUN(NAME test_c_interop_03 LABELS llvm c
158158
EXTRAFILES test_c_interop_03b.c)
159-
RUN(NAME test_c_interop_04 LABELS llvm c
159+
RUN(NAME test_c_interop_04 LABELS cpython llvm c
160160
EXTRAFILES test_c_interop_04b.c)
161161
RUN(NAME test_c_interop_05 LABELS llvm c
162162
EXTRAFILES test_c_interop_05b.c)

integration_tests/test_c_interop_04.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
1-
from ltypes import ccall, f32, f64, i32, i64, CPtr, pointer, Pointer, p_c_pointer
1+
from ltypes import (ccall, f32, f64, i32, i64, CPtr, pointer, Pointer,
2+
p_c_pointer, empty_c_void_p)
3+
from numpy import empty, int32
24

35
@ccall
46
def sum_pi32_i32(x: CPtr) -> i32:
57
pass
68

79
def test_c_callbacks():
810
xi32: i32[4]
11+
xi32 = empty(4, dtype=int32)
912
sumi32: i32
1013
xi32[0] = 3
1114
xi32[1] = 4
1215
xi32[2] = 5
1316
xi32[3] = 6
1417
print(xi32[0], xi32[1], xi32[2], xi32[3])
1518
p: CPtr
19+
p = empty_c_void_p()
1620
p_c_pointer(pointer(xi32), p)
1721
print(pointer(xi32), p)
1822
sumi32 = sum_pi32_i32(p)

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3336,6 +3336,11 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
33363336
// with the type
33373337
tmp = nullptr;
33383338
return;
3339+
} else if (call_name == "empty_c_void_p") {
3340+
// TODO: check that `empty_c_void_p uses` has arguments that are compatible
3341+
// with the type
3342+
tmp = nullptr;
3343+
return;
33393344
} else if (call_name == "TypeVar") {
33403345
// Ignore TypeVar for now, we handle it based on the identifier itself
33413346
tmp = nullptr;

src/runtime/ltypes/ltypes.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
import platform
55
from typing import TypeVar
66

7-
__slots__ = ["i8", "i16", "i32", "i64", "f32", "f64", "c32", "c64", "c_ptr",
8-
"overload", "ccall", "TypeVar", "pointer", "Pointer"]
7+
# TODO: this does not seem to restrict other imports
8+
__slots__ = ["i8", "i16", "i32", "i64", "f32", "f64", "c32", "c64", "CPtr",
9+
"overload", "ccall", "TypeVar", "pointer", "c_p_pointer", "Pointer"]
910

1011
# data-types
1112

@@ -120,13 +121,15 @@ def convert_type_to_ctype(arg):
120121
return ctypes.c_int64
121122
elif arg == i32:
122123
return ctypes.c_int32
124+
elif arg == CPtr:
125+
return ctypes.c_void_p
123126
elif arg is None:
124127
raise NotImplementedError("Type cannot be None")
125128
elif isinstance(arg, Array):
126129
type = convert_type_to_ctype(arg._type)
127130
return ctypes.POINTER(type)
128131
else:
129-
raise NotImplementedError("Type not implemented")
132+
raise NotImplementedError("Type %r not implemented" % arg)
130133
def get_rtlib_dir():
131134
current_dir = os.path.dirname(os.path.abspath(__file__))
132135
return os.path.join(current_dir, "..")
@@ -174,8 +177,23 @@ def ccall(f):
174177
wrapped_f = CTypes(f)
175178
return wrapped_f
176179

177-
def pointer(type_):
178-
return type_
180+
def pointer(x):
181+
from numpy import ndarray
182+
if isinstance(x, ndarray):
183+
return ctypes.c_void_p(x.ctypes.data)
184+
#return x.ctypes.data_as(ctypes.POINTER(ctypes.c_int32))
185+
else:
186+
type_ = x.annotations[0]
187+
if type_ == i32:
188+
return ctypes.pointer(ctypes.c_int32(x))
189+
else:
190+
raise Exception("Type not supported in pointer()")
179191

180192
def c_p_pointer(cptr, targettype):
181193
return pointer(targettype)
194+
195+
def p_c_pointer(ptr, cptr):
196+
cptr.value = ptr.value
197+
198+
def empty_c_void_p():
199+
return ctypes.c_void_p()

0 commit comments

Comments
 (0)