Eliminate ctx.set_attr.

This commit is contained in:
Adam Kelly
2019-04-04 14:49:10 +01:00
parent 25c17b4829
commit c8eda3733d
23 changed files with 129 additions and 126 deletions

View File

@@ -43,8 +43,6 @@ impl PyValue for PyBytes {
// Fill bytes class methods:
pub fn init(context: &PyContext) {
let bytes_type = context.bytes_type.as_object();
let bytes_doc =
"bytes(iterable_of_ints) -> bytes\n\
bytes(string, encoding[, errors]) -> bytes\n\
@@ -56,7 +54,7 @@ pub fn init(context: &PyContext) {
- any object implementing the buffer API.\n \
- an integer";
extend_class!(context, bytes_type, {
extend_class!(context, &context.bytes_type, {
"__new__" => context.new_rustfunc(bytes_new),
"__eq__" => context.new_rustfunc(PyBytesRef::eq),
"__lt__" => context.new_rustfunc(PyBytesRef::lt),

View File

@@ -80,8 +80,7 @@ impl PyCodeRef {
}
pub fn init(context: &PyContext) {
let code_type = context.code_type.as_object();
extend_class!(context, code_type, {
extend_class!(context, &context.code_type, {
"__new__" => context.new_rustfunc(PyCodeRef::new),
"__repr__" => context.new_rustfunc(PyCodeRef::repr),

View File

@@ -4,7 +4,7 @@ use std::fmt;
use crate::function::{KwArgs, OptionalArg};
use crate::pyobject::{
DictProtocol, PyAttributes, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
DictProtocol, IntoPyObject, PyAttributes, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
};
use crate::vm::{ReprGuard, VirtualMachine};
@@ -58,7 +58,7 @@ impl PyDictRef {
if let OptionalArg::Present(dict_obj) = dict_obj {
if objtype::isinstance(&dict_obj, &vm.ctx.dict_type()) {
for (needle, value) in get_key_value_pairs(&dict_obj) {
dict.set_item(&vm.ctx, &objstr::get_value(&needle), value);
dict.set_item(needle, value, vm);
}
} else {
let iter = objiter::get_iter(vm, &dict_obj)?;
@@ -77,13 +77,12 @@ impl PyDictRef {
if objiter::get_next_object(vm, &elem_iter)?.is_some() {
return Err(err(vm));
}
dict.set_item(&vm.ctx, &objstr::get_value(&needle), value);
dict.set_item(needle, value, vm);
}
}
}
for (needle, value) in kwargs.into_iter() {
let py_needle = vm.new_str(needle);
dict.set_item(&vm.ctx, &objstr::get_value(&py_needle), value);
dict.set_item(vm.new_str(needle), value, vm);
}
Ok(dict)
}
@@ -181,7 +180,7 @@ impl PyDictRef {
}
fn setitem(self, needle: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) {
self.set_item(&vm.ctx, &objstr::get_value(&needle), value)
self.set_item(needle, value, vm)
}
fn getitem(self, key: PyStringRef, vm: &VirtualMachine) -> PyResult {
@@ -216,6 +215,23 @@ impl PyDictRef {
}
}
// Used during module initialisation when vm isn't available.
pub fn from_attributes(ctx: &PyContext, attributes: PyAttributes) -> PyDictRef {
let dict = ctx.new_dict();
for (key_str, value) in attributes.into_iter() {
dict.unsafe_str_insert(&key_str, value, ctx);
}
dict
}
// Pub needed for some nasty edge cases.
// It will be unsafe if there are entries in the dictionary that compare equal.
pub fn unsafe_str_insert(&self, key: &str, value: PyObjectRef, ctx: &PyContext) {
self.entries
.borrow_mut()
.insert(key.to_string(), (ctx.new_str(key.to_string()), value));
}
/// Take a python dictionary and convert it to attributes.
pub fn to_attributes(self) -> PyAttributes {
let mut attrs = PyAttributes::new();
@@ -228,12 +244,14 @@ impl PyDictRef {
}
impl DictProtocol for PyDictRef {
fn contains_key(&self, k: &str) -> bool {
self.entries.borrow().get(k).is_some()
fn contains_key<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> bool {
let key_str = &objstr::get_value(&key.into_pyobject(vm).unwrap());
self.entries.borrow().get(key_str).is_some()
}
fn get_item(&self, k: &str) -> Option<PyObjectRef> {
match self.entries.borrow().get(k) {
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> Option<PyObjectRef> {
let key_str = &objstr::get_value(&key.into_pyobject(vm).unwrap());
match self.entries.borrow().get(key_str) {
Some(v) => Some(v.1.clone()),
None => None,
}
@@ -244,10 +262,11 @@ impl DictProtocol for PyDictRef {
}
// Item set/get:
fn set_item(&self, ctx: &PyContext, key_str: &str, v: PyObjectRef) {
let key = ctx.new_str(key_str.to_string());
fn set_item<T: IntoPyObject>(&self, key: T, value: PyObjectRef, vm: &VirtualMachine) {
let key = key.into_pyobject(vm).unwrap();
let key_str = &objstr::get_value(&key);
let elements = &mut self.entries.borrow_mut();
elements.insert(key_str.to_string(), (key.clone(), v.clone()));
elements.insert(key_str.to_string(), (key.clone(), value));
}
fn del_item(&self, key: &str) {

View File

@@ -3,8 +3,7 @@ use crate::pyobject::{PyContext, PyResult, TypeProtocol};
use crate::vm::VirtualMachine;
pub fn init(context: &PyContext) {
let ellipsis_type = context.ellipsis_type.as_object();
extend_class!(context, ellipsis_type, {
extend_class!(context, &context.ellipsis_type, {
"__new__" => context.new_rustfunc(ellipsis_new),
"__repr__" => context.new_rustfunc(ellipsis_repr)
});

View File

@@ -20,7 +20,7 @@ pub fn new_memory_view(
bytes_object: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<PyMemoryViewRef> {
vm.ctx.set_attr(&cls, "obj", bytes_object.clone());
vm.set_attr(cls.as_object(), "obj", bytes_object.clone())?;
PyMemoryView { obj: bytes_object }.into_ref_with_type(vm, cls)
}

View File

@@ -77,7 +77,7 @@ fn object_setattr(
}
if let Some(ref dict) = obj.clone().dict {
dict.set_item(&vm.ctx, &attr_name.value, value);
dict.set_item(attr_name, value, vm);
Ok(())
} else {
Err(vm.new_attribute_error(format!(
@@ -208,7 +208,7 @@ fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMach
}
}
if let Some(obj_attr) = object_getattr(&obj, &name) {
if let Some(obj_attr) = object_getattr(&obj, &name, &vm) {
Ok(obj_attr)
} else if let Some(attr) = objtype::class_get_attr(&cls, &name) {
vm.call_get_descriptor(attr, obj)
@@ -219,9 +219,9 @@ fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMach
}
}
fn object_getattr(obj: &PyObjectRef, attr_name: &str) -> Option<PyObjectRef> {
fn object_getattr(obj: &PyObjectRef, attr_name: &str, vm: &VirtualMachine) -> Option<PyObjectRef> {
if let Some(ref dict) = obj.dict {
dict.get_item(attr_name)
dict.get_item(attr_name, vm)
} else {
None
}

View File

@@ -762,6 +762,12 @@ impl IntoPyObject for &str {
}
}
impl IntoPyObject for &String {
fn into_pyobject(self, vm: &VirtualMachine) -> PyResult {
Ok(vm.ctx.new_str(self.clone()))
}
}
pub fn init(ctx: &PyContext) {
PyStringRef::extend_class(ctx, &ctx.str_type);
}

View File

@@ -124,7 +124,7 @@ fn super_new(
} else {
let frame = vm.current_frame().expect("no current frame for super()");
if let Some(first_arg) = frame.code.arg_names.get(0) {
match vm.get_locals().get_item(first_arg) {
match vm.get_locals().get_item(first_arg, vm) {
Some(obj) => obj.clone(),
_ => {
return Err(vm

View File

@@ -162,6 +162,13 @@ impl PyClassRef {
Ok(())
}
// This is used for class initialisation where the vm is not yet available.
pub fn set_str_attr<V: Into<PyObjectRef>>(&self, attr_name: &str, value: V) {
self.attributes
.borrow_mut()
.insert(attr_name.to_string(), value.into());
}
fn subclasses(self, _vm: &VirtualMachine) -> PyList {
let mut subclasses = self.subclasses.borrow_mut();
subclasses.retain(|x| x.upgrade().is_some());