From 630fbd948a1f838b7a9dd612229c5a3f1c6dfb31 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Sat, 31 Aug 2019 09:46:55 +0300 Subject: [PATCH 1/4] Use LinkedList in scope locals --- vm/src/scope.rs | 72 ++++++++++--------------------------------------- 1 file changed, 14 insertions(+), 58 deletions(-) diff --git a/vm/src/scope.rs b/vm/src/scope.rs index eda7ddc09..ebfaab121 100644 --- a/vm/src/scope.rs +++ b/vm/src/scope.rs @@ -1,5 +1,5 @@ +use std::collections::LinkedList; use std::fmt; -use std::rc::Rc; use crate::obj::objdict::PyDictRef; use crate::pyobject::{ItemProtocol, PyContext, PyObjectRef, PyResult}; @@ -9,58 +9,9 @@ use crate::vm::VirtualMachine; * So a scope is a linked list of scopes. * When a name is looked up, it is check in its scope. */ -#[derive(Debug)] -struct RcListNode { - elem: T, - next: Option>>, -} - -#[derive(Debug, Clone)] -struct RcList { - head: Option>>, -} - -struct Iter<'a, T: 'a> { - next: Option<&'a RcListNode>, -} - -impl RcList { - pub fn new() -> Self { - RcList { head: None } - } - - pub fn insert(self, elem: T) -> Self { - RcList { - head: Some(Rc::new(RcListNode { - elem, - next: self.head, - })), - } - } - - #[cfg_attr(feature = "flame-it", flame("RcList"))] - pub fn iter(&self) -> Iter { - Iter { - next: self.head.as_ref().map(|node| &**node), - } - } -} - -impl<'a, T> Iterator for Iter<'a, T> { - type Item = &'a T; - - #[cfg_attr(feature = "flame-it", flame("Iter"))] - fn next(&mut self) -> Option { - self.next.map(|node| { - self.next = node.next.as_ref().map(|node| &**node); - &node.elem - }) - } -} - #[derive(Clone)] pub struct Scope { - locals: RcList, + locals: LinkedList, pub globals: PyDictRef, } @@ -73,11 +24,14 @@ impl fmt::Debug for Scope { impl Scope { pub fn new(locals: Option, globals: PyDictRef, vm: &VirtualMachine) -> Scope { - let locals = match locals { - Some(dict) => RcList::new().insert(dict), - None => RcList::new(), + let mut locals_list = LinkedList::new(); + if let Some(dict) = locals { + locals_list.push_front(dict) + } + let scope = Scope { + locals: locals_list, + globals, }; - let scope = Scope { locals, globals }; scope.store_name(vm, "__annotations__", vm.ctx.new_dict().into_object()); scope } @@ -97,19 +51,21 @@ impl Scope { } pub fn get_locals(&self) -> PyDictRef { - match self.locals.iter().next() { + match self.locals.front() { Some(dict) => dict.clone(), None => self.globals.clone(), } } pub fn get_only_locals(&self) -> Option { - self.locals.iter().next().cloned() + self.locals.front().cloned() } pub fn new_child_scope_with_locals(&self, locals: PyDictRef) -> Scope { + let mut new_locals = self.locals.clone(); + new_locals.push_front(locals); Scope { - locals: self.locals.clone().insert(locals), + locals: new_locals, globals: self.globals.clone(), } } From 59884ef6f04670ef9f6d0cf55e925446c805bded Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Wed, 4 Sep 2019 11:46:39 +0300 Subject: [PATCH 2/4] Change locals to Vec --- vm/src/scope.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/vm/src/scope.rs b/vm/src/scope.rs index ebfaab121..0275d3eb1 100644 --- a/vm/src/scope.rs +++ b/vm/src/scope.rs @@ -1,4 +1,3 @@ -use std::collections::LinkedList; use std::fmt; use crate::obj::objdict::PyDictRef; @@ -11,7 +10,7 @@ use crate::vm::VirtualMachine; */ #[derive(Clone)] pub struct Scope { - locals: LinkedList, + locals: Vec, pub globals: PyDictRef, } @@ -24,14 +23,11 @@ impl fmt::Debug for Scope { impl Scope { pub fn new(locals: Option, globals: PyDictRef, vm: &VirtualMachine) -> Scope { - let mut locals_list = LinkedList::new(); - if let Some(dict) = locals { - locals_list.push_front(dict) - } - let scope = Scope { - locals: locals_list, - globals, + let locals = match locals { + Some(dict) => vec![dict], + None => vec![], }; + let scope = Scope { locals, globals }; scope.store_name(vm, "__annotations__", vm.ctx.new_dict().into_object()); scope } @@ -51,19 +47,20 @@ impl Scope { } pub fn get_locals(&self) -> PyDictRef { - match self.locals.front() { + match self.locals.first() { Some(dict) => dict.clone(), None => self.globals.clone(), } } pub fn get_only_locals(&self) -> Option { - self.locals.front().cloned() + self.locals.first().cloned() } pub fn new_child_scope_with_locals(&self, locals: PyDictRef) -> Scope { - let mut new_locals = self.locals.clone(); - new_locals.push_front(locals); + let mut new_locals = Vec::with_capacity(self.locals.len() + 1); + new_locals.push(locals); + new_locals.append(&mut self.locals.clone()); Scope { locals: new_locals, globals: self.globals.clone(), From 42c4339729dbe15c49ad435c77039f6c248581c1 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Wed, 4 Sep 2019 14:50:30 +0300 Subject: [PATCH 3/4] Use get in store_cell --- vm/src/scope.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vm/src/scope.rs b/vm/src/scope.rs index 0275d3eb1..c23b83df9 100644 --- a/vm/src/scope.rs +++ b/vm/src/scope.rs @@ -114,8 +114,7 @@ impl NameProtocol for Scope { fn store_cell(&self, vm: &VirtualMachine, name: &str, value: PyObjectRef) { self.locals - .iter() - .nth(1) + .get(1) .expect("no outer scope for non-local") .set_item(name, value, vm) .unwrap(); From 29d9105ce1da0f0edc9d65c880184c0d9c245ec7 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Wed, 4 Sep 2019 16:04:53 +0300 Subject: [PATCH 4/4] Use extend_from_slice --- vm/src/scope.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/src/scope.rs b/vm/src/scope.rs index c23b83df9..bbba87a30 100644 --- a/vm/src/scope.rs +++ b/vm/src/scope.rs @@ -60,7 +60,7 @@ impl Scope { pub fn new_child_scope_with_locals(&self, locals: PyDictRef) -> Scope { let mut new_locals = Vec::with_capacity(self.locals.len() + 1); new_locals.push(locals); - new_locals.append(&mut self.locals.clone()); + new_locals.extend_from_slice(&self.locals); Scope { locals: new_locals, globals: self.globals.clone(),