diff --git a/derive/src/pystructseq.rs b/derive/src/pystructseq.rs index 236f10efdd..0da5fa3831 100644 --- a/derive/src/pystructseq.rs +++ b/derive/src/pystructseq.rs @@ -36,7 +36,7 @@ pub(crate) fn impl_pystruct_sequence( self.#field_names, vm, )),*]; - ::rustpython_vm::builtins::tuple::PyTuple::_new(items.into_boxed_slice()) + ::rustpython_vm::builtins::tuple::PyTuple::new_unchecked(items.into_boxed_slice()) } } impl ::rustpython_vm::IntoPyObject for #ty { diff --git a/vm/src/builtins/memory.rs b/vm/src/builtins/memory.rs index 4e3f23218d..eaf8539c77 100644 --- a/vm/src/builtins/memory.rs +++ b/vm/src/builtins/memory.rs @@ -11,7 +11,7 @@ use crate::{ protocol::{BufferInternal, BufferOptions, PyBuffer}, sliceable::{convert_slice, wrap_index, SequenceIndex}, slots::{AsBuffer, Comparable, Hashable, PyComparisonOp, SlotConstructor}, - stdlib::pystruct::_struct::FormatSpec, + stdlib::pystruct::FormatSpec, utils::Either, IdProtocol, IntoPyObject, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromBorrowedObject, TryFromObject, TypeProtocol, VirtualMachine, diff --git a/vm/src/builtins/mod.rs b/vm/src/builtins/mod.rs index 29d96cd0e6..9dc9f94ba9 100644 --- a/vm/src/builtins/mod.rs +++ b/vm/src/builtins/mod.rs @@ -63,7 +63,7 @@ pub use pytype::{PyType, PyTypeRef}; pub(crate) mod range; pub use range::PyRange; pub(crate) mod set; -pub use set::PySet; +pub use set::{PyFrozenSet, PySet}; pub(crate) mod singletons; pub use singletons::{PyNone, PyNotImplemented}; pub(crate) mod slice; @@ -84,7 +84,4 @@ pub use zip::PyZip; pub use float::try_to_bigint as try_f64_to_bigint; pub use int::try_to_float as try_bigint_to_f64; -mod make_module; -pub use make_module::{ascii, make_module, print}; - pub use crate::exceptions::types::*; diff --git a/vm/src/builtins/pystr.rs b/vm/src/builtins/pystr.rs index e29939296b..38be33ecde 100644 --- a/vm/src/builtins/pystr.rs +++ b/vm/src/builtins/pystr.rs @@ -477,7 +477,7 @@ impl PyStr { } #[pymethod(magic)] - pub(crate) fn repr(&self, vm: &VirtualMachine) -> PyResult<String> { + pub fn repr(&self, vm: &VirtualMachine) -> PyResult<String> { let in_len = self.byte_len(); let mut out_len = 0usize; // let mut max = 127; diff --git a/vm/src/builtins/pytype.rs b/vm/src/builtins/pytype.rs index 6d494ca5d3..71a27a327a 100644 --- a/vm/src/builtins/pytype.rs +++ b/vm/src/builtins/pytype.rs @@ -302,7 +302,7 @@ impl PyType { #[pyproperty(name = "__mro__")] fn get_mro(zelf: PyRef<Self>) -> PyTuple { let elements: Vec<PyObjectRef> = zelf.iter_mro().map(|x| x.as_object().clone()).collect(); - PyTuple::_new(elements.into_boxed_slice()) + PyTuple::new_unchecked(elements.into_boxed_slice()) } #[pyproperty(magic)] diff --git a/vm/src/builtins/tuple.rs b/vm/src/builtins/tuple.rs index c10f30420b..65666cbf2e 100644 --- a/vm/src/builtins/tuple.rs +++ b/vm/src/builtins/tuple.rs @@ -115,7 +115,7 @@ impl PyTuple { /// Creating a new tuple with given boxed slice. /// NOTE: for usual case, you probably want to use PyTupleRef::with_elements. /// Calling this function implies trying micro optimization for non-zero-sized tuple. - pub(crate) fn _new(elements: Box<[PyObjectRef]>) -> Self { + pub fn new_unchecked(elements: Box<[PyObjectRef]>) -> Self { Self { elements } } diff --git a/vm/src/format.rs b/vm/src/format.rs index ddbda3ee99..30eb286393 100644 --- a/vm/src/format.rs +++ b/vm/src/format.rs @@ -1,8 +1,9 @@ use crate::{ - builtins::{self, PyBaseExceptionRef, PyStrRef}, + builtins::{PyBaseExceptionRef, PyStrRef}, common::float_ops, exceptions::IntoPyException, function::FuncArgs, + stdlib::builtins, ItemProtocol, PyObjectRef, PyResult, TypeProtocol, VirtualMachine, }; use itertools::{Itertools, PeekingNext}; diff --git a/vm/src/frame.rs b/vm/src/frame.rs index 9c7c28dab3..2d77e3eae6 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -1,8 +1,6 @@ use crate::common::{boxvec::BoxVec, lock::PyMutex}; use crate::{ - builtins::PyBaseExceptionRef, builtins::{ - self, asyncgenerator::PyAsyncGenWrappedValue, coroutine::PyCoroutine, function::{PyCell, PyCellRef, PyFunction}, @@ -10,7 +8,7 @@ use crate::{ list, pystr, set, traceback::PyTraceback, tuple::{PyTuple, PyTupleTyped}, - PyCode, PyDict, PyDictRef, PySlice, PyStr, PyStrRef, PyTypeRef, + PyBaseExceptionRef, PyCode, PyDict, PyDictRef, PySlice, PyStr, PyStrRef, PyTypeRef, }, bytecode, coroutine::Coro, @@ -20,6 +18,7 @@ use crate::{ protocol::PyIter, scope::Scope, slots::PyComparisonOp, + stdlib::builtins, IdProtocol, ItemProtocol, PyMethod, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, VirtualMachine, }; diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 5b089dafea..e0ee8068e9 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -60,7 +60,7 @@ mod frozen; pub mod function; pub mod import; pub mod iterator; -mod protocol; +pub mod protocol; pub mod py_io; pub mod py_serde; mod pyobject; @@ -69,12 +69,12 @@ pub mod readline; pub mod scope; mod sequence; mod signal; -mod sliceable; +pub mod sliceable; pub mod slots; pub mod stdlib; pub mod types; pub mod utils; -mod version; +pub mod version; mod vm; // pub use self::Executor; diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index fe2ef73971..0eabfe0d76 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -106,7 +106,7 @@ impl PyContext { let false_value = create_object(PyInt::from(0), &types.bool_type); let empty_tuple = create_object( - PyTuple::_new(Vec::new().into_boxed_slice()), + PyTuple::new_unchecked(Vec::new().into_boxed_slice()), &types.tuple_type, ); let empty_frozenset = diff --git a/vm/src/sliceable.rs b/vm/src/sliceable.rs index b366d9b4bf..0eb5fd1bea 100644 --- a/vm/src/sliceable.rs +++ b/vm/src/sliceable.rs @@ -404,7 +404,7 @@ pub(crate) fn wrap_index(p: isize, len: usize) -> Option<usize> { } // return pos is in range [0, len] inclusive -pub(crate) fn saturate_index(p: isize, len: usize) -> usize { +pub fn saturate_index(p: isize, len: usize) -> usize { let mut p = p; let len = len.to_isize().unwrap(); if p < 0 { diff --git a/vm/src/builtins/make_module.rs b/vm/src/stdlib/builtins.rs similarity index 99% rename from vm/src/builtins/make_module.rs rename to vm/src/stdlib/builtins.rs index 964da58e6c..8edfea6189 100644 --- a/vm/src/builtins/make_module.rs +++ b/vm/src/stdlib/builtins.rs @@ -6,8 +6,8 @@ use crate::{PyObjectRef, VirtualMachine}; /// Built-in functions, exceptions, and other objects. /// /// Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices. -#[pymodule(name = "builtins")] -mod decl { +#[pymodule] +mod builtins { use crate::builtins::{ enumerate::PyReverseSequenceIterator, function::{PyCellRef, PyFunctionRef}, @@ -891,12 +891,12 @@ mod decl { } } -pub use decl::{ascii, print}; +pub use builtins::{ascii, print}; pub fn make_module(vm: &VirtualMachine, module: PyObjectRef) { let ctx = &vm.ctx; - decl::extend_module(vm, &module); + builtins::extend_module(vm, &module); let debug_mode: bool = vm.state.settings.optimize == 0; extend_module!(vm, module, { diff --git a/vm/src/stdlib/fcntl.rs b/vm/src/stdlib/fcntl.rs index 5a0b0a21b6..f0302dda83 100644 --- a/vm/src/stdlib/fcntl.rs +++ b/vm/src/stdlib/fcntl.rs @@ -3,7 +3,7 @@ pub(crate) use fcntl::make_module; #[pymodule] mod fcntl { use crate::{ - builtins::int, + builtins::PyIntRef, function::{ArgMemoryBuffer, ArgStrOrBytesLike, OptionalArg}, stdlib::{io, os}, utils::Either, @@ -25,7 +25,7 @@ mod fcntl { fn fcntl( io::Fildes(fd): io::Fildes, cmd: i32, - arg: OptionalArg<Either<ArgStrOrBytesLike, int::PyIntRef>>, + arg: OptionalArg<Either<ArgStrOrBytesLike, PyIntRef>>, vm: &VirtualMachine, ) -> PyResult { let int = match arg { diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 548b652058..ba705f7044 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -35,7 +35,7 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef { #[allow(unused)] #[derive(Copy, Clone)] #[repr(transparent)] -pub(crate) struct Fildes(pub i32); +pub struct Fildes(pub i32); impl TryFromObject for Fildes { fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> { diff --git a/vm/src/stdlib/mod.rs b/vm/src/stdlib/mod.rs index 8861c444ac..f2d73cc6b8 100644 --- a/vm/src/stdlib/mod.rs +++ b/vm/src/stdlib/mod.rs @@ -4,6 +4,7 @@ pub(crate) mod ast; mod atexit; mod binascii; mod bisect; +pub mod builtins; mod cmath; mod codecs; mod collections; diff --git a/vm/src/stdlib/nt.rs b/vm/src/stdlib/nt.rs index c55a42f590..3c08219d81 100644 --- a/vm/src/stdlib/nt.rs +++ b/vm/src/stdlib/nt.rs @@ -427,3 +427,11 @@ macro_rules! suppress_iph { ret }}; } + +pub fn init_winsock() { + static WSA_INIT: parking_lot::Once = parking_lot::Once::new(); + WSA_INIT.call_once(|| unsafe { + let mut wsa_data = std::mem::MaybeUninit::uninit(); + let _ = winapi::um::winsock2::WSAStartup(0x0101, wsa_data.as_mut_ptr()); + }) +} diff --git a/vm/src/stdlib/posix.rs b/vm/src/stdlib/posix.rs index 90e3cc7f24..15961965a7 100644 --- a/vm/src/stdlib/posix.rs +++ b/vm/src/stdlib/posix.rs @@ -2,7 +2,7 @@ use crate::{PyObjectRef, PyResult, VirtualMachine}; use nix; use std::os::unix::io::RawFd; -pub(crate) fn raw_set_inheritable(fd: RawFd, inheritable: bool) -> nix::Result<()> { +pub fn raw_set_inheritable(fd: RawFd, inheritable: bool) -> nix::Result<()> { use nix::fcntl; let flags = fcntl::FdFlag::from_bits_truncate(fcntl::fcntl(fd, fcntl::FcntlArg::F_GETFD)?); let mut new_flags = flags; diff --git a/vm/src/stdlib/pystruct.rs b/vm/src/stdlib/pystruct.rs index a85a0f3f7d..085f73f92d 100644 --- a/vm/src/stdlib/pystruct.rs +++ b/vm/src/stdlib/pystruct.rs @@ -966,4 +966,4 @@ pub(crate) mod _struct { } } -pub(crate) use _struct::make_module; +pub(crate) use _struct::{make_module, FormatSpec}; diff --git a/vm/src/stdlib/select.rs b/vm/src/stdlib/select.rs index a0411ca049..33a2a15e34 100644 --- a/vm/src/stdlib/select.rs +++ b/vm/src/stdlib/select.rs @@ -2,7 +2,9 @@ use crate::{PyObjectRef, PyResult, TryFromBorrowedObject, TryFromObject, Virtual use std::{io, mem}; pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef { - super::socket::init_winsock(); + #[cfg(windows)] + super::nt::init_winsock(); + #[cfg(unix)] { use crate::PyClassImpl; @@ -171,7 +173,7 @@ mod decl { return Err(vm.new_value_error("timeout must be positive".to_owned())); } } - let deadline = timeout.map(|s| time::get_time(vm).unwrap() + s); + let deadline = timeout.map(|s| time::time(vm).unwrap() + s); let seq2set = |list| -> PyResult<(Vec<Selectable>, FdSet)> { let v = vm.extract_elements::<Selectable>(list)?; @@ -210,7 +212,7 @@ mod decl { vm.check_signals()?; if let Some(ref mut timeout) = timeout { - *timeout = deadline.unwrap() - time::get_time(vm).unwrap(); + *timeout = deadline.unwrap() - time::time(vm).unwrap(); if *timeout < 0.0 { r.clear(); w.clear(); diff --git a/vm/src/stdlib/signal.rs b/vm/src/stdlib/signal.rs index 0eff5d1584..c696012d41 100644 --- a/vm/src/stdlib/signal.rs +++ b/vm/src/stdlib/signal.rs @@ -192,7 +192,7 @@ pub(crate) mod _signal { #[cfg(windows)] let is_socket = if fd != INVALID_WAKEUP { - crate::stdlib::socket::init_winsock(); + crate::stdlib::nt::init_winsock(); let mut res = 0i32; let mut res_size = std::mem::size_of::<i32>() as i32; let res = unsafe { diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index 5dd94b1368..63b8778960 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -1818,7 +1818,8 @@ rustpython_common::static_cell! { } pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { - init_winsock(); + #[cfg(windows)] + super::nt::init_winsock(); let ctx = &vm.ctx; let socket_timeout = TIMEOUT_ERROR @@ -1978,14 +1979,3 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: &PyObjectRef) { "sethostname" => named_function!(ctx, _socket, sethostname), }); } - -pub fn init_winsock() { - #[cfg(windows)] - { - static WSA_INIT: parking_lot::Once = parking_lot::Once::new(); - WSA_INIT.call_once(|| unsafe { - let mut wsa_data = std::mem::MaybeUninit::uninit(); - let _ = winapi::um::winsock2::WSAStartup(0x0101, wsa_data.as_mut_ptr()); - }) - } -} diff --git a/vm/src/stdlib/sys.rs b/vm/src/stdlib/sys.rs index 11cd2d17db..fda309a85d 100644 --- a/vm/src/stdlib/sys.rs +++ b/vm/src/stdlib/sys.rs @@ -1,18 +1,20 @@ -use num_traits::ToPrimitive; -use std::{env, mem, path}; - -use crate::builtins::{PyStr, PyStrRef, PyTypeRef}; use crate::common::{ ascii, hash::{PyHash, PyUHash}, }; -use crate::frame::FrameRef; -use crate::function::{FuncArgs, OptionalArg, PosArgs}; -use crate::vm::{PySettings, VirtualMachine}; -use crate::{builtins, exceptions, py_io, version}; use crate::{ + builtins::{PyStr, PyStrRef, PyTypeRef}, + exceptions, + frame::FrameRef, + function::{FuncArgs, OptionalArg, PosArgs}, + py_io, + stdlib::builtins, + version, + vm::{PySettings, VirtualMachine}, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRefExact, PyResult, PyStructSequence, }; +use num_traits::ToPrimitive; +use std::{env, mem, path}; /* * The magic sys module. diff --git a/vm/src/stdlib/time.rs b/vm/src/stdlib/time.rs index 801c164b35..54a7409c45 100644 --- a/vm/src/stdlib/time.rs +++ b/vm/src/stdlib/time.rs @@ -2,7 +2,9 @@ // See also: // https://docs.python.org/3/library/time.html -use crate::{PyObjectRef, PyResult, VirtualMachine}; +use crate::{PyObjectRef, VirtualMachine}; + +pub use time::*; pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef { let module = time::make_module(vm); @@ -14,32 +16,6 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef { module } -#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))] -pub(crate) fn get_time(vm: &VirtualMachine) -> PyResult<f64> { - Ok(duration_since_system_now(vm)?.as_secs_f64()) -} - -#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] -pub(crate) fn get_time(_vm: &VirtualMachine) -> PyResult<f64> { - use wasm_bindgen::prelude::*; - #[wasm_bindgen] - extern "C" { - type Date; - #[wasm_bindgen(static_method_of = Date)] - fn now() -> f64; - } - // Date.now returns unix time in milliseconds, we want it in seconds - Ok(Date::now() / 1000.0) -} - -fn duration_since_system_now(vm: &VirtualMachine) -> PyResult<std::time::Duration> { - use std::time::{SystemTime, UNIX_EPOCH}; - - SystemTime::now() - .duration_since(UNIX_EPOCH) - .map_err(|e| vm.new_value_error(format!("Time error: {:?}", e))) -} - #[pymodule(name = "time")] mod time { use crate::{ @@ -70,6 +46,14 @@ mod time { #[allow(dead_code)] pub(super) const NS_TO_US: i64 = 1000; + fn duration_since_system_now(vm: &VirtualMachine) -> PyResult<std::time::Duration> { + use std::time::{SystemTime, UNIX_EPOCH}; + + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map_err(|e| vm.new_value_error(format!("Time error: {:?}", e))) + } + #[cfg(not(unix))] #[pyfunction] fn sleep(dur: std::time::Duration) { @@ -79,19 +63,37 @@ mod time { #[cfg(not(target_os = "wasi"))] #[pyfunction] fn time_ns(vm: &VirtualMachine) -> PyResult<u64> { - Ok(super::duration_since_system_now(vm)?.as_nanos() as u64) + Ok(duration_since_system_now(vm)?.as_nanos() as u64) } #[pyfunction(name = "perf_counter")] // TODO: fix #[pyfunction] - fn time(vm: &VirtualMachine) -> PyResult<f64> { - super::get_time(vm) + pub fn time(vm: &VirtualMachine) -> PyResult<f64> { + _time(vm) + } + + #[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))] + fn _time(vm: &VirtualMachine) -> PyResult<f64> { + Ok(duration_since_system_now(vm)?.as_secs_f64()) + } + + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] + fn _time(_vm: &VirtualMachine) -> PyResult<f64> { + use wasm_bindgen::prelude::*; + #[wasm_bindgen] + extern "C" { + type Date; + #[wasm_bindgen(static_method_of = Date)] + fn now() -> f64; + } + // Date.now returns unix time in milliseconds, we want it in seconds + Ok(Date::now() / 1000.0) } #[pyfunction] fn monotonic(vm: &VirtualMachine) -> PyResult<f64> { // TODO: implement proper monotonic time! - Ok(super::duration_since_system_now(vm)?.as_secs_f64()) + Ok(duration_since_system_now(vm)?.as_secs_f64()) } fn pyobj_to_naive_date_time( diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 45361bfb99..9aff2a72e0 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -8,13 +8,12 @@ use crate::compile::{self, CompileError, CompileErrorType, CompileOpts}; use crate::{ builtins::{ - self, code::{self, PyCode}, module, object, tuple::{PyTuple, PyTupleRef, PyTupleTyped}, - PyDictRef, PyInt, PyIntRef, PyList, PyModule, PyStr, PyStrRef, PyTypeRef, + PyBaseException, PyBaseExceptionRef, PyDictRef, PyInt, PyIntRef, PyList, PyModule, PyStr, + PyStrRef, PyTypeRef, }, - builtins::{PyBaseException, PyBaseExceptionRef}, bytecode, codecs::CodecsRegistry, common::{ascii, hash::HashSecret, lock::PyMutex, rc::PyRc}, @@ -325,7 +324,7 @@ impl VirtualMachine { panic!("Double Initialize Error"); } - builtins::make_module(self, self.builtins.clone()); + stdlib::builtins::make_module(self, self.builtins.clone()); stdlib::sys::make_module(self, self.sys_module.clone(), self.builtins.clone()); let mut inner_init = || -> PyResult<()> {