| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,7 +5,6 @@ use crate::pystate::with_vm; | |||
| 5 | 5 | use crate::util::CStrExt; | |
| 6 | 6 | use core::ffi::{c_char, c_int}; | |
| 7 | 7 | use core::fmt::Debug; | |
| 8 | - use core::ptr::NonNull; | ||
| 9 | 8 | use rustpython_vm::function::{FuncArgs, HeapMethodDef, PosArgs, PyMethodFlags}; | |
| 10 | 9 | use rustpython_vm::types::c_slots::{kwargs_ptr, ret_ptr_to_pyresult, split_args}; | |
| 11 | 10 | use rustpython_vm::{AsObject, PyObjectRef, PyRef, PyResult, VirtualMachine}; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,15 +1,16 @@ | |||
| 1 | - use crate::abstract_::{dict_to_kwargs, tuple_to_args}; | ||
| 2 | 1 | use crate::descrobject::{PyGetSetDef, PyMemberDef}; | |
| 3 | 2 | use crate::methodobject::{PyMethodDef, build_method_def}; | |
| 4 | 3 | use crate::object::define_py_check; | |
| 5 | 4 | use crate::pystate::with_vm; | |
| 6 | 5 | use crate::slots::{PySlot, PySlotKind, PySlotType}; | |
| 7 | 6 | use crate::util::CStrExt; | |
| 8 | 7 | 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}; | ||
| 12 | 12 | use rustpython_vm::{AsObject, Py, PyObject}; | |
| 13 | + use std::ptr; | ||
| 13 | 14 | ||
| 14 | 15 | pub type PyTypeObject = Py<PyType>; | |
| 15 | 16 | ||
@@ -99,63 +100,26 @@ pub unsafe extern "C" fn PyType_GetFullyQualifiedName(ptr: *const PyTypeObject) | |||
| 99 | 100 | ||
| 100 | 101 | #[unsafe(no_mangle)] | |
| 101 | 102 | 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 | + } | ||
| 152 | 115 | } | |
| 153 | 116 | ||
| 154 | 117 | #[unsafe(no_mangle)] | |
| 155 | 118 | pub extern "C" fn PyType_FromSlots(slots: *const PySlot) -> *mut PyObject { | |
| 156 | 119 | with_vm(|vm| { | |
| 157 | 120 | let mut name = None; | |
| 158 | 121 | let mut base = None; | |
| 122 | + let c_slots = CSlots::new(); | ||
| 159 | 123 | let mut methods = Vec::new(); | |
| 160 | 124 | let mut type_slots: PyTypeSlots = Default::default(); | |
| 161 | 125 | let attrs = Default::default(); | |
@@ -192,9 +156,12 @@ pub extern "C" fn PyType_FromSlots(slots: *const PySlot) -> *mut PyObject { | |||
| 192 | 156 | type_slots.doc = doc; | |
| 193 | 157 | } | |
| 194 | 158 | 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())); | ||
| 198 | 165 | } | |
| 199 | 166 | SlotAccessor::TpBase => { | |
| 200 | 167 | base = unsafe { Some(&*slot.pfunc.cast::<PyTypeObject>()) } | |
@@ -257,6 +224,7 @@ pub extern "C" fn PyType_FromSlots(slots: *const PySlot) -> *mut PyObject { | |||
| 257 | 224 | vm.new_system_error(format!("Failed to create type from slots: {msg}")) | |
| 258 | 225 | })?; | |
| 259 | 226 | ||
| 227 | + class.set_c_slots(c_slots, vm)?; | ||
| 260 | 228 | let mut attrs = class.attributes.write(); | |
| 261 | 229 | let class_static = unsafe { &*((&*class) as *const _) }; | |
| 262 | 230 | for (name, method) in methods { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,9 +9,7 @@ | |||
| 9 | 9 | //! `__new__` is the same wrapper a native type gets, so a call through it is | |
| 10 | 10 | //! checked by `PyType::__new__` before it reaches the slot. | |
| 11 | 11 | ||
| 12 | - use crate::object::PyTypeObject; | ||
| 13 | - use core::ffi::{c_int, c_void}; | ||
| 14 | - use core::ptr; | ||
| 12 | + use core::ffi::c_int; | ||
| 15 | 13 | use rustpython_vm::builtins::PyType; | |
| 16 | 14 | use rustpython_vm::function::PyMethodFlags; | |
| 17 | 15 | 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 | |||
| 42 | 40 | Ok(()) | |
| 43 | 41 | } | |
| 44 | 42 | ||
| 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 | - | ||
| 64 | 43 | #[cfg(test)] | |
| 65 | 44 | mod tests { | |
| 66 | 45 | use super::*; | |
| 67 | - use crate::PyObject; | ||
| 46 | + use crate::{PyObject, object::{PyType_GetSlot, PyTypeObject}}; | ||
| 47 | + use core::ffi::c_void; | ||
| 68 | 48 | use pyo3::Python; | |
| 69 | 49 | use rustpython_vm::builtins::{PyStrRef, PyTuple, PyTypeRef}; | |
| 70 | 50 | use rustpython_vm::function::{FuncArgs, KwArgs}; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments