FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Test #8435 type slots api · RustPython/RustPython@bc481ed · GitHub

Commit bc481ed

Browse files
Test #8435 type slots api
1 parent ab5f063 commit bc481ed

3 files changed

Lines changed: 28 additions & 81 deletions

File tree

‎crates/capi/src/methodobject.rs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use crate::pystate::with_vm;
55
use crate::util::CStrExt;
66
use core::ffi::{c_char, c_int};
77
use core::fmt::Debug;
8-
use core::ptr::NonNull;
98
use rustpython_vm::function::{FuncArgs, HeapMethodDef, PosArgs, PyMethodFlags};
109
use rustpython_vm::types::c_slots::{kwargs_ptr, ret_ptr_to_pyresult, split_args};
1110
use rustpython_vm::{AsObject, PyObjectRef, PyRef, PyResult, VirtualMachine};

‎crates/capi/src/object/pytype.rs‎

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
use crate::abstract_::{dict_to_kwargs, tuple_to_args};
21
use crate::descrobject::{PyGetSetDef, PyMemberDef};
32
use crate::methodobject::{PyMethodDef, build_method_def};
43
use crate::object::define_py_check;
54
use crate::pystate::with_vm;
65
use crate::slots::{PySlot, PySlotKind, PySlotType};
76
use crate::util::CStrExt;
87
use core::ffi::{c_char, c_int, c_ulong, c_void};
9-
use rustpython_vm::builtins::{PyDict, PyStr, PyTuple, PyType};
10-
use rustpython_vm::function::{FuncArgs, PyMethodFlags};
11-
use rustpython_vm::types::{PyTypeFlags, PyTypeSlots, SlotAccessor};
8+
use core::mem::transmute;
9+
use rustpython_vm::builtins::{PyStr, PyType};
10+
use rustpython_vm::function::PyMethodFlags;
11+
use rustpython_vm::types::{CSlotId, CSlots, PyTypeFlags, PyTypeSlots, SlotAccessor};
1212
use rustpython_vm::{AsObject, Py, PyObject};
13+
use std::ptr;
1314

1415
pub type PyTypeObject = Py<PyType>;
1516

@@ -99,63 +100,26 @@ pub unsafe extern "C" fn PyType_GetFullyQualifiedName(ptr: *const PyTypeObject)
99100

100101
#[unsafe(no_mangle)]
101102
pub unsafe extern "C" fn PyType_GetSlot(ty: *const PyTypeObject, slot: c_int) -> *mut c_void {
102-
with_vm(|_vm| {
103-
let ty = unsafe { &*ty };
104-
let slot: u8 = slot
105-
.try_into()
106-
.expect("slot number out of range for SlotAccessor");
107-
let slot_accessor: SlotAccessor = slot
108-
.try_into()
109-
.expect("invalid slot number for SlotAccessor");
110-
111-
match slot_accessor {
112-
SlotAccessor::TpNew => {
113-
extern "C" fn newfunc_wrapper(
114-
subtype: *mut PyTypeObject,
115-
args: *mut PyObject,
116-
kwargs: *mut PyObject,
117-
) -> *mut PyObject {
118-
with_vm(|vm| {
119-
let subtype = unsafe { &*subtype };
120-
121-
let args = if let Some(args_obj) = unsafe { args.as_ref() } {
122-
tuple_to_args(args_obj.try_downcast_ref::<PyTuple>(vm)?)
123-
} else {
124-
().into()
125-
};
126-
127-
let kwargs = unsafe { kwargs.as_ref() }
128-
.map(|obj| dict_to_kwargs(vm, obj.try_downcast_ref::<PyDict>(vm)?))
129-
.transpose()?
130-
.unwrap_or_default();
131-
132-
subtype
133-
.slots
134-
.new
135-
.load()
136-
.expect("tp_new slot function pointer is null")(
137-
subtype.to_owned(),
138-
FuncArgs::new(args, kwargs),
139-
vm,
140-
)
141-
})
142-
}
143-
144-
ty.slots.new.load().map(|_| newfunc_wrapper as *mut c_void)
145-
}
146-
_ => {
147-
todo!("Slot {slot_accessor:?} for {ty:?} is not yet implemented in PyType_GetSlot")
148-
}
149-
}
150-
.unwrap_or_default()
151-
})
103+
let ty = unsafe { &*ty };
104+
eprintln!("PyType_GetSlot({:?}, {:?})", ty, slot);
105+
let Some(c_slots) = ty.slots.c_slots() else {
106+
return ptr::null_mut();
107+
};
108+
match CSlotId::from_raw(slot) {
109+
Some(CSlotId::TpNew) => c_slots
110+
.new
111+
.load()
112+
.map_or(ptr::null_mut(), |f| f as *mut c_void),
113+
None => ptr::null_mut(),
114+
}
152115
}
153116

154117
#[unsafe(no_mangle)]
155118
pub extern "C" fn PyType_FromSlots(slots: *const PySlot) -> *mut PyObject {
156119
with_vm(|vm| {
157120
let mut name = None;
158121
let mut base = None;
122+
let c_slots = CSlots::new();
159123
let mut methods = Vec::new();
160124
let mut type_slots: PyTypeSlots = Default::default();
161125
let attrs = Default::default();
@@ -192,9 +156,12 @@ pub extern "C" fn PyType_FromSlots(slots: *const PySlot) -> *mut PyObject {
192156
type_slots.doc = doc;
193157
}
194158
SlotAccessor::TpNew => {
195-
type_slots.new.store(Some(|ty, _args, vm| {
196-
Err(vm.new_not_implemented_error(format!("tp_new is not yet implemented in PyType_FromSlots for {ty:?}")))
197-
}));
159+
let tp_new = unsafe { transmute(slot.pfunc) };
160+
c_slots.new.store(Some(tp_new));
161+
let def = vm
162+
.ctx
163+
.new_method_def("__new__", PyType::__new__, PyMethodFlags::METHOD, None);
164+
methods.push(("__new__", def.into()));
198165
}
199166
SlotAccessor::TpBase => {
200167
base = unsafe { Some(&*slot.pfunc.cast::<PyTypeObject>()) }
@@ -257,6 +224,7 @@ pub extern "C" fn PyType_FromSlots(slots: *const PySlot) -> *mut PyObject {
257224
vm.new_system_error(format!("Failed to create type from slots: {msg}"))
258225
})?;
259226

227+
class.set_c_slots(c_slots, vm)?;
260228
let mut attrs = class.attributes.write();
261229
let class_static = unsafe { &*((&*class) as *const _) };
262230
for (name, method) in methods {

‎crates/capi/src/typeobject.rs‎

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99
//! `__new__` is the same wrapper a native type gets, so a call through it is
1010
//! checked by `PyType::__new__` before it reaches the slot.
1111
12-
use crate::object::PyTypeObject;
13-
use core::ffi::{c_int, c_void};
14-
use core::ptr;
12+
use core::ffi::c_int;
1513
use rustpython_vm::builtins::PyType;
1614
use rustpython_vm::function::PyMethodFlags;
1715
use rustpython_vm::types::{CNewFunc, CSlotId, CSlots};
@@ -42,29 +40,11 @@ pub fn set_tp_new(vm: &VirtualMachine, ty: &Py<PyType>, tp_new: newfunc) -> PyRe
4240
Ok(())
4341
}
4442

45-
/// Only slots installed from C are reported. A slot backed by a Rust function
46-
/// has no C ABI entry point yet and reads as empty, as does a slot id this
47-
/// layer does not handle.
48-
#[unsafe(no_mangle)]
49-
#[allow(non_upper_case_globals)]
50-
pub unsafe extern "C" fn PyType_GetSlot(ty: *const PyTypeObject, slot: c_int) -> *mut c_void {
51-
let ty = unsafe { &*ty };
52-
let Some(c_slots) = ty.slots.c_slots() else {
53-
return ptr::null_mut();
54-
};
55-
match CSlotId::from_raw(slot) {
56-
Some(CSlotId::TpNew) => c_slots
57-
.new
58-
.load()
59-
.map_or(ptr::null_mut(), |f| f as *mut c_void),
60-
None => ptr::null_mut(),
61-
}
62-
}
63-
6443
#[cfg(test)]
6544
mod tests {
6645
use super::*;
67-
use crate::PyObject;
46+
use crate::{PyObject, object::{PyType_GetSlot, PyTypeObject}};
47+
use core::ffi::c_void;
6848
use pyo3::Python;
6949
use rustpython_vm::builtins::{PyStrRef, PyTuple, PyTypeRef};
7050
use rustpython_vm::function::{FuncArgs, KwArgs};

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL