From 18044abbb611480b6249ea4d7c3cfa5f9a3281c7 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 6 Apr 2023 01:23:36 +0900 Subject: [PATCH 1/2] use interned str for builtin function names --- derive-impl/src/pyclass.rs | 4 ++-- derive-impl/src/pymodule.rs | 2 +- vm/src/builtins/builtin_func.rs | 14 +++++++------- vm/src/builtins/staticmethod.rs | 4 ++-- vm/src/exceptions.rs | 6 +++--- vm/src/macros.rs | 2 +- vm/src/vm/context.rs | 14 +++++++------- wasm/lib/src/wasm_builtins.rs | 4 ++-- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/derive-impl/src/pyclass.rs b/derive-impl/src/pyclass.rs index d74c8e8e43..3e642ef3d2 100644 --- a/derive-impl/src/pyclass.rs +++ b/derive-impl/src/pyclass.rs @@ -629,7 +629,7 @@ where quote_spanned! { ident.span() => class.set_attr( ctx.names.#name_ident, - ctx.make_func_def(#py_name, Self::#ident) + ctx.make_func_def(ctx.intern_str(#py_name), Self::#ident) #doc #build_func .into(), @@ -639,7 +639,7 @@ where quote_spanned! { ident.span() => class.set_str_attr( #py_name, - ctx.make_func_def(#py_name, Self::#ident) + ctx.make_func_def(ctx.intern_str(#py_name), Self::#ident) #doc #build_func, ctx, diff --git a/derive-impl/src/pymodule.rs b/derive-impl/src/pymodule.rs index 14717f6728..47e373b7fe 100644 --- a/derive-impl/src/pymodule.rs +++ b/derive-impl/src/pymodule.rs @@ -334,7 +334,7 @@ impl ModuleItem for FunctionItem { }; let doc = quote!(.with_doc(#doc.to_owned(), &vm.ctx)); let new_func = quote_spanned!(ident.span()=> - vm.ctx.make_func_def(#py_name, #ident) + vm.ctx.make_func_def(vm.ctx.intern_str(#py_name), #ident) #doc .into_function() .with_module(vm.new_pyobj(#module.to_owned())) diff --git a/vm/src/builtins/builtin_func.rs b/vm/src/builtins/builtin_func.rs index 47479fd344..39a5353aa7 100644 --- a/vm/src/builtins/builtin_func.rs +++ b/vm/src/builtins/builtin_func.rs @@ -1,4 +1,4 @@ -use super::{type_, PyClassMethod, PyStaticMethod, PyStr, PyStrRef, PyType}; +use super::{type_, PyClassMethod, PyStaticMethod, PyStr, PyStrInterned, PyStrRef, PyType}; use crate::{ builtins::PyBoundMethod, class::PyClassImpl, @@ -10,12 +10,12 @@ use std::fmt; pub struct PyNativeFuncDef { pub func: PyNativeFunc, - pub name: PyStrRef, + pub name: &'static PyStrInterned, pub doc: Option, } impl PyNativeFuncDef { - pub fn new(func: PyNativeFunc, name: PyStrRef) -> Self { + pub fn new(func: PyNativeFunc, name: &'static PyStrInterned) -> Self { Self { func, name, @@ -122,7 +122,7 @@ impl PyBuiltinFunction { } #[pygetset(magic)] fn name(&self) -> PyStrRef { - self.value.name.clone() + self.value.name.to_owned() } #[pygetset(magic)] fn qualname(&self) -> PyStrRef { @@ -217,7 +217,7 @@ impl Callable for PyBuiltinMethod { impl PyBuiltinMethod { pub fn new_ref( - name: impl Into, + name: &'static PyStrInterned, class: &'static Py, f: F, ctx: &Context, @@ -236,7 +236,7 @@ impl PyBuiltinMethod { impl PyBuiltinMethod { #[pygetset(magic)] fn name(&self) -> PyStrRef { - self.value.name.clone() + self.value.name.to_owned() } #[pygetset(magic)] fn qualname(&self) -> String { @@ -260,7 +260,7 @@ impl PyBuiltinMethod { ) -> (Option, (Option, PyStrRef)) { let builtins_getattr = vm.builtins.get_attr("getattr", vm).ok(); let classname = vm.builtins.get_attr(&self.class.__name__(vm), vm).ok(); - (builtins_getattr, (classname, self.value.name.clone())) + (builtins_getattr, (classname, self.value.name.to_owned())) } } diff --git a/vm/src/builtins/staticmethod.rs b/vm/src/builtins/staticmethod.rs index 187648e2c0..d9de4be692 100644 --- a/vm/src/builtins/staticmethod.rs +++ b/vm/src/builtins/staticmethod.rs @@ -1,4 +1,4 @@ -use super::{PyStr, PyType, PyTypeRef}; +use super::{PyStr, PyStrInterned, PyType, PyTypeRef}; use crate::{ builtins::builtin_func::PyBuiltinMethod, class::PyClassImpl, @@ -75,7 +75,7 @@ impl PyStaticMethod { impl PyStaticMethod { pub fn new_builtin_ref( - name: impl Into, + name: &'static PyStrInterned, class: &'static Py, f: F, ctx: &Context, diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index d095a9569d..f4e2e99b58 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -753,7 +753,7 @@ impl ExceptionZoo { extend_exception!(PyLookupError, ctx, excs.lookup_error); extend_exception!(PyIndexError, ctx, excs.index_error); extend_exception!(PyKeyError, ctx, excs.key_error, { - "__str__" => ctx.new_method("__str__", excs.key_error, key_error_str), + "__str__" => ctx.new_method(identifier!(ctx, __str__), excs.key_error, key_error_str), }); extend_exception!(PyMemoryError, ctx, excs.memory_error); @@ -786,8 +786,8 @@ impl ExceptionZoo { "filename" => ctx.none(), // second exception filename "filename2" => ctx.none(), - "__str__" => ctx.new_method("__str__", excs.os_error, os_error_str), - "__reduce__" => ctx.new_method("__reduce__", excs.os_error, os_error_reduce), + "__str__" => ctx.new_method(identifier!(ctx, __str__), excs.os_error, os_error_str), + "__reduce__" => ctx.new_method(identifier!(ctx, __reduce__), excs.os_error, os_error_reduce), }); // TODO: this isn't really accurate #[cfg(windows)] diff --git a/vm/src/macros.rs b/vm/src/macros.rs index d2c4102994..5f990d1a4a 100644 --- a/vm/src/macros.rs +++ b/vm/src/macros.rs @@ -219,7 +219,7 @@ macro_rules! named_function { let ctx: &$crate::Context = &$ctx; $crate::__exports::paste::expr! { ctx.make_func_def( - stringify!($func), + ctx.intern_str(stringify!($func)), [<$module _ $func>], ) .into_function() diff --git a/vm/src/vm/context.rs b/vm/src/vm/context.rs index 3fdbb17266..0ca248eb5e 100644 --- a/vm/src/vm/context.rs +++ b/vm/src/vm/context.rs @@ -288,8 +288,7 @@ impl Context { let names = unsafe { ConstName::new(&string_pool, &types.str_type.to_owned()) }; let slot_new_wrapper = create_object( - PyNativeFuncDef::new(PyType::__new__.into_func(), names.__new__.to_owned()) - .into_function(), + PyNativeFuncDef::new(PyType::__new__.into_func(), names.__new__).into_function(), types.builtin_function_or_method_type, ) .into(); @@ -491,11 +490,11 @@ impl Context { } #[inline] - pub fn make_func_def(&self, name: impl Into, f: F) -> PyNativeFuncDef + pub fn make_func_def(&self, name: &'static PyStrInterned, f: F) -> PyNativeFuncDef where F: IntoPyNativeFunc, { - PyNativeFuncDef::new(f.into_func(), PyStr::new_ref(name, self)) + PyNativeFuncDef::new(f.into_func(), name) } #[inline] @@ -531,16 +530,17 @@ impl Context { } // #[deprecated] - pub fn new_function(&self, name: impl Into, f: F) -> PyRef + pub fn new_function(&self, name: &str, f: F) -> PyRef where F: IntoPyNativeFunc, { - self.make_func_def(name, f).build_function(self) + self.make_func_def(self.intern_str(name), f) + .build_function(self) } pub fn new_method( &self, - name: impl Into, + name: &'static PyStrInterned, class: &'static Py, f: F, ) -> PyRef diff --git a/wasm/lib/src/wasm_builtins.rs b/wasm/lib/src/wasm_builtins.rs index 6cf86ea570..216360c1c9 100644 --- a/wasm/lib/src/wasm_builtins.rs +++ b/wasm/lib/src/wasm_builtins.rs @@ -30,13 +30,13 @@ pub fn make_stdout_object( {} )); let write_method = ctx.new_method( - "write", + ctx.intern_str("write"), cls, move |_self: PyObjectRef, data: PyStrRef, vm: &VirtualMachine| -> PyResult<()> { write_f(data.as_str(), vm) }, ); - let flush_method = ctx.new_method("flush", cls, |_self: PyObjectRef| {}); + let flush_method = ctx.new_method(ctx.intern_str("flush"), cls, |_self: PyObjectRef| {}); extend_class!(ctx, cls, { "write" => write_method, "flush" => flush_method, From 798b3bc15856557cf11c7c5805570affd21033e8 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 6 Apr 2023 01:42:59 +0900 Subject: [PATCH 2/2] expose slot_new_wrapper as its base type --- vm/src/class.rs | 12 +++++++----- vm/src/vm/context.rs | 5 ++--- wasm/lib/src/convert.rs | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/vm/src/class.rs b/vm/src/class.rs index e52ca58da8..eef9d94523 100644 --- a/vm/src/class.rs +++ b/vm/src/class.rs @@ -3,7 +3,7 @@ use crate::{ builtins::{PyBaseObject, PyBoundMethod, PyType, PyTypeRef}, identifier, - object::{Py, PyObjectRef}, + object::Py, types::{hash_not_implemented, PyTypeFlags, PyTypeSlots}, vm::Context, }; @@ -99,10 +99,12 @@ pub trait PyClassImpl: PyClassDef { ); } if class.slots.new.load().is_some() { - let bound: PyObjectRef = - PyBoundMethod::new_ref(class.to_owned().into(), ctx.slot_new_wrapper.clone(), ctx) - .into(); - class.set_attr(identifier!(ctx, __new__), bound); + let bound = PyBoundMethod::new_ref( + class.to_owned().into(), + ctx.slot_new_wrapper.clone().into(), + ctx, + ); + class.set_attr(identifier!(ctx, __new__), bound.into()); } if class.slots.hash.load().map_or(0, |h| h as usize) == hash_not_implemented as usize { diff --git a/vm/src/vm/context.rs b/vm/src/vm/context.rs index 0ca248eb5e..163acb3ef5 100644 --- a/vm/src/vm/context.rs +++ b/vm/src/vm/context.rs @@ -45,7 +45,7 @@ pub struct Context { pub int_cache_pool: Vec, // there should only be exact objects of str in here, no non-str objects and no subclasses pub(crate) string_pool: StringPool, - pub(crate) slot_new_wrapper: PyObjectRef, + pub(crate) slot_new_wrapper: PyRef, pub names: ConstName, } @@ -290,8 +290,7 @@ impl Context { let slot_new_wrapper = create_object( PyNativeFuncDef::new(PyType::__new__.into_func(), names.__new__).into_function(), types.builtin_function_or_method_type, - ) - .into(); + ); let empty_str = unsafe { string_pool.intern("", types.str_type.to_owned()) }.to_owned(); let empty_bytes = create_object(PyBytes::from(Vec::new()), types.bytes_type); diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs index 75b944cba8..f91f153f2e 100644 --- a/wasm/lib/src/convert.rs +++ b/wasm/lib/src/convert.rs @@ -216,7 +216,7 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef { let func = js_sys::Function::from(js_val); vm.ctx .new_function( - String::from(func.name()), + String::from(func.name()).as_str(), move |args: FuncArgs, vm: &VirtualMachine| -> PyResult { let this = Object::new(); for (k, v) in args.kwargs {