diff --git a/crates/capi/src/object.rs b/crates/capi/src/object.rs index fb8fc3de5..47ac58560 100644 --- a/crates/capi/src/object.rs +++ b/crates/capi/src/object.rs @@ -1,7 +1,8 @@ use crate::PyObject; use crate::pystate::with_vm; -use core::ffi::{c_int, c_uint, c_ulong}; -use rustpython_vm::builtins::PyType; +use core::ffi::{CStr, c_char, c_int, c_uint, c_ulong}; +use core::ptr::NonNull; +use rustpython_vm::builtins::{PyStr, PyType}; use rustpython_vm::{AsObject, Py}; pub type PyTypeObject = Py; @@ -46,3 +47,91 @@ pub extern "C" fn Py_GetConstantBorrowed(constant_id: c_uint) -> *mut PyObject { Ok(constant) }) } + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyObject_GetAttr( + obj: *mut PyObject, + name: *mut PyObject, +) -> *mut PyObject { + with_vm(|vm| { + let obj = unsafe { &*obj }; + let name = unsafe { &*name }.try_downcast_ref::(vm)?; + obj.get_attr(name, vm) + }) +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyObject_GetAttrString( + obj: *mut PyObject, + attr_name: *const c_char, +) -> *mut PyObject { + with_vm(|vm| { + let obj = unsafe { &*obj }; + let name = unsafe { + CStr::from_ptr(attr_name) + .to_str() + .expect("attribute name must be valid UTF-8") + }; + obj.get_attr(name, vm) + }) +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyObject_SetAttrString( + obj: *mut PyObject, + attr_name: *const c_char, + value: *mut PyObject, +) -> c_int { + with_vm(|vm| { + let obj = unsafe { &*obj }; + let name = unsafe { CStr::from_ptr(attr_name) } + .to_str() + .expect("attribute name must be valid UTF-8"); + let value = unsafe { &*value }.to_owned(); + obj.set_attr(name, value, vm) + }) +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyObject_SetAttr( + obj: *mut PyObject, + name: *mut PyObject, + value: *mut PyObject, +) -> c_int { + with_vm(|vm| { + let obj = unsafe { &*obj }; + let name = unsafe { &*name }.try_downcast_ref::(vm)?; + let value = unsafe { &*value }.to_owned(); + obj.set_attr(name, value, vm) + }) +} + +#[unsafe(no_mangle)] +pub extern "C" fn PyObject_Repr(obj: *mut PyObject) -> *mut PyObject { + with_vm(|vm| { + let Some(obj) = NonNull::new(obj) else { + return Ok(vm.ctx.new_str("")); + }; + + unsafe { obj.as_ref() }.repr(vm) + }) +} + +#[unsafe(no_mangle)] +pub extern "C" fn PyObject_Str(obj: *mut PyObject) -> *mut PyObject { + with_vm(|vm| { + let Some(obj) = NonNull::new(obj) else { + return Ok(vm.ctx.new_str("")); + }; + + unsafe { obj.as_ref() }.str(vm) + }) +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyObject_IsTrue(obj: *mut PyObject) -> c_int { + with_vm(|vm| { + let obj = unsafe { &*obj }; + obj.to_owned().is_true(vm) + }) +}