From a6a3101f2f8af0860272c15c2b0be45564a642f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Tue, 14 Jun 2022 15:18:35 +0300 Subject: [PATCH] Implement cpython support in test_c_interop_04 --- integration_tests/CMakeLists.txt | 2 +- integration_tests/test_c_interop_04.py | 6 ++++- src/lpython/semantics/python_ast_to_asr.cpp | 5 ++++ src/runtime/ltypes/ltypes.py | 28 +++++++++++++++++---- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index e8c2459ef4..5674dec808 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -156,7 +156,7 @@ RUN(NAME test_c_interop_02 LABELS cpython llvm c EXTRAFILES test_c_interop_02b.c) RUN(NAME test_c_interop_03 LABELS llvm c EXTRAFILES test_c_interop_03b.c) -RUN(NAME test_c_interop_04 LABELS llvm c +RUN(NAME test_c_interop_04 LABELS cpython llvm c EXTRAFILES test_c_interop_04b.c) RUN(NAME test_c_interop_05 LABELS llvm c EXTRAFILES test_c_interop_05b.c) diff --git a/integration_tests/test_c_interop_04.py b/integration_tests/test_c_interop_04.py index 9f9c90929f..483e4266c8 100644 --- a/integration_tests/test_c_interop_04.py +++ b/integration_tests/test_c_interop_04.py @@ -1,4 +1,6 @@ -from ltypes import ccall, f32, f64, i32, i64, CPtr, pointer, Pointer, p_c_pointer +from ltypes import (ccall, f32, f64, i32, i64, CPtr, pointer, Pointer, + p_c_pointer, empty_c_void_p) +from numpy import empty, int32 @ccall def sum_pi32_i32(x: CPtr) -> i32: @@ -6,6 +8,7 @@ def sum_pi32_i32(x: CPtr) -> i32: def test_c_callbacks(): xi32: i32[4] + xi32 = empty(4, dtype=int32) sumi32: i32 xi32[0] = 3 xi32[1] = 4 @@ -13,6 +16,7 @@ def test_c_callbacks(): xi32[3] = 6 print(xi32[0], xi32[1], xi32[2], xi32[3]) p: CPtr + p = empty_c_void_p() p_c_pointer(pointer(xi32), p) print(pointer(xi32), p) sumi32 = sum_pi32_i32(p) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 991eb623fd..ff610631bf 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -3336,6 +3336,11 @@ class BodyVisitor : public CommonVisitor { // with the type tmp = nullptr; return; + } else if (call_name == "empty_c_void_p") { + // TODO: check that `empty_c_void_p uses` has arguments that are compatible + // with the type + tmp = nullptr; + return; } else if (call_name == "TypeVar") { // Ignore TypeVar for now, we handle it based on the identifier itself tmp = nullptr; diff --git a/src/runtime/ltypes/ltypes.py b/src/runtime/ltypes/ltypes.py index 03983de50c..1531770518 100644 --- a/src/runtime/ltypes/ltypes.py +++ b/src/runtime/ltypes/ltypes.py @@ -4,8 +4,9 @@ import platform from typing import TypeVar -__slots__ = ["i8", "i16", "i32", "i64", "f32", "f64", "c32", "c64", "c_ptr", - "overload", "ccall", "TypeVar", "pointer", "Pointer"] +# TODO: this does not seem to restrict other imports +__slots__ = ["i8", "i16", "i32", "i64", "f32", "f64", "c32", "c64", "CPtr", + "overload", "ccall", "TypeVar", "pointer", "c_p_pointer", "Pointer"] # data-types @@ -120,13 +121,15 @@ def convert_type_to_ctype(arg): return ctypes.c_int64 elif arg == i32: return ctypes.c_int32 + elif arg == CPtr: + return ctypes.c_void_p elif arg is None: raise NotImplementedError("Type cannot be None") elif isinstance(arg, Array): type = convert_type_to_ctype(arg._type) return ctypes.POINTER(type) else: - raise NotImplementedError("Type not implemented") + raise NotImplementedError("Type %r not implemented" % arg) def get_rtlib_dir(): current_dir = os.path.dirname(os.path.abspath(__file__)) return os.path.join(current_dir, "..") @@ -174,8 +177,23 @@ def ccall(f): wrapped_f = CTypes(f) return wrapped_f -def pointer(type_): - return type_ +def pointer(x): + from numpy import ndarray + if isinstance(x, ndarray): + return ctypes.c_void_p(x.ctypes.data) + #return x.ctypes.data_as(ctypes.POINTER(ctypes.c_int32)) + else: + type_ = x.annotations[0] + if type_ == i32: + return ctypes.pointer(ctypes.c_int32(x)) + else: + raise Exception("Type not supported in pointer()") def c_p_pointer(cptr, targettype): return pointer(targettype) + +def p_c_pointer(ptr, cptr): + cptr.value = ptr.value + +def empty_c_void_p(): + return ctypes.c_void_p()