Skip to content

Commit c8eda37

Browse files
committed
Eliminate ctx.set_attr.
1 parent 25c17b4 commit c8eda37

File tree

23 files changed

+129
-126
lines changed

23 files changed

+129
-126
lines changed

derive/src/pyclass.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ pub fn impl_pyimpl(attr: AttributeArgs, item: Item) -> TokenStream2 {
118118
}| {
119119
let constructor_fn = kind.to_ctx_constructor_fn();
120120
quote! {
121-
ctx.set_attr(class, #py_name, ctx.#constructor_fn(Self::#fn_name));
121+
class.set_str_attr(#py_name, ctx.#constructor_fn(Self::#fn_name));
122122
}
123123
},
124124
);

vm/src/builtins.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,12 @@ fn builtin_import(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
669669
// builtin_vars
670670

671671
pub fn make_module(ctx: &PyContext) -> PyObjectRef {
672-
let py_mod = py_module!(ctx, "__builtins__", {
672+
#[cfg(target_arch = "wasm32")]
673+
let open = ctx.none();
674+
#[cfg(not(target_arch = "wasm32"))]
675+
let open = ctx.new_rustfunc(io_open);
676+
677+
py_module!(ctx, "__builtins__", {
673678
//set __name__ fixes: https://github.com/RustPython/RustPython/issues/146
674679
"__name__" => ctx.new_str(String::from("__main__")),
675680

@@ -715,6 +720,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
715720
"min" => ctx.new_rustfunc(builtin_min),
716721
"object" => ctx.object(),
717722
"oct" => ctx.new_rustfunc(builtin_oct),
723+
"open" => open,
718724
"ord" => ctx.new_rustfunc(builtin_ord),
719725
"next" => ctx.new_rustfunc(builtin_next),
720726
"pow" => ctx.new_rustfunc(builtin_pow),
@@ -759,12 +765,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
759765
"ZeroDivisionError" => ctx.exceptions.zero_division_error.clone(),
760766
"KeyError" => ctx.exceptions.key_error.clone(),
761767
"OSError" => ctx.exceptions.os_error.clone(),
762-
});
763-
764-
#[cfg(not(target_arch = "wasm32"))]
765-
ctx.set_attr(&py_mod, "open", ctx.new_rustfunc(io_open));
766-
767-
py_mod
768+
})
768769
}
769770

770771
pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResult {
@@ -801,6 +802,6 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
801802
"__call__",
802803
vec![name_arg, bases, namespace.into_object()],
803804
)?;
804-
cells.set_item(&vm.ctx, "__class__", class.clone());
805+
cells.set_item("__class__", class.clone(), vm);
805806
Ok(class)
806807
}

vm/src/exceptions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ fn exception_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
1313
vm.new_str("No msg".to_string())
1414
};
1515
let traceback = vm.ctx.new_list(Vec::new());
16-
vm.ctx.set_attr(&zelf, "msg", msg);
17-
vm.ctx.set_attr(&zelf, "__traceback__", traceback);
16+
vm.set_attr(&zelf, "msg", msg)?;
17+
vm.set_attr(&zelf, "__traceback__", traceback)?;
1818
Ok(vm.get_none())
1919
}
2020

vm/src/frame.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,29 +132,29 @@ pub trait NameProtocol {
132132
impl NameProtocol for Scope {
133133
fn load_name(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef> {
134134
for dict in self.locals.iter() {
135-
if let Some(value) = dict.get_item(name) {
135+
if let Some(value) = dict.get_item(name, vm) {
136136
return Some(value);
137137
}
138138
}
139139

140-
if let Some(value) = self.globals.get_item(name) {
140+
if let Some(value) = self.globals.get_item(name, vm) {
141141
return Some(value);
142142
}
143143

144144
vm.get_attribute(vm.builtins.clone(), name).ok()
145145
}
146146

147-
fn load_cell(&self, _vm: &VirtualMachine, name: &str) -> Option<PyObjectRef> {
147+
fn load_cell(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef> {
148148
for dict in self.locals.iter().skip(1) {
149-
if let Some(value) = dict.get_item(name) {
149+
if let Some(value) = dict.get_item(name, vm) {
150150
return Some(value);
151151
}
152152
}
153153
None
154154
}
155155

156156
fn store_name(&self, vm: &VirtualMachine, key: &str, value: PyObjectRef) {
157-
self.get_locals().set_item(&vm.ctx, key, value)
157+
self.get_locals().set_item(key, value, vm)
158158
}
159159

160160
fn delete_name(&self, _vm: &VirtualMachine, key: &str) {
@@ -392,11 +392,11 @@ impl Frame {
392392
// Take all key-value pairs from the dict:
393393
let dict_elements = objdict::get_key_value_pairs(&obj);
394394
for (key, value) in dict_elements.iter() {
395-
map_obj.set_item(&vm.ctx, &objstr::get_value(key), value.clone());
395+
map_obj.set_item(key.clone(), value.clone(), vm);
396396
}
397397
} else {
398398
let key = self.pop_value();
399-
map_obj.set_item(&vm.ctx, &objstr::get_value(&key), obj)
399+
map_obj.set_item(key, obj, vm)
400400
}
401401
}
402402
self.push_value(map_obj.into_object());
@@ -585,7 +585,7 @@ impl Frame {
585585
let scope = self.scope.clone();
586586
let obj = vm.ctx.new_function(code_obj, scope, defaults);
587587

588-
vm.ctx.set_attr(&obj, "__annotations__", annotations);
588+
vm.set_attr(&obj, "__annotations__", annotations)?;
589589

590590
self.push_value(obj);
591591
Ok(None)

vm/src/import.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn import_uncached_module(vm: &VirtualMachine, current_path: PathBuf, module: &s
3939
// trace!("Code object: {:?}", code_obj);
4040

4141
let attrs = vm.ctx.new_dict();
42-
attrs.set_item(&vm.ctx, "__name__", vm.new_str(module.to_string()));
42+
attrs.set_item("__name__", vm.new_str(module.to_string()), vm);
4343
vm.run_code_obj(code_obj, Scope::new(None, attrs.clone()))?;
4444
Ok(vm.ctx.new_module(module, attrs))
4545
}

vm/src/macros.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,15 @@ macro_rules! no_kwargs {
114114

115115
#[macro_export]
116116
macro_rules! py_module {
117-
( $ctx:expr, $module_name:expr, { $($name:expr => $value:expr),* $(,)* }) => {
118-
{
119-
let py_mod = $ctx.new_module($module_name, $ctx.new_dict());
120-
$(
121-
$ctx.set_attr(&py_mod, $name, $value);
122-
)*
123-
py_mod
124-
}
125-
}
117+
( $ctx:expr, $module_name:expr, { $($name:expr => $value:expr),* $(,)* }) => {{
118+
let mut attributes = $crate::pyobject::PyAttributes::new();
119+
$(
120+
let value: PyObjectRef = $value.into();
121+
attributes.insert($name.to_string(), value);
122+
)*
123+
let module_dict = $crate::obj::objdict::PyDictRef::from_attributes($ctx, attributes);
124+
$ctx.new_module($module_name, module_dict)
125+
}};
126126
}
127127

128128
#[macro_export]
@@ -131,7 +131,7 @@ macro_rules! py_class {
131131
{
132132
let py_class = $ctx.new_class($class_name, $class_base);
133133
$(
134-
$ctx.set_attr(&py_class, $name, $value);
134+
py_class.set_str_attr($name, $value);
135135
)*
136136
py_class
137137
}
@@ -143,7 +143,7 @@ macro_rules! extend_class {
143143
( $ctx:expr, $class:expr, { $($name:expr => $value:expr),* $(,)* }) => {
144144
let class = $class;
145145
$(
146-
$ctx.set_attr(class, $name, $value);
146+
class.set_str_attr($name, $value);
147147
)*
148148
}
149149
}

vm/src/obj/objbytes.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ impl PyValue for PyBytes {
4343

4444
// Fill bytes class methods:
4545
pub fn init(context: &PyContext) {
46-
let bytes_type = context.bytes_type.as_object();
47-
4846
let bytes_doc =
4947
"bytes(iterable_of_ints) -> bytes\n\
5048
bytes(string, encoding[, errors]) -> bytes\n\
@@ -56,7 +54,7 @@ pub fn init(context: &PyContext) {
5654
- any object implementing the buffer API.\n \
5755
- an integer";
5856

59-
extend_class!(context, bytes_type, {
57+
extend_class!(context, &context.bytes_type, {
6058
"__new__" => context.new_rustfunc(bytes_new),
6159
"__eq__" => context.new_rustfunc(PyBytesRef::eq),
6260
"__lt__" => context.new_rustfunc(PyBytesRef::lt),

vm/src/obj/objcode.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ impl PyCodeRef {
8080
}
8181

8282
pub fn init(context: &PyContext) {
83-
let code_type = context.code_type.as_object();
84-
extend_class!(context, code_type, {
83+
extend_class!(context, &context.code_type, {
8584
"__new__" => context.new_rustfunc(PyCodeRef::new),
8685
"__repr__" => context.new_rustfunc(PyCodeRef::repr),
8786

vm/src/obj/objdict.rs

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::fmt;
44

55
use crate::function::{KwArgs, OptionalArg};
66
use crate::pyobject::{
7-
DictProtocol, PyAttributes, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
7+
DictProtocol, IntoPyObject, PyAttributes, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
88
};
99
use crate::vm::{ReprGuard, VirtualMachine};
1010

@@ -58,7 +58,7 @@ impl PyDictRef {
5858
if let OptionalArg::Present(dict_obj) = dict_obj {
5959
if objtype::isinstance(&dict_obj, &vm.ctx.dict_type()) {
6060
for (needle, value) in get_key_value_pairs(&dict_obj) {
61-
dict.set_item(&vm.ctx, &objstr::get_value(&needle), value);
61+
dict.set_item(needle, value, vm);
6262
}
6363
} else {
6464
let iter = objiter::get_iter(vm, &dict_obj)?;
@@ -77,13 +77,12 @@ impl PyDictRef {
7777
if objiter::get_next_object(vm, &elem_iter)?.is_some() {
7878
return Err(err(vm));
7979
}
80-
dict.set_item(&vm.ctx, &objstr::get_value(&needle), value);
80+
dict.set_item(needle, value, vm);
8181
}
8282
}
8383
}
8484
for (needle, value) in kwargs.into_iter() {
85-
let py_needle = vm.new_str(needle);
86-
dict.set_item(&vm.ctx, &objstr::get_value(&py_needle), value);
85+
dict.set_item(vm.new_str(needle), value, vm);
8786
}
8887
Ok(dict)
8988
}
@@ -181,7 +180,7 @@ impl PyDictRef {
181180
}
182181

183182
fn setitem(self, needle: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) {
184-
self.set_item(&vm.ctx, &objstr::get_value(&needle), value)
183+
self.set_item(needle, value, vm)
185184
}
186185

187186
fn getitem(self, key: PyStringRef, vm: &VirtualMachine) -> PyResult {
@@ -216,6 +215,23 @@ impl PyDictRef {
216215
}
217216
}
218217

218+
// Used during module initialisation when vm isn't available.
219+
pub fn from_attributes(ctx: &PyContext, attributes: PyAttributes) -> PyDictRef {
220+
let dict = ctx.new_dict();
221+
for (key_str, value) in attributes.into_iter() {
222+
dict.unsafe_str_insert(&key_str, value, ctx);
223+
}
224+
dict
225+
}
226+
227+
// Pub needed for some nasty edge cases.
228+
// It will be unsafe if there are entries in the dictionary that compare equal.
229+
pub fn unsafe_str_insert(&self, key: &str, value: PyObjectRef, ctx: &PyContext) {
230+
self.entries
231+
.borrow_mut()
232+
.insert(key.to_string(), (ctx.new_str(key.to_string()), value));
233+
}
234+
219235
/// Take a python dictionary and convert it to attributes.
220236
pub fn to_attributes(self) -> PyAttributes {
221237
let mut attrs = PyAttributes::new();
@@ -228,12 +244,14 @@ impl PyDictRef {
228244
}
229245

230246
impl DictProtocol for PyDictRef {
231-
fn contains_key(&self, k: &str) -> bool {
232-
self.entries.borrow().get(k).is_some()
247+
fn contains_key<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> bool {
248+
let key_str = &objstr::get_value(&key.into_pyobject(vm).unwrap());
249+
self.entries.borrow().get(key_str).is_some()
233250
}
234251

235-
fn get_item(&self, k: &str) -> Option<PyObjectRef> {
236-
match self.entries.borrow().get(k) {
252+
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> Option<PyObjectRef> {
253+
let key_str = &objstr::get_value(&key.into_pyobject(vm).unwrap());
254+
match self.entries.borrow().get(key_str) {
237255
Some(v) => Some(v.1.clone()),
238256
None => None,
239257
}
@@ -244,10 +262,11 @@ impl DictProtocol for PyDictRef {
244262
}
245263

246264
// Item set/get:
247-
fn set_item(&self, ctx: &PyContext, key_str: &str, v: PyObjectRef) {
248-
let key = ctx.new_str(key_str.to_string());
265+
fn set_item<T: IntoPyObject>(&self, key: T, value: PyObjectRef, vm: &VirtualMachine) {
266+
let key = key.into_pyobject(vm).unwrap();
267+
let key_str = &objstr::get_value(&key);
249268
let elements = &mut self.entries.borrow_mut();
250-
elements.insert(key_str.to_string(), (key.clone(), v.clone()));
269+
elements.insert(key_str.to_string(), (key.clone(), value));
251270
}
252271

253272
fn del_item(&self, key: &str) {

vm/src/obj/objellipsis.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ use crate::pyobject::{PyContext, PyResult, TypeProtocol};
33
use crate::vm::VirtualMachine;
44

55
pub fn init(context: &PyContext) {
6-
let ellipsis_type = context.ellipsis_type.as_object();
7-
extend_class!(context, ellipsis_type, {
6+
extend_class!(context, &context.ellipsis_type, {
87
"__new__" => context.new_rustfunc(ellipsis_new),
98
"__repr__" => context.new_rustfunc(ellipsis_repr)
109
});

0 commit comments

Comments
 (0)