mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Add integer c-api support (#7905)
* Add integer c-api support * Fix `PyLong_AsUnsignedLongLong` return value * Fix error message * Add type check functions
This commit is contained in:
committed by
GitHub
parent
20cb8843e0
commit
6e56d935cf
@@ -11,6 +11,7 @@ extern crate alloc;
|
||||
pub mod abstract_;
|
||||
pub mod bytesobject;
|
||||
pub mod import;
|
||||
pub mod longobject;
|
||||
pub mod object;
|
||||
pub mod pyerrors;
|
||||
pub mod pylifecycle;
|
||||
|
||||
89
crates/capi/src/longobject.rs
Normal file
89
crates/capi/src/longobject.rs
Normal file
@@ -0,0 +1,89 @@
|
||||
use crate::PyObject;
|
||||
use crate::object::define_py_check;
|
||||
use crate::pystate::with_vm;
|
||||
use core::ffi::{c_long, c_longlong, c_ulong, c_ulonglong};
|
||||
use rustpython_vm::PyResult;
|
||||
use rustpython_vm::builtins::PyInt;
|
||||
|
||||
define_py_check!(fn PyLong_Check, types.int_type);
|
||||
define_py_check!(exact fn PyLong_CheckExact, types.int_type);
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn PyLong_FromLong(value: c_long) -> *mut PyObject {
|
||||
with_vm(|vm| vm.ctx.new_int(value))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn PyLong_FromLongLong(value: c_longlong) -> *mut PyObject {
|
||||
with_vm(|vm| vm.ctx.new_int(value))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn PyLong_FromSsize_t(value: isize) -> *mut PyObject {
|
||||
with_vm(|vm| vm.ctx.new_int(value))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn PyLong_FromSize_t(value: usize) -> *mut PyObject {
|
||||
with_vm(|vm| vm.ctx.new_int(value))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn PyLong_FromUnsignedLong(value: c_ulong) -> *mut PyObject {
|
||||
with_vm(|vm| vm.ctx.new_int(value))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn PyLong_FromUnsignedLongLong(value: c_ulonglong) -> *mut PyObject {
|
||||
with_vm(|vm| vm.ctx.new_int(value))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn PyLong_AsLong(obj: *mut PyObject) -> c_long {
|
||||
with_vm::<PyResult<c_long>, _>(|vm| {
|
||||
unsafe { &*obj }
|
||||
.to_owned()
|
||||
.try_index(vm)?
|
||||
.as_bigint()
|
||||
.try_into()
|
||||
.map_err(|_| vm.new_overflow_error("Python int too large to convert to C long"))
|
||||
})
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn PyLong_AsUnsignedLongLong(obj: *mut PyObject) -> c_ulonglong {
|
||||
with_vm::<PyResult<c_ulonglong>, _>(|vm| {
|
||||
unsafe { &*obj }
|
||||
.to_owned()
|
||||
.try_downcast::<PyInt>(vm)?
|
||||
.as_bigint()
|
||||
.try_into()
|
||||
.map_err(|_| {
|
||||
vm.new_overflow_error("Python int too large to convert to C unsigned long long")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(false)]
|
||||
mod tests {
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::PyInt;
|
||||
|
||||
#[test]
|
||||
fn test_py_int_u32() {
|
||||
Python::attach(|py| {
|
||||
let number = PyInt::new(py, 123);
|
||||
assert!(number.is_instance_of::<PyInt>());
|
||||
assert_eq!(number.extract::<i32>().unwrap(), 123);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_py_int_u64() {
|
||||
Python::attach(|py| {
|
||||
let number = PyInt::new(py, 123u64);
|
||||
assert!(number.is_instance_of::<PyInt>());
|
||||
assert_eq!(number.extract::<u64>().unwrap(), 123);
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::PyObject;
|
||||
use core::convert::Infallible;
|
||||
use core::ffi::{c_char, c_double, c_int, c_long, c_void};
|
||||
use core::ffi::{c_char, c_double, c_int, c_long, c_ulonglong, c_void};
|
||||
use rustpython_vm::{PyObjectRef, PyRef, PyResult, VirtualMachine};
|
||||
|
||||
pub(crate) trait FfiResult<Output = Self> {
|
||||
@@ -93,6 +93,14 @@ impl FfiResult for c_long {
|
||||
}
|
||||
}
|
||||
|
||||
impl FfiResult for c_ulonglong {
|
||||
const ERR_VALUE: Self = Self::MAX;
|
||||
|
||||
fn into_output(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl FfiResult for c_double {
|
||||
const ERR_VALUE: Self = -1.0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user