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
Prev Previous commit
Next Next commit
tmp
  • Loading branch information
arihant2math committed Mar 24, 2025
commit 47ed34b9226cb2ea0ca351d9110c092dccb6a29e
12 changes: 9 additions & 3 deletions extra_tests/snippets/builtins_ctypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,16 @@ def create_string_buffer(init, size=None):
if size is None:
size = len(init)+1
_sys.audit("ctypes.create_string_buffer", init, size)
buftype = c_char * size
buftype = c_char.__mul__(size)
print(type(c_char.__mul__(size)))
# buftype = c_char * size
buf = buftype()
buf.value = init
return buf
elif isinstance(init, int):
_sys.audit("ctypes.create_string_buffer", None, init)
buftype = c_char * init
buftype = c_char.__mul__(init)
# buftype = c_char * init
buf = buftype()
return buf
raise TypeError(init)
Expand Down Expand Up @@ -260,8 +263,11 @@ def LoadLibrary(self, name):

cdll = LibraryLoader(CDLL)

test_byte_array = create_string_buffer(b"Hello, World!")

if _os.name == "posix" or _sys.platform == "darwin":
pass
else:
libc = cdll.msvcrt
print("rand", libc.rand())
libc.rand()
libc.printf(test_byte_array)
1 change: 1 addition & 0 deletions vm/src/stdlib/ctypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub fn extend_module_nodes(vm: &VirtualMachine, module: &Py<PyModule>) {
extend_module!(vm, module, {
"_CData" => PyCData::make_class(ctx),
"_SimpleCData" => PyCSimple::make_class(ctx),
"ArrayType" => array::PyCArrayType::make_class(ctx),
"Array" => array::PyCArray::make_class(ctx),
"CFuncPtr" => function::PyCFuncPtr::make_class(ctx),
"_Pointer" => pointer::PyCPointer::make_class(ctx),
Expand Down
95 changes: 93 additions & 2 deletions vm/src/stdlib/ctypes/array.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,96 @@
use crate::types::Callable;
use crate::{Py, PyObjectRef, PyPayload};
use crate::{PyResult, VirtualMachine, builtins::PyTypeRef, types::Constructor};
use crossbeam_utils::atomic::AtomicCell;
use rustpython_common::lock::PyRwLock;

// TODO: make it metaclass
#[pyclass(name = "Array", module = "_ctypes")]
#[derive(PyPayload)]
pub struct PyCArrayType {
pub(super) inner: PyCArray,
}

impl std::fmt::Debug for PyCArrayType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PyCArrayType")
.field("inner", &self.inner)
.finish()
}
}

impl Callable for PyCArrayType {
type Args = ();
fn call(zelf: &Py<Self>, _args: Self::Args, vm: &VirtualMachine) -> PyResult {
Ok(PyCArray {
typ: PyRwLock::new(zelf.inner.typ.read().clone()),
length: AtomicCell::new(zelf.inner.length.load()),
value: PyRwLock::new(zelf.inner.value.read().clone())
}
.into_pyobject(&vm))
}
}

impl Constructor for PyCArrayType {
type Args = PyObjectRef;

fn py_new(_cls: PyTypeRef, args: Self::Args, vm: &VirtualMachine) -> PyResult {
unreachable!()
}
}

#[pyclass(flags(IMMUTABLETYPE))]
impl PyCArrayType {}

#[pyclass(name = "Array", module = "_ctypes")]
pub struct PyCArray {}
#[derive(PyPayload)]
pub struct PyCArray {
pub(super) typ: PyRwLock<PyTypeRef>,
pub(super) length: AtomicCell<usize>,
pub(super) value: PyRwLock<PyObjectRef>,
}

impl std::fmt::Debug for PyCArray {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PyCArray")
.field("typ", &self.typ)
.field("length", &self.length)
.finish()
}
}

impl Constructor for PyCArray {
type Args = (PyTypeRef, usize);

fn py_new(_cls: PyTypeRef, args: Self::Args, vm: &VirtualMachine) -> PyResult {
Ok(Self {
typ: PyRwLock::new(args.0),
length: AtomicCell::new(args.1),
value: PyRwLock::new(vm.ctx.none())
}
.into_pyobject(&vm))
}
}

#[pyclass(flags(BASETYPE, IMMUTABLETYPE))]
impl PyCArray {}
impl PyCArray {
#[pygetset(name = "_type_")]
fn typ(&self) -> PyTypeRef {
self.typ.read().clone()
}

#[pygetset(name = "_length_")]
fn length(&self) -> usize {
self.length.load()
}

#[pygetset(name = "_value_")]
fn value(&self) -> PyObjectRef {
self.value.read().clone()
}

#[pygetset(setter, name = "_value_")]
fn set_value(&self, value: PyObjectRef) {
*self.value.write() = value;
}
}
21 changes: 21 additions & 0 deletions vm/src/stdlib/ctypes/base.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::array::{PyCArray, PyCArrayType};
use crate::builtins::PyType;
use crate::builtins::{PyBytes, PyFloat, PyInt, PyNone, PyStr, PyTypeRef};
use crate::convert::ToPyObject;
Expand Down Expand Up @@ -246,4 +247,24 @@ impl PyCSimple {
zelf.value.store(content);
Ok(())
}

#[pyclassmethod]
fn repeat(cls: PyTypeRef, n: isize, vm: &VirtualMachine) -> PyResult {
if n < 0 {
return Err(vm.new_value_error(format!("Array length must be >= 0, not {}", n)));
}
Ok(PyCArrayType {
inner: PyCArray {
typ: PyRwLock::new(cls),
length: AtomicCell::new(n as usize),
value: PyRwLock::new(vm.ctx.none()),
},
}
.to_pyobject(vm))
}

#[pyclassmethod(magic)]
fn mul(cls: PyTypeRef, n: isize, vm: &VirtualMachine) -> PyResult {
PyCSimple::repeat(cls, n, vm)
}
}