Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
18 changes: 18 additions & 0 deletions crates/vm/src/builtins/bool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,26 @@ impl Representable for PyBool {
}
}

fn vectorcall_bool(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
(zelf.slots.new.load().unwrap())(zelf.to_owned(), func_args, vm)
}

pub(crate) fn init(context: &'static Context) {
PyBool::extend_class(context, context.types.bool_type);
context
.types
.bool_type
.slots
.vectorcall
.store(Some(vectorcall_bool));
}

// pub fn not(vm: &VirtualMachine, obj: &PyObject) -> PyResult<bool> {
Expand Down
23 changes: 22 additions & 1 deletion crates/vm/src/builtins/bytearray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ use crate::{
},
convert::{ToPyObject, ToPyResult},
function::{
ArgBytesLike, ArgIterable, ArgSize, Either, OptionalArg, OptionalOption, PyComparisonValue,
ArgBytesLike, ArgIterable, ArgSize, Either, FuncArgs, OptionalArg, OptionalOption,
PyComparisonValue,
},
protocol::{
BufferDescriptor, BufferMethods, BufferResizeGuard, PyBuffer, PyIterReturn,
Expand Down Expand Up @@ -66,9 +67,29 @@ impl PyPayload for PyByteArray {
}
}

fn vectorcall_bytearray(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let obj = PyByteArray::default().into_ref_with_type(vm, zelf.to_owned())?;
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
PyByteArray::slot_init(obj.clone().into(), func_args, vm)?;
Ok(obj.into())
}

/// Fill bytearray class methods dictionary.
pub(crate) fn init(context: &'static Context) {
PyByteArray::extend_class(context, context.types.bytearray_type);
context
.types
.bytearray_type
.slots
.vectorcall
.store(Some(vectorcall_bytearray));
PyByteArrayIterator::extend_class(context, context.types.bytearray_iterator_type);
}

Expand Down
18 changes: 18 additions & 0 deletions crates/vm/src/builtins/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,27 @@ impl PyPayload for PyBytes {
}
}

fn vectorcall_bytes(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
(zelf.slots.new.load().unwrap())(zelf.to_owned(), func_args, vm)
}

pub(crate) fn init(context: &'static Context) {
PyBytes::extend_class(context, context.types.bytes_type);
PyBytesIterator::extend_class(context, context.types.bytes_iterator_type);
context
.types
.bytes_type
.slots
.vectorcall
.store(Some(vectorcall_bytes));
}

impl Constructor for PyBytes {
Expand Down
18 changes: 18 additions & 0 deletions crates/vm/src/builtins/complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,26 @@ impl PyObjectRef {
}
}

fn vectorcall_complex(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
(zelf.slots.new.load().unwrap())(zelf.to_owned(), func_args, vm)
}

pub fn init(context: &'static Context) {
PyComplex::extend_class(context, context.types.complex_type);
context
.types
.complex_type
.slots
.vectorcall
.store(Some(vectorcall_complex));
}

fn to_op_complex(value: &PyObject, vm: &VirtualMachine) -> PyResult<Option<Complex64>> {
Expand Down
24 changes: 23 additions & 1 deletion crates/vm/src/builtins/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ use crate::{
class::{PyClassDef, PyClassImpl},
common::ascii,
dict_inner::{self, DictKey},
function::{ArgIterable, KwArgs, OptionalArg, PyArithmeticValue::*, PyComparisonValue},
function::{
ArgIterable, FuncArgs, KwArgs, OptionalArg, PyArithmeticValue::*, PyComparisonValue,
},
iter::PyExactSizeIterator,
protocol::{PyIterIter, PyIterReturn, PyMappingMethods, PyNumberMethods, PySequenceMethods},
recursion::ReprGuard,
Expand Down Expand Up @@ -1433,8 +1435,28 @@ fn set_inner_number_or(a: &PyObject, b: &PyObject, vm: &VirtualMachine) -> PyRes
set_inner_number_op(a, b, |a, b| a.union(b, vm), vm)
}

fn vectorcall_dict(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let obj = PyDict::default().into_ref_with_type(vm, zelf.to_owned())?;
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
PyDict::slot_init(obj.clone().into(), func_args, vm)?;
Ok(obj.into())
}

pub(crate) fn init(context: &'static Context) {
PyDict::extend_class(context, context.types.dict_type);
context
.types
.dict_type
.slots
.vectorcall
.store(Some(vectorcall_dict));
PyDictKeys::extend_class(context, context.types.dict_keys_type);
PyDictKeyIterator::extend_class(context, context.types.dict_keyiterator_type);
PyDictReverseKeyIterator::extend_class(context, context.types.dict_reversekeyiterator_type);
Expand Down
13 changes: 13 additions & 0 deletions crates/vm/src/builtins/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,20 @@ pub(crate) fn get_value(obj: &PyObject) -> f64 {
obj.downcast_ref::<PyFloat>().unwrap().value
}

fn vectorcall_float(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
(zelf.slots.new.load().unwrap())(zelf.to_owned(), func_args, vm)
}

#[rustfmt::skip] // to avoid line splitting
pub fn init(context: &'static Context) {
PyFloat::extend_class(context, context.types.float_type);
context.types.float_type.slots.vectorcall.store(Some(vectorcall_float));
}
18 changes: 18 additions & 0 deletions crates/vm/src/builtins/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,24 @@ pub fn try_to_float(int: &BigInt, vm: &VirtualMachine) -> PyResult<f64> {
.ok_or_else(|| vm.new_overflow_error("int too large to convert to float"))
}

fn vectorcall_int(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
(zelf.slots.new.load().unwrap())(zelf.to_owned(), func_args, vm)
}

pub(crate) fn init(context: &'static Context) {
PyInt::extend_class(context, context.types.int_type);
context
.types
.int_type
.slots
.vectorcall
.store(Some(vectorcall_int));
}
15 changes: 15 additions & 0 deletions crates/vm/src/builtins/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -768,9 +768,24 @@ impl IterNext for PyListReverseIterator {
}
}

fn vectorcall_list(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let obj = PyList::default().into_ref_with_type(vm, zelf.to_owned())?;
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
PyList::slot_init(obj.clone().into(), func_args, vm)?;
Ok(obj.into())
}

pub fn init(context: &'static Context) {
let list_type = &context.types.list_type;
PyList::extend_class(context, list_type);
list_type.slots.vectorcall.store(Some(vectorcall_list));

PyListIterator::extend_class(context, context.types.list_iterator_type);
PyListReverseIterator::extend_class(context, context.types.list_reverseiterator_type);
Expand Down
40 changes: 40 additions & 0 deletions crates/vm/src/builtins/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1421,8 +1421,48 @@ impl IterNext for PySetIterator {
}
}

fn vectorcall_set(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let obj = PySet::default().into_ref_with_type(vm, zelf.to_owned())?;
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
PySet::slot_init(obj.clone().into(), func_args, vm)?;
Ok(obj.into())
}

fn vectorcall_frozenset(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
(zelf.slots.new.load().unwrap())(zelf.to_owned(), func_args, vm)
}

pub fn init(context: &'static Context) {
PySet::extend_class(context, context.types.set_type);
context
.types
.set_type
.slots
.vectorcall
.store(Some(vectorcall_set));

PyFrozenSet::extend_class(context, context.types.frozenset_type);
context
.types
.frozenset_type
.slots
.vectorcall
.store(Some(vectorcall_frozenset));

PySetIterator::extend_class(context, context.types.set_iterator_type);
}
17 changes: 17 additions & 0 deletions crates/vm/src/builtins/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1782,8 +1782,25 @@ struct ReplaceArgs {
count: isize,
}

fn vectorcall_str(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
(zelf.slots.new.load().unwrap())(zelf.to_owned(), func_args, vm)
}

pub fn init(ctx: &'static Context) {
PyStr::extend_class(ctx, ctx.types.str_type);
ctx.types
.str_type
.slots
.vectorcall
.store(Some(vectorcall_str));

PyStrIterator::extend_class(ctx, ctx.types.str_iterator_type);
}
Expand Down
20 changes: 20 additions & 0 deletions crates/vm/src/builtins/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -695,9 +695,29 @@ impl IterNext for PyTupleIterator {
}
}

fn vectorcall_tuple(
zelf_obj: &PyObject,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult {
let zelf: &Py<PyType> = zelf_obj.downcast_ref().unwrap();
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
// Use the type's own slot_new rather than calling PyTuple::slot_new directly,
// so Rust-level subclasses (e.g. struct sequences) get their custom slot_new called.
(zelf.slots.new.load().unwrap())(zelf.to_owned(), func_args, vm)
}

pub(crate) fn init(context: &'static Context) {
PyTuple::extend_class(context, context.types.tuple_type);
PyTupleIterator::extend_class(context, context.types.tuple_iterator_type);
context
.types
.tuple_type
.slots
.vectorcall
.store(Some(vectorcall_tuple));
}

pub(super) fn tuple_hash(elements: &[PyObjectRef], vm: &VirtualMachine) -> PyResult<PyHash> {
Expand Down
7 changes: 7 additions & 0 deletions crates/vm/src/builtins/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2665,6 +2665,13 @@ fn vectorcall_type(
if nargs == 1 && no_kwargs {
return Ok(args[0].obj_type());
}
} else if zelf.slots.call.load().is_none() {
// Per-type constructor vectorcall for non-callable types (dict, list, int, etc.)
// When slots.call is set, slots.vectorcall is for calling instances (e.g. vectorcall_function),
// not for constructing them, so we must not dispatch it here.
if let Some(type_vc) = zelf.slots.vectorcall.load() {
return type_vc(zelf_obj, args, nargs, kwnames, vm);
}
}

// Fallback: construct FuncArgs and use standard call
Expand Down
Loading
Loading