From 430bc4bac2217c3fe5dc6c06e6eda28272cb93d6 Mon Sep 17 00:00:00 2001
From: coolreader18 <33094578+coolreader18@users.noreply.github.com>
Date: Sat, 23 Mar 2019 09:35:53 -0500
Subject: [PATCH 001/658] Fix vm.import when there are no frames on stack
---
vm/src/builtins.rs | 11 ++++++++---
vm/src/obj/objsuper.rs | 8 +++++---
vm/src/vm.rs | 30 +++++++++++++++++++-----------
3 files changed, 32 insertions(+), 17 deletions(-)
diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs
index 6d3d512a7..a81273e60 100644
--- a/vm/src/builtins.rs
+++ b/vm/src/builtins.rs
@@ -700,9 +700,14 @@ fn builtin_import(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
]
);
let current_path = {
- let mut source_pathbuf = PathBuf::from(&vm.current_frame().code.source_path);
- source_pathbuf.pop();
- source_pathbuf
+ match vm.current_frame() {
+ Some(frame) => {
+ let mut source_pathbuf = PathBuf::from(&frame.code.source_path);
+ source_pathbuf.pop();
+ source_pathbuf
+ }
+ None => PathBuf::new(),
+ }
};
import_module(vm, current_path, &objstr::get_value(name))
diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs
index 2b2be0241..43161ae6b 100644
--- a/vm/src/obj/objsuper.rs
+++ b/vm/src/obj/objsuper.rs
@@ -129,13 +129,15 @@ fn super_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
let py_obj = if let Some(obj) = py_obj {
obj.clone()
} else {
- let frame = vm.current_frame();
+ 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) {
Some(obj) => obj.clone(),
_ => {
- return Err(vm
- .new_type_error(format!("super arguement {} was not supplied", first_arg)));
+ return Err(vm.new_type_error(format!(
+ "super arguement {} was not supplied",
+ first_arg
+ )));
}
}
} else {
diff --git a/vm/src/vm.rs b/vm/src/vm.rs
index 029588d13..05a115732 100644
--- a/vm/src/vm.rs
+++ b/vm/src/vm.rs
@@ -91,19 +91,28 @@ impl VirtualMachine {
result
}
- pub fn current_frame(&self) -> Ref {
- Ref::map(self.frames.borrow(), |frames| {
- let index = frames.len() - 1;
- let current_frame = &frames[index];
- objframe::get_value(current_frame)
- })
+ pub fn current_frame(&self) -> Option[> {
+ let frames = self.frames.borrow();
+ if frames.is_empty() {
+ None
+ } else {
+ Some(Ref::map(self.frames.borrow(), |frames| {
+ objframe::get_value(frames.last().unwrap())
+ }))
+ }
}
pub fn current_scope(&self) -> Ref {
- let frame = self.current_frame();
+ let frame = self
+ .current_frame()
+ .expect("called current_scope but no frames on the stack");
Ref::map(frame, |f| &f.scope)
}
+ pub fn try_class(&self, module: &str, class: &str) -> PyResult {
+ self.get_attribute(self.import(module)?, class)
+ }
+
pub fn class(&self, module: &str, class: &str) -> PyObjectRef {
let module = self
.import(module)
@@ -246,10 +255,9 @@ impl VirtualMachine {
}
pub fn import(&self, module: &str) -> PyResult {
- let builtins_import = self.builtins.get_item("__import__");
- match builtins_import {
- Some(func) => self.invoke(func, vec![self.ctx.new_str(module.to_string())]),
- None => Err(self.new_exception(
+ match self.get_attribute(self.builtins.clone(), "__import__") {
+ Ok(func) => self.invoke(func, vec![self.ctx.new_str(module.to_string())]),
+ Err(_) => Err(self.new_exception(
self.ctx.exceptions.import_error.clone(),
"__import__ not found".to_string(),
)),
From a830d8e131bf5d4f5debbc054814bbbbe4777535 Mon Sep 17 00:00:00 2001
From: coolreader18 <33094578+coolreader18@users.noreply.github.com>
Date: Sat, 23 Mar 2019 09:36:15 -0500
Subject: [PATCH 002/658] Add PyDocument and PyElement
---
vm/src/function.rs | 1 +
wasm/lib/src/browser_module.rs | 113 ++++++++++++++++++++++++++-------
wasm/lib/src/convert.rs | 4 +-
wasm/lib/src/vm_class.rs | 1 -
4 files changed, 94 insertions(+), 25 deletions(-)
diff --git a/vm/src/function.rs b/vm/src/function.rs
index 7159427e5..3093b8c5f 100644
--- a/vm/src/function.rs
+++ b/vm/src/function.rs
@@ -304,6 +304,7 @@ pub enum OptionalArg {
}
impl OptionalArg {
+ #[inline]
pub fn into_option(self) -> Option {
match self {
Present(value) => Some(value),
diff --git a/wasm/lib/src/browser_module.rs b/wasm/lib/src/browser_module.rs
index 7fc2a2476..13f1404ab 100644
--- a/wasm/lib/src/browser_module.rs
+++ b/wasm/lib/src/browser_module.rs
@@ -1,5 +1,3 @@
-use std::path::PathBuf;
-
use futures::Future;
use js_sys::Promise;
use num_traits::cast::ToPrimitive;
@@ -7,11 +5,13 @@ use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::{future_to_promise, JsFuture};
-use rustpython_vm::function::PyFuncArgs;
-use rustpython_vm::import::import_module;
-use rustpython_vm::obj::{objint, objstr};
+use rustpython_vm::function::{OptionalArg, PyFuncArgs};
+use rustpython_vm::obj::{
+ objint,
+ objstr::{self, PyStringRef},
+};
use rustpython_vm::pyobject::{
- AttributeProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
+ PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use rustpython_vm::VirtualMachine;
@@ -44,7 +44,7 @@ impl FetchResponseFormat {
fn browser_fetch(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(url, Some(vm.ctx.str_type()))]);
- let promise_type = import_promise_type(vm)?;
+ let promise_type = vm.try_class("browser", "Promise")?;
let response_format =
args.get_optional_kwarg_with_type("response_format", vm.ctx.str_type(), vm)?;
@@ -165,7 +165,7 @@ pub struct PyPromise {
impl PyValue for PyPromise {
fn class(vm: &VirtualMachine) -> PyObjectRef {
- vm.class(BROWSER_NAME, "Promise")
+ vm.class("browser", "Promise")
}
}
@@ -182,15 +182,8 @@ pub fn get_promise_value(obj: &PyObjectRef) -> Promise {
panic!("Inner error getting promise")
}
-pub fn import_promise_type(vm: &VirtualMachine) -> PyResult {
- match import_module(vm, PathBuf::default(), BROWSER_NAME)?.get_attr("Promise") {
- Some(promise) => Ok(promise),
- None => Err(vm.new_not_implemented_error("No Promise".to_string())),
- }
-}
-
fn promise_then(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- let promise_type = import_promise_type(vm)?;
+ let promise_type = vm.try_class("browser", "Promise")?;
arg_check!(
vm,
args,
@@ -236,7 +229,7 @@ fn promise_then(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
}
fn promise_catch(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- let promise_type = import_promise_type(vm)?;
+ let promise_type = vm.try_class("browser", "Promise")?;
arg_check!(
vm,
args,
@@ -270,6 +263,65 @@ fn promise_catch(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(PyPromise::new_obj(promise_type, ret_promise))
}
+#[derive(Debug)]
+struct PyDocument {
+ doc: web_sys::Document,
+}
+type PyDocumentRef = PyRef;
+
+impl PyValue for PyDocument {
+ fn class(vm: &VirtualMachine) -> PyObjectRef {
+ vm.class("browser", "Document")
+ }
+}
+
+fn document_query(zelf: PyDocumentRef, query: PyStringRef, vm: &VirtualMachine) -> PyResult {
+ let elem = zelf
+ .doc
+ .query_selector(&query.value)
+ .map_err(|err| convert::js_py_typeerror(vm, err))?;
+ let elem = match elem {
+ Some(elem) => PyElement { elem }.into_ref(vm).into_object(),
+ None => vm.get_none(),
+ };
+ Ok(elem)
+}
+
+#[derive(Debug)]
+struct PyElement {
+ elem: web_sys::Element,
+}
+type PyElementRef = PyRef;
+
+impl PyValue for PyElement {
+ fn class(vm: &VirtualMachine) -> PyObjectRef {
+ vm.class("browser", "Element")
+ }
+}
+
+fn elem_get_attr(
+ zelf: PyElementRef,
+ attr: PyStringRef,
+ default: OptionalArg,
+ vm: &VirtualMachine,
+) -> PyObjectRef {
+ match zelf.elem.get_attribute(&attr.value) {
+ Some(s) => vm.new_str(s),
+ None => default.into_option().unwrap_or_else(|| vm.get_none()),
+ }
+}
+
+fn elem_set_attr(
+ zelf: PyElementRef,
+ attr: PyStringRef,
+ value: PyStringRef,
+ vm: &VirtualMachine,
+) -> PyResult<()> {
+ zelf.elem
+ .set_attribute(&attr.value, &value.value)
+ .map_err(|err| convert::js_to_py(vm, err))
+}
+
fn browser_alert(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(message, Some(vm.ctx.str_type()))]);
@@ -315,19 +367,36 @@ fn browser_prompt(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(result)
}
-const BROWSER_NAME: &str = "browser";
-
pub fn make_module(ctx: &PyContext) -> PyObjectRef {
let promise = py_class!(ctx, "Promise", ctx.object(), {
"then" => ctx.new_rustfunc(promise_then),
- "catch" => ctx.new_rustfunc(promise_catch)
+ "catch" => ctx.new_rustfunc(promise_catch),
});
- py_module!(ctx, BROWSER_NAME, {
+ let document_class = py_class!(ctx, "Document", ctx.object(), {
+ "query" => ctx.new_rustfunc(document_query),
+ });
+
+ let document = PyObject::new(
+ PyDocument {
+ doc: window().document().expect("Document missing from window"),
+ },
+ document_class.clone(),
+ );
+
+ let element = py_class!(ctx, "Element", ctx.object(), {
+ "get_attr" => ctx.new_rustfunc(elem_get_attr),
+ "set_attr" => ctx.new_rustfunc(elem_set_attr),
+ });
+
+ py_module!(ctx, "browser", {
"fetch" => ctx.new_rustfunc(browser_fetch),
"request_animation_frame" => ctx.new_rustfunc(browser_request_animation_frame),
"cancel_animation_frame" => ctx.new_rustfunc(browser_cancel_animation_frame),
"Promise" => promise,
+ "Document" => document_class,
+ "document" => document,
+ "Element" => element,
"alert" => ctx.new_rustfunc(browser_alert),
"confirm" => ctx.new_rustfunc(browser_confirm),
"prompt" => ctx.new_rustfunc(browser_prompt),
@@ -337,5 +406,5 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
pub fn setup_browser_module(vm: &VirtualMachine) {
vm.stdlib_inits
.borrow_mut()
- .insert(BROWSER_NAME.to_string(), Box::new(make_module));
+ .insert("browser".to_string(), Box::new(make_module));
}
diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs
index 122ff1763..b7f9048e9 100644
--- a/wasm/lib/src/convert.rs
+++ b/wasm/lib/src/convert.rs
@@ -114,7 +114,7 @@ pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue {
}
}
// the browser module might not be injected
- if let Ok(promise_type) = browser_module::import_promise_type(vm) {
+ if let Ok(promise_type) = vm.try_class("browser", "Promise") {
if objtype::isinstance(&py_obj, &promise_type) {
return browser_module::get_promise_value(&py_obj).into();
}
@@ -158,7 +158,7 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
if js_val.is_object() {
if let Some(promise) = js_val.dyn_ref::() {
// the browser module might not be injected
- if let Ok(promise_type) = browser_module::import_promise_type(vm) {
+ if let Ok(promise_type) = vm.try_class("browser", "Promise") {
return browser_module::PyPromise::new_obj(promise_type, promise.clone());
}
}
diff --git a/wasm/lib/src/vm_class.rs b/wasm/lib/src/vm_class.rs
index 9d80854f7..77822147a 100644
--- a/wasm/lib/src/vm_class.rs
+++ b/wasm/lib/src/vm_class.rs
@@ -49,7 +49,6 @@ impl StoredVirtualMachine {
thread_local! {
static STORED_VMS: RefCell>> =
RefCell::default();
- static ACTIVE_VMS: RefCell> = RefCell::default();
}
#[wasm_bindgen(js_name = vmStore)]
From 2626a800ab486c74ae3a28e19a0ac1757e19fe64 Mon Sep 17 00:00:00 2001
From: Aviv Palivoda
Date: Sat, 23 Mar 2019 11:04:40 +0200
Subject: [PATCH 003/658] Support frozenset
---
tests/snippets/set.py | 85 ++++++++++++++++++
vm/src/obj/objset.rs | 204 ++++++++++++++++++++++++++++++------------
2 files changed, 233 insertions(+), 56 deletions(-)
diff --git a/tests/snippets/set.py b/tests/snippets/set.py
index a7a20b0ef..9e49dff89 100644
--- a/tests/snippets/set.py
+++ b/tests/snippets/set.py
@@ -144,3 +144,88 @@ a ^= set([3,4,5])
assert a == set([1,2,4,5])
with assertRaises(TypeError):
a ^= 1
+
+# frozen set
+
+assert frozenset([1,2]) == frozenset([1,2])
+assert not frozenset([1,2,3]) == frozenset([1,2])
+
+assert frozenset([1,2,3]) >= frozenset([1,2])
+assert frozenset([1,2]) >= frozenset([1,2])
+assert not frozenset([1,3]) >= frozenset([1,2])
+
+assert frozenset([1,2,3]).issuperset(frozenset([1,2]))
+assert frozenset([1,2]).issuperset(frozenset([1,2]))
+assert not frozenset([1,3]).issuperset(frozenset([1,2]))
+
+assert frozenset([1,2,3]) > frozenset([1,2])
+assert not frozenset([1,2]) > frozenset([1,2])
+assert not frozenset([1,3]) > frozenset([1,2])
+
+assert frozenset([1,2]) <= frozenset([1,2,3])
+assert frozenset([1,2]) <= frozenset([1,2])
+assert not frozenset([1,3]) <= frozenset([1,2])
+
+assert frozenset([1,2]).issubset(frozenset([1,2,3]))
+assert frozenset([1,2]).issubset(frozenset([1,2]))
+assert not frozenset([1,3]).issubset(frozenset([1,2]))
+
+assert frozenset([1,2]) < frozenset([1,2,3])
+assert not frozenset([1,2]) < frozenset([1,2])
+assert not frozenset([1,3]) < frozenset([1,2])
+
+a = frozenset([1, 2, 3])
+assert len(a) == 3
+b = a.copy()
+assert b == a
+
+assert frozenset([1,2,3]).union(frozenset([4,5])) == frozenset([1,2,3,4,5])
+assert frozenset([1,2,3]).union(frozenset([1,2,3,4,5])) == frozenset([1,2,3,4,5])
+
+assert frozenset([1,2,3]) | frozenset([4,5]) == frozenset([1,2,3,4,5])
+assert frozenset([1,2,3]) | frozenset([1,2,3,4,5]) == frozenset([1,2,3,4,5])
+
+assert frozenset([1,2,3]).intersection(frozenset([1,2])) == frozenset([1,2])
+assert frozenset([1,2,3]).intersection(frozenset([5,6])) == frozenset([])
+
+assert frozenset([1,2,3]) & frozenset([4,5]) == frozenset([])
+assert frozenset([1,2,3]) & frozenset([1,2,3,4,5]) == frozenset([1,2,3])
+
+assert frozenset([1,2,3]).difference(frozenset([1,2])) == frozenset([3])
+assert frozenset([1,2,3]).difference(frozenset([5,6])) == frozenset([1,2,3])
+
+assert frozenset([1,2,3]) - frozenset([4,5]) == frozenset([1,2,3])
+assert frozenset([1,2,3]) - frozenset([1,2,3,4,5]) == frozenset([])
+
+assert frozenset([1,2,3]).symmetric_difference(frozenset([1,2])) == frozenset([3])
+assert frozenset([1,2,3]).symmetric_difference(frozenset([5,6])) == frozenset([1,2,3,5,6])
+
+assert frozenset([1,2,3]) ^ frozenset([4,5]) == frozenset([1,2,3,4,5])
+assert frozenset([1,2,3]) ^ frozenset([1,2,3,4,5]) == frozenset([4,5])
+
+assert_raises(TypeError, lambda: frozenset([[]]))
+
+# set and frozen set
+assert frozenset([1,2,3]).union(set([4,5])) == frozenset([1,2,3,4,5])
+assert set([1,2,3]).union(frozenset([4,5])) == set([1,2,3,4,5])
+
+assert frozenset([1,2,3]) | set([4,5]) == frozenset([1,2,3,4,5])
+assert set([1,2,3]) | frozenset([4,5]) == set([1,2,3,4,5])
+
+assert frozenset([1,2,3]).intersection(set([5,6])) == frozenset([])
+assert set([1,2,3]).intersection(frozenset([5,6])) == set([])
+
+assert frozenset([1,2,3]) & set([1,2,3,4,5]) == frozenset([1,2,3])
+assert set([1,2,3]) & frozenset([1,2,3,4,5]) == set([1,2,3])
+
+assert frozenset([1,2,3]).difference(set([5,6])) == frozenset([1,2,3])
+assert set([1,2,3]).difference(frozenset([5,6])) == set([1,2,3])
+
+assert frozenset([1,2,3]) - set([4,5]) == frozenset([1,2,3])
+assert set([1,2,3]) - frozenset([4,5]) == frozenset([1,2,3])
+
+assert frozenset([1,2,3]).symmetric_difference(set([1,2])) == frozenset([3])
+assert set([1,2,3]).symmetric_difference(frozenset([1,2])) == set([3])
+
+assert frozenset([1,2,3]) ^ set([4,5]) == frozenset([1,2,3,4,5])
+assert set([1,2,3]) ^ frozenset([4,5]) == set([1,2,3,4,5])
diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs
index 33a445531..8bb338d40 100644
--- a/vm/src/obj/objset.rs
+++ b/vm/src/obj/objset.rs
@@ -9,13 +9,14 @@ use std::hash::{Hash, Hasher};
use crate::function::{OptionalArg, PyFuncArgs};
use crate::pyobject::{
- PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
+ PyContext, PyIteratorValue, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::vm::{ReprGuard, VirtualMachine};
use super::objbool;
use super::objint;
use super::objiter;
+use super::objtype;
use super::objtype::PyClassRef;
#[derive(Default)]
@@ -24,6 +25,12 @@ pub struct PySet {
}
pub type PySetRef = PyRef;
+#[derive(Default)]
+pub struct PyFrozenSet {
+ elements: RefCell>,
+}
+pub type PyFrozenSetRef = PyRef;
+
impl fmt::Debug for PySet {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// TODO: implement more detailed, non-recursive Debug formatter
@@ -31,14 +38,69 @@ impl fmt::Debug for PySet {
}
}
+impl fmt::Debug for PyFrozenSet {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ // TODO: implement more detailed, non-recursive Debug formatter
+ f.write_str("frozenset")
+ }
+}
+
impl PyValue for PySet {
fn class(vm: &VirtualMachine) -> PyClassRef {
vm.ctx.set_type()
}
}
+impl PyValue for PyFrozenSet {
+ fn class(vm: &VirtualMachine) -> PyClassRef {
+ vm.ctx.frozenset_type()
+ }
+}
+
pub fn get_elements(obj: &PyObjectRef) -> HashMap {
- obj.payload::().unwrap().elements.borrow().clone()
+ if let Some(set) = obj.payload::() {
+ return set.elements.borrow().clone();
+ } else if let Some(frozenset) = obj.payload::() {
+ return frozenset.elements.borrow().clone();
+ }
+ panic!("Not frozenset or set");
+}
+
+macro_rules! validate_set_or_frozenset {
+ ( $vm:ident, $obj:expr ) => {
+ if !(objtype::issubclass(&$obj, &$vm.ctx.set_type())
+ || objtype::issubclass(&$obj, &$vm.ctx.frozenset_type()))
+ {
+ return Err($vm.new_type_error(format!(
+ "{} is not a subtype of set or frozenset a",
+ $obj.typ()
+ )));
+ }
+ };
+}
+
+fn create_set(
+ vm: &VirtualMachine,
+ elements: HashMap,
+ cls: PyClassRef,
+) -> PyResult {
+ if objtype::issubclass(&cls, &vm.ctx.set_type()) {
+ Ok(PyObject::new(
+ PySet {
+ elements: RefCell::new(elements),
+ },
+ PySet::class(vm).into_object(),
+ ))
+ } else if objtype::issubclass(&cls, &vm.ctx.frozenset_type()) {
+ Ok(PyObject::new(
+ PyFrozenSet {
+ elements: RefCell::new(elements),
+ },
+ PyFrozenSet::class(vm).into_object(),
+ ))
+ } else {
+ Err(vm.new_type_error(format!("{} is not a subtype of set or frozenset", cls)))
+ }
}
fn perform_action_with_hash(
@@ -152,11 +214,9 @@ fn set_clear(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
}
/* Create a new object of sub-type of set */
-fn set_new(
- cls: PyClassRef,
- iterable: OptionalArg,
- vm: &VirtualMachine,
-) -> PyResult {
+fn set_new(cls: PyClassRef, iterable: OptionalArg, vm: &VirtualMachine) -> PyResult {
+ validate_set_or_frozenset!(vm, cls);
+
let elements: HashMap = match iterable {
OptionalArg::Missing => HashMap::new(),
OptionalArg::Present(iterable) => {
@@ -169,25 +229,22 @@ fn set_new(
}
};
- PySet {
- elements: RefCell::new(elements),
- }
- .into_ref_with_type(vm, cls)
+ create_set(vm, elements, cls)
}
fn set_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
trace!("set.len called with: {:?}", args);
- arg_check!(vm, args, required = [(s, Some(vm.ctx.set_type()))]);
+ arg_check!(vm, args, required = [(s, None)]);
+ validate_set_or_frozenset!(vm, s.type_pyref());
let elements = get_elements(s);
Ok(vm.context().new_int(elements.len()))
}
-fn set_copy(obj: PySetRef, _vm: &VirtualMachine) -> PySet {
+fn set_copy(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
trace!("set.copy called with: {:?}", obj);
- let elements = obj.elements.borrow().clone();
- PySet {
- elements: RefCell::new(elements),
- }
+ validate_set_or_frozenset!(vm, obj.type_pyref());
+ let elements = get_elements(&obj).clone();
+ create_set(vm, elements, obj.type_pyref())
}
fn set_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -211,11 +268,8 @@ fn set_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
}
pub fn set_contains(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(
- vm,
- args,
- required = [(set, Some(vm.ctx.set_type())), (needle, None)]
- );
+ arg_check!(vm, args, required = [(set, None), (needle, None)]);
+ validate_set_or_frozenset!(vm, &set.type_pyref());
for element in get_elements(set).iter() {
match vm._eq(needle.clone(), element.1.clone()) {
Ok(value) => {
@@ -281,14 +335,10 @@ fn set_compare_inner(
size_func: &Fn(usize, usize) -> bool,
swap: bool,
) -> PyResult {
- arg_check!(
- vm,
- args,
- required = [
- (zelf, Some(vm.ctx.set_type())),
- (other, Some(vm.ctx.set_type()))
- ]
- );
+ arg_check!(vm, args, required = [(zelf, None), (other, None)]);
+
+ validate_set_or_frozenset!(vm, zelf.type_pyref());
+ validate_set_or_frozenset!(vm, other.type_pyref());
let get_zelf = |swap: bool| -> &PyObjectRef {
if swap {
@@ -323,47 +373,48 @@ fn set_compare_inner(
Ok(vm.new_bool(true))
}
-fn set_union(zelf: PySetRef, other: PySetRef, _vm: &VirtualMachine) -> PySet {
- let mut elements = zelf.elements.borrow().clone();
- elements.extend(other.elements.borrow().clone());
+fn set_union(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
+ validate_set_or_frozenset!(vm, zelf.type_pyref());
+ validate_set_or_frozenset!(vm, other.type_pyref());
- PySet {
- elements: RefCell::new(elements),
- }
+ let mut elements = get_elements(&zelf).clone();
+ elements.extend(get_elements(&other).clone());
+
+ create_set(vm, elements, zelf.type_pyref())
}
-fn set_intersection(zelf: PySetRef, other: PySetRef, vm: &VirtualMachine) -> PyResult {
+fn set_intersection(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
set_combine_inner(zelf, other, vm, SetCombineOperation::Intersection)
}
-fn set_difference(zelf: PySetRef, other: PySetRef, vm: &VirtualMachine) -> PyResult {
+fn set_difference(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
set_combine_inner(zelf, other, vm, SetCombineOperation::Difference)
}
fn set_symmetric_difference(
- zelf: PySetRef,
- other: PySetRef,
+ zelf: PyObjectRef,
+ other: PyObjectRef,
vm: &VirtualMachine,
-) -> PyResult {
+) -> PyResult {
+ validate_set_or_frozenset!(vm, zelf.type_pyref());
+ validate_set_or_frozenset!(vm, other.type_pyref());
let mut elements = HashMap::new();
- for element in zelf.elements.borrow().iter() {
- let value = vm.call_method(other.as_object(), "__contains__", vec![element.1.clone()])?;
+ for element in get_elements(&zelf).iter() {
+ let value = vm.call_method(&other, "__contains__", vec![element.1.clone()])?;
if !objbool::get_value(&value) {
elements.insert(element.0.clone(), element.1.clone());
}
}
- for element in other.elements.borrow().iter() {
- let value = vm.call_method(zelf.as_object(), "__contains__", vec![element.1.clone()])?;
+ for element in get_elements(&other).iter() {
+ let value = vm.call_method(&zelf, "__contains__", vec![element.1.clone()])?;
if !objbool::get_value(&value) {
elements.insert(element.0.clone(), element.1.clone());
}
}
- Ok(PySet {
- elements: RefCell::new(elements),
- })
+ create_set(vm, elements, zelf.type_pyref())
}
enum SetCombineOperation {
@@ -372,15 +423,17 @@ enum SetCombineOperation {
}
fn set_combine_inner(
- zelf: PySetRef,
- other: PySetRef,
+ zelf: PyObjectRef,
+ other: PyObjectRef,
vm: &VirtualMachine,
op: SetCombineOperation,
-) -> PyResult {
+) -> PyResult {
+ validate_set_or_frozenset!(vm, zelf.type_pyref());
+ validate_set_or_frozenset!(vm, other.type_pyref());
let mut elements = HashMap::new();
- for element in zelf.elements.borrow().iter() {
- let value = vm.call_method(other.as_object(), "__contains__", vec![element.1.clone()])?;
+ for element in get_elements(&zelf).iter() {
+ let value = vm.call_method(&other, "__contains__", vec![element.1.clone()])?;
let should_add = match op {
SetCombineOperation::Intersection => objbool::get_value(&value),
SetCombineOperation::Difference => !objbool::get_value(&value),
@@ -390,9 +443,7 @@ fn set_combine_inner(
}
}
- Ok(PySet {
- elements: RefCell::new(elements),
- })
+ create_set(vm, elements, zelf.type_pyref())
}
fn set_pop(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -614,6 +665,46 @@ pub fn init(context: &PyContext) {
frozenset(iterable) -> frozenset object\n\n\
Build an immutable unordered collection of unique elements.";
+ context.set_attr(frozenset_type, "__new__", context.new_rustfunc(set_new));
+ context.set_attr(frozenset_type, "__eq__", context.new_rustfunc(set_eq));
+ context.set_attr(frozenset_type, "__ge__", context.new_rustfunc(set_ge));
+ context.set_attr(frozenset_type, "__gt__", context.new_rustfunc(set_gt));
+ context.set_attr(frozenset_type, "__le__", context.new_rustfunc(set_le));
+ context.set_attr(frozenset_type, "__lt__", context.new_rustfunc(set_lt));
+ context.set_attr(frozenset_type, "issubset", context.new_rustfunc(set_le));
+ context.set_attr(frozenset_type, "issuperset", context.new_rustfunc(set_ge));
+ context.set_attr(frozenset_type, "union", context.new_rustfunc(set_union));
+ context.set_attr(frozenset_type, "__or__", context.new_rustfunc(set_union));
+ context.set_attr(
+ frozenset_type,
+ "intersection",
+ context.new_rustfunc(set_intersection),
+ );
+ context.set_attr(
+ frozenset_type,
+ "__and__",
+ context.new_rustfunc(set_intersection),
+ );
+ context.set_attr(
+ frozenset_type,
+ "difference",
+ context.new_rustfunc(set_difference),
+ );
+ context.set_attr(
+ frozenset_type,
+ "__sub__",
+ context.new_rustfunc(set_difference),
+ );
+ context.set_attr(
+ frozenset_type,
+ "symmetric_difference",
+ context.new_rustfunc(set_symmetric_difference),
+ );
+ context.set_attr(
+ frozenset_type,
+ "__xor__",
+ context.new_rustfunc(set_symmetric_difference),
+ );
context.set_attr(
frozenset_type,
"__contains__",
@@ -630,4 +721,5 @@ pub fn init(context: &PyContext) {
"__repr__",
context.new_rustfunc(frozenset_repr),
);
+ context.set_attr(frozenset_type, "copy", context.new_rustfunc(set_copy));
}
From dc05d5f94b43985245e5af0a505d0d0ce4e2a350 Mon Sep 17 00:00:00 2001
From: Aviv Palivoda
Date: Sat, 23 Mar 2019 11:06:18 +0200
Subject: [PATCH 004/658] Remove Refcell around PyFrozenSet elements
---
vm/src/obj/objset.rs | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs
index 8bb338d40..1d69d3bde 100644
--- a/vm/src/obj/objset.rs
+++ b/vm/src/obj/objset.rs
@@ -27,7 +27,7 @@ pub type PySetRef = PyRef;
#[derive(Default)]
pub struct PyFrozenSet {
- elements: RefCell>,
+ elements: HashMap,
}
pub type PyFrozenSetRef = PyRef;
@@ -61,7 +61,7 @@ pub fn get_elements(obj: &PyObjectRef) -> HashMap {
if let Some(set) = obj.payload::() {
return set.elements.borrow().clone();
} else if let Some(frozenset) = obj.payload::() {
- return frozenset.elements.borrow().clone();
+ return frozenset.elements.clone();
}
panic!("Not frozenset or set");
}
@@ -93,9 +93,7 @@ fn create_set(
))
} else if objtype::issubclass(&cls, &vm.ctx.frozenset_type()) {
Ok(PyObject::new(
- PyFrozenSet {
- elements: RefCell::new(elements),
- },
+ PyFrozenSet { elements: elements },
PyFrozenSet::class(vm).into_object(),
))
} else {
From 0aabe88c5dc1aceea51a579e3bb9c5551bd17949 Mon Sep 17 00:00:00 2001
From: coolreader18 <33094578+coolreader18@users.noreply.github.com>
Date: Sat, 23 Mar 2019 14:04:14 -0500
Subject: [PATCH 005/658] Put `browser` class methods into `impl` blocks
---
vm/src/vm.rs | 7 +-
wasm/lib/src/browser_module.rs | 239 +++++++++++++++------------------
wasm/lib/src/convert.rs | 14 +-
3 files changed, 123 insertions(+), 137 deletions(-)
diff --git a/vm/src/vm.rs b/vm/src/vm.rs
index 76b06ddfc..9cf4b98e0 100644
--- a/vm/src/vm.rs
+++ b/vm/src/vm.rs
@@ -111,7 +111,10 @@ impl VirtualMachine {
}
pub fn try_class(&self, module: &str, class: &str) -> PyResult {
- let class = self.get_attribute(self.import(module)?, class)?.downcast().expect("not a class");
+ let class = self
+ .get_attribute(self.import(module)?, class)?
+ .downcast()
+ .expect("not a class");
Ok(class)
}
@@ -122,7 +125,7 @@ impl VirtualMachine {
let class = self
.get_attribute(module.clone(), class)
.unwrap_or_else(|_| panic!("module {} has no class {}", module, class));
- class.downcast().expect("not a class");
+ class.downcast().expect("not a class")
}
/// Create a new python string object.
diff --git a/wasm/lib/src/browser_module.rs b/wasm/lib/src/browser_module.rs
index 0be52c43d..ce2d3d6c1 100644
--- a/wasm/lib/src/browser_module.rs
+++ b/wasm/lib/src/browser_module.rs
@@ -7,6 +7,7 @@ use wasm_bindgen_futures::{future_to_promise, JsFuture};
use rustpython_vm::function::{OptionalArg, PyFuncArgs};
use rustpython_vm::obj::{
+ objfunction::PyFunction,
objint,
objstr::{self, PyStringRef},
objtype::PyClassRef,
@@ -45,8 +46,6 @@ impl FetchResponseFormat {
fn browser_fetch(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(url, Some(vm.ctx.str_type()))]);
- let promise_type = vm.try_class("browser", "Promise")?;
-
let response_format =
args.get_optional_kwarg_with_type("response_format", vm.ctx.str_type(), vm)?;
let method = args.get_optional_kwarg_with_type("method", vm.ctx.str_type(), vm)?;
@@ -102,7 +101,9 @@ fn browser_fetch(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
})
.and_then(JsFuture::from);
- Ok(PyPromise::new_obj(promise_type, future_to_promise(future)))
+ Ok(PyPromise::new(future_to_promise(future))
+ .into_ref(vm)
+ .into_object())
}
fn browser_request_animation_frame(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -163,6 +164,7 @@ fn browser_cancel_animation_frame(vm: &VirtualMachine, args: PyFuncArgs) -> PyRe
pub struct PyPromise {
value: Promise,
}
+pub type PyPromiseRef = PyRef;
impl PyValue for PyPromise {
fn class(vm: &VirtualMachine) -> PyClassRef {
@@ -171,156 +173,135 @@ impl PyValue for PyPromise {
}
impl PyPromise {
- pub fn new_obj(promise_type: PyClassRef, value: Promise) -> PyObjectRef {
- PyObject::new(PyPromise { value }, promise_type.into_object())
+ pub fn new(value: Promise) -> PyPromise {
+ PyPromise { value }
}
-}
-
-pub fn get_promise_value(obj: &PyObjectRef) -> Promise {
- if let Some(promise) = obj.payload::() {
- return promise.value.clone();
+ pub fn value(&self) -> Promise {
+ self.value.clone()
}
- panic!("Inner error getting promise")
-}
-fn promise_then(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- let promise_type = vm.try_class("browser", "Promise")?;
- arg_check!(
- vm,
- args,
- required = [
- (zelf, Some(promise_type.clone())),
- (on_fulfill, Some(vm.ctx.function_type()))
- ],
- optional = [(on_reject, Some(vm.ctx.function_type()))]
- );
+ fn then(
+ zelf: PyPromiseRef,
+ on_fulfill: PyRef,
+ on_reject: OptionalArg>,
+ vm: &VirtualMachine,
+ ) -> PyResult {
+ let acc_vm = AccessibleVM::from(vm);
- let on_fulfill = on_fulfill.clone();
- let on_reject = on_reject.cloned();
-
- let acc_vm = AccessibleVM::from(vm);
-
- let promise = get_promise_value(zelf);
-
- let ret_future = JsFuture::from(promise).then(move |res| {
- let stored_vm = &acc_vm
- .upgrade()
- .expect("that the vm is valid when the promise resolves");
- let vm = &stored_vm.vm;
- let ret = match res {
- Ok(val) => {
- let val = convert::js_to_py(vm, val);
- vm.invoke(on_fulfill, PyFuncArgs::new(vec![val], vec![]))
- }
- Err(err) => {
- if let Some(on_reject) = on_reject {
- let err = convert::js_to_py(vm, err);
- vm.invoke(on_reject, PyFuncArgs::new(vec![err], vec![]))
- } else {
- return Err(err);
- }
- }
- };
- convert::pyresult_to_jsresult(vm, ret)
- });
-
- let ret_promise = future_to_promise(ret_future);
-
- Ok(PyPromise::new_obj(promise_type, ret_promise))
-}
-
-fn promise_catch(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- let promise_type = vm.try_class("browser", "Promise")?;
- arg_check!(
- vm,
- args,
- required = [
- (zelf, Some(promise_type.clone())),
- (on_reject, Some(vm.ctx.function_type()))
- ]
- );
-
- let on_reject = on_reject.clone();
-
- let acc_vm = AccessibleVM::from(vm);
-
- let promise = get_promise_value(zelf);
-
- let ret_future = JsFuture::from(promise).then(move |res| match res {
- Ok(val) => Ok(val),
- Err(err) => {
- let stored_vm = acc_vm
+ let ret_future = JsFuture::from(zelf.value.clone()).then(move |res| {
+ let stored_vm = &acc_vm
.upgrade()
.expect("that the vm is valid when the promise resolves");
let vm = &stored_vm.vm;
- let err = convert::js_to_py(vm, err);
- let res = vm.invoke(on_reject, PyFuncArgs::new(vec![err], vec![]));
- convert::pyresult_to_jsresult(vm, res)
- }
- });
+ let ret = match res {
+ Ok(val) => {
+ let val = convert::js_to_py(vm, val);
+ vm.invoke(on_fulfill.into_object(), PyFuncArgs::new(vec![val], vec![]))
+ }
+ Err(err) => {
+ if let OptionalArg::Present(on_reject) = on_reject {
+ let err = convert::js_to_py(vm, err);
+ vm.invoke(on_reject.into_object(), PyFuncArgs::new(vec![err], vec![]))
+ } else {
+ return Err(err);
+ }
+ }
+ };
+ convert::pyresult_to_jsresult(vm, ret)
+ });
- let ret_promise = future_to_promise(ret_future);
+ let ret_promise = future_to_promise(ret_future);
- Ok(PyPromise::new_obj(promise_type, ret_promise))
+ Ok(PyPromise::new(ret_promise).into_ref(vm))
+ }
+
+ fn catch(
+ zelf: PyPromiseRef,
+ on_reject: PyRef,
+ vm: &VirtualMachine,
+ ) -> PyResult {
+ let acc_vm = AccessibleVM::from(vm);
+
+ let ret_future = JsFuture::from(zelf.value.clone()).then(move |res| match res {
+ Ok(val) => Ok(val),
+ Err(err) => {
+ let stored_vm = acc_vm
+ .upgrade()
+ .expect("that the vm is valid when the promise resolves");
+ let vm = &stored_vm.vm;
+ let err = convert::js_to_py(vm, err);
+ let res = vm.invoke(on_reject.into_object(), PyFuncArgs::new(vec![err], vec![]));
+ convert::pyresult_to_jsresult(vm, res)
+ }
+ });
+
+ let ret_promise = future_to_promise(ret_future);
+
+ Ok(PyPromise::new(ret_promise).into_ref(vm))
+ }
}
#[derive(Debug)]
-struct PyDocument {
+struct Document {
doc: web_sys::Document,
}
-type PyDocumentRef = PyRef;
+type DocumentRef = PyRef;
-impl PyValue for PyDocument {
- fn class(vm: &VirtualMachine) -> PyObjectRef {
+impl PyValue for Document {
+ fn class(vm: &VirtualMachine) -> PyClassRef {
vm.class("browser", "Document")
}
}
-fn document_query(zelf: PyDocumentRef, query: PyStringRef, vm: &VirtualMachine) -> PyResult {
- let elem = zelf
- .doc
- .query_selector(&query.value)
- .map_err(|err| convert::js_py_typeerror(vm, err))?;
- let elem = match elem {
- Some(elem) => PyElement { elem }.into_ref(vm).into_object(),
- None => vm.get_none(),
- };
- Ok(elem)
+impl Document {
+ fn query(zelf: DocumentRef, query: PyStringRef, vm: &VirtualMachine) -> PyResult {
+ let elem = zelf
+ .doc
+ .query_selector(&query.value)
+ .map_err(|err| convert::js_py_typeerror(vm, err))?;
+ let elem = match elem {
+ Some(elem) => Element { elem }.into_ref(vm).into_object(),
+ None => vm.get_none(),
+ };
+ Ok(elem)
+ }
}
#[derive(Debug)]
-struct PyElement {
+struct Element {
elem: web_sys::Element,
}
-type PyElementRef = PyRef;
+type ElementRef = PyRef;
-impl PyValue for PyElement {
- fn class(vm: &VirtualMachine) -> PyObjectRef {
+impl PyValue for Element {
+ fn class(vm: &VirtualMachine) -> PyClassRef {
vm.class("browser", "Element")
}
}
-fn elem_get_attr(
- zelf: PyElementRef,
- attr: PyStringRef,
- default: OptionalArg,
- vm: &VirtualMachine,
-) -> PyObjectRef {
- match zelf.elem.get_attribute(&attr.value) {
- Some(s) => vm.new_str(s),
- None => default.into_option().unwrap_or_else(|| vm.get_none()),
+impl Element {
+ fn get_attr(
+ zelf: ElementRef,
+ attr: PyStringRef,
+ default: OptionalArg,
+ vm: &VirtualMachine,
+ ) -> PyObjectRef {
+ match zelf.elem.get_attribute(&attr.value) {
+ Some(s) => vm.new_str(s),
+ None => default.into_option().unwrap_or_else(|| vm.get_none()),
+ }
}
-}
-fn elem_set_attr(
- zelf: PyElementRef,
- attr: PyStringRef,
- value: PyStringRef,
- vm: &VirtualMachine,
-) -> PyResult<()> {
- zelf.elem
- .set_attribute(&attr.value, &value.value)
- .map_err(|err| convert::js_to_py(vm, err))
+ fn set_attr(
+ zelf: ElementRef,
+ attr: PyStringRef,
+ value: PyStringRef,
+ vm: &VirtualMachine,
+ ) -> PyResult<()> {
+ zelf.elem
+ .set_attribute(&attr.value, &value.value)
+ .map_err(|err| convert::js_to_py(vm, err))
+ }
}
fn browser_alert(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -370,24 +351,24 @@ fn browser_prompt(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
pub fn make_module(ctx: &PyContext) -> PyObjectRef {
let promise = py_class!(ctx, "Promise", ctx.object(), {
- "then" => ctx.new_rustfunc(promise_then),
- "catch" => ctx.new_rustfunc(promise_catch),
+ "then" => ctx.new_rustfunc(PyPromise::then),
+ "catch" => ctx.new_rustfunc(PyPromise::catch),
});
let document_class = py_class!(ctx, "Document", ctx.object(), {
- "query" => ctx.new_rustfunc(document_query),
+ "query" => ctx.new_rustfunc(Document::query),
});
let document = PyObject::new(
- PyDocument {
+ Document {
doc: window().document().expect("Document missing from window"),
},
- document_class.clone(),
+ document_class.clone().into_object(),
);
let element = py_class!(ctx, "Element", ctx.object(), {
- "get_attr" => ctx.new_rustfunc(elem_get_attr),
- "set_attr" => ctx.new_rustfunc(elem_set_attr),
+ "get_attr" => ctx.new_rustfunc(Element::get_attr),
+ "set_attr" => ctx.new_rustfunc(Element::set_attr),
});
py_module!(ctx, "browser", {
diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs
index 9c9e9f902..ecdb4b110 100644
--- a/wasm/lib/src/convert.rs
+++ b/wasm/lib/src/convert.rs
@@ -4,7 +4,7 @@ use wasm_bindgen::{closure::Closure, prelude::*, JsCast};
use rustpython_vm::function::PyFuncArgs;
use rustpython_vm::obj::{objbytes, objint, objsequence, objtype};
-use rustpython_vm::pyobject::{DictProtocol, PyObjectRef, PyResult};
+use rustpython_vm::pyobject::{DictProtocol, PyObjectRef, PyResult, PyValue};
use rustpython_vm::VirtualMachine;
use crate::browser_module;
@@ -115,9 +115,9 @@ pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue {
}
}
// the browser module might not be injected
- if let Ok(promise_type) = vm.try_class("browser", "Promise") {
- if objtype::isinstance(&py_obj, &promise_type) {
- return browser_module::get_promise_value(&py_obj).into();
+ if vm.try_class("browser", "Promise").is_ok() {
+ if let Some(py_prom) = py_obj.payload::() {
+ return py_prom.value().into();
}
}
@@ -159,8 +159,10 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
if js_val.is_object() {
if let Some(promise) = js_val.dyn_ref::() {
// the browser module might not be injected
- if let Ok(promise_type) = vm.try_class("browser", "Promise") {
- return browser_module::PyPromise::new_obj(promise_type, promise.clone());
+ if vm.try_class("browser", "Promise").is_ok() {
+ return browser_module::PyPromise::new(promise.clone())
+ .into_ref(vm)
+ .into_object();
}
}
if Array::is_array(&js_val) {
From 590b659548a090d08bb51bca46a4457cc560e9a8 Mon Sep 17 00:00:00 2001
From: Aviv Palivoda
Date: Sat, 23 Mar 2019 23:24:57 +0200
Subject: [PATCH 006/658] Change validate_set_or_frozenset to a function
---
vm/src/obj/objset.rs | 44 ++++++++++++++++++++------------------------
1 file changed, 20 insertions(+), 24 deletions(-)
diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs
index 1d69d3bde..300dc9bca 100644
--- a/vm/src/obj/objset.rs
+++ b/vm/src/obj/objset.rs
@@ -66,17 +66,13 @@ pub fn get_elements(obj: &PyObjectRef) -> HashMap {
panic!("Not frozenset or set");
}
-macro_rules! validate_set_or_frozenset {
- ( $vm:ident, $obj:expr ) => {
- if !(objtype::issubclass(&$obj, &$vm.ctx.set_type())
- || objtype::issubclass(&$obj, &$vm.ctx.frozenset_type()))
- {
- return Err($vm.new_type_error(format!(
- "{} is not a subtype of set or frozenset a",
- $obj.typ()
- )));
- }
- };
+fn validate_set_or_frozenset(vm: &VirtualMachine, cls: PyClassRef) -> PyResult<()> {
+ if !(objtype::issubclass(&cls, &vm.ctx.set_type())
+ || objtype::issubclass(&cls, &vm.ctx.frozenset_type()))
+ {
+ return Err(vm.new_type_error(format!("{} is not a subtype of set or frozenset", cls)));
+ }
+ Ok(())
}
fn create_set(
@@ -213,7 +209,7 @@ fn set_clear(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
/* Create a new object of sub-type of set */
fn set_new(cls: PyClassRef, iterable: OptionalArg, vm: &VirtualMachine) -> PyResult {
- validate_set_or_frozenset!(vm, cls);
+ validate_set_or_frozenset(vm, cls.clone())?;
let elements: HashMap = match iterable {
OptionalArg::Missing => HashMap::new(),
@@ -227,20 +223,20 @@ fn set_new(cls: PyClassRef, iterable: OptionalArg, vm: &VirtualMach
}
};
- create_set(vm, elements, cls)
+ create_set(vm, elements, cls.clone())
}
fn set_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
trace!("set.len called with: {:?}", args);
arg_check!(vm, args, required = [(s, None)]);
- validate_set_or_frozenset!(vm, s.type_pyref());
+ validate_set_or_frozenset(vm, s.type_pyref())?;
let elements = get_elements(s);
Ok(vm.context().new_int(elements.len()))
}
fn set_copy(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
trace!("set.copy called with: {:?}", obj);
- validate_set_or_frozenset!(vm, obj.type_pyref());
+ validate_set_or_frozenset(vm, obj.type_pyref())?;
let elements = get_elements(&obj).clone();
create_set(vm, elements, obj.type_pyref())
}
@@ -267,7 +263,7 @@ fn set_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
pub fn set_contains(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(set, None), (needle, None)]);
- validate_set_or_frozenset!(vm, &set.type_pyref());
+ validate_set_or_frozenset(vm, set.type_pyref())?;
for element in get_elements(set).iter() {
match vm._eq(needle.clone(), element.1.clone()) {
Ok(value) => {
@@ -335,8 +331,8 @@ fn set_compare_inner(
) -> PyResult {
arg_check!(vm, args, required = [(zelf, None), (other, None)]);
- validate_set_or_frozenset!(vm, zelf.type_pyref());
- validate_set_or_frozenset!(vm, other.type_pyref());
+ validate_set_or_frozenset(vm, zelf.type_pyref())?;
+ validate_set_or_frozenset(vm, other.type_pyref())?;
let get_zelf = |swap: bool| -> &PyObjectRef {
if swap {
@@ -372,8 +368,8 @@ fn set_compare_inner(
}
fn set_union(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
- validate_set_or_frozenset!(vm, zelf.type_pyref());
- validate_set_or_frozenset!(vm, other.type_pyref());
+ validate_set_or_frozenset(vm, zelf.type_pyref())?;
+ validate_set_or_frozenset(vm, other.type_pyref())?;
let mut elements = get_elements(&zelf).clone();
elements.extend(get_elements(&other).clone());
@@ -394,8 +390,8 @@ fn set_symmetric_difference(
other: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult {
- validate_set_or_frozenset!(vm, zelf.type_pyref());
- validate_set_or_frozenset!(vm, other.type_pyref());
+ validate_set_or_frozenset(vm, zelf.type_pyref())?;
+ validate_set_or_frozenset(vm, other.type_pyref())?;
let mut elements = HashMap::new();
for element in get_elements(&zelf).iter() {
@@ -426,8 +422,8 @@ fn set_combine_inner(
vm: &VirtualMachine,
op: SetCombineOperation,
) -> PyResult {
- validate_set_or_frozenset!(vm, zelf.type_pyref());
- validate_set_or_frozenset!(vm, other.type_pyref());
+ validate_set_or_frozenset(vm, zelf.type_pyref())?;
+ validate_set_or_frozenset(vm, other.type_pyref())?;
let mut elements = HashMap::new();
for element in get_elements(&zelf).iter() {
From 0f2889a0e5b861c57e97cec3fafc451818e2f1f7 Mon Sep 17 00:00:00 2001
From: coolreader18 <33094578+coolreader18@users.noreply.github.com>
Date: Sat, 23 Mar 2019 19:46:46 -0500
Subject: [PATCH 007/658] Fix weird rustfmt
---
vm/src/obj/objsuper.rs | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs
index 1920a73fe..17d015a5f 100644
--- a/vm/src/obj/objsuper.rs
+++ b/vm/src/obj/objsuper.rs
@@ -123,10 +123,8 @@ fn super_new(
match vm.get_locals().get_item(first_arg) {
Some(obj) => obj.clone(),
_ => {
- return Err(vm.new_type_error(format!(
- "super arguement {} was not supplied",
- first_arg
- )));
+ return Err(vm
+ .new_type_error(format!("super argument {} was not supplied", first_arg)));
}
}
} else {
From ec433cdbb91aa9babca4369906237e2db59eb3ff Mon Sep 17 00:00:00 2001
From: coolreader18 <33094578+coolreader18@users.noreply.github.com>
Date: Sat, 23 Mar 2019 22:17:21 -0500
Subject: [PATCH 008/658] Fix rustfmt again (?)
---
vm/src/obj/objsuper.rs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs
index 53e347b9f..c41cf183e 100644
--- a/vm/src/obj/objsuper.rs
+++ b/vm/src/obj/objsuper.rs
@@ -128,8 +128,9 @@ fn super_new(
match vm.get_locals().get_item(first_arg) {
Some(obj) => obj.clone(),
_ => {
- return Err(vm
- .new_type_error(format!("super argument {} was not supplied", first_arg)));
+ return Err(
+ vm.new_type_error(format!("super arguement {} was not supplied", first_arg))
+ );
}
}
} else {
From 12564da369a9b3388b12d01043cda43bb56027c3 Mon Sep 17 00:00:00 2001
From: coolreader18 <33094578+coolreader18@users.noreply.github.com>
Date: Sat, 23 Mar 2019 22:46:21 -0500
Subject: [PATCH 009/658] Rustfmt?
---
vm/src/obj/objsuper.rs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs
index c41cf183e..f04fb6605 100644
--- a/vm/src/obj/objsuper.rs
+++ b/vm/src/obj/objsuper.rs
@@ -128,9 +128,8 @@ fn super_new(
match vm.get_locals().get_item(first_arg) {
Some(obj) => obj.clone(),
_ => {
- return Err(
- vm.new_type_error(format!("super arguement {} was not supplied", first_arg))
- );
+ return Err(vm
+ .new_type_error(format!("super arguement {} was not supplied", first_arg)));
}
}
} else {
From 9a6f7aa8a1f58e346e1da4027a608c67d4dfc7ba Mon Sep 17 00:00:00 2001
From: Adrian Wielgosik
Date: Fri, 22 Mar 2019 19:12:33 +0100
Subject: [PATCH 010/658] Make PyRef::clone not require T implementing Clone
It seems to be a weird consequence of using PhantomData,
so I just rolled a custom Clone.
---
vm/src/obj/objmodule.rs | 2 +-
vm/src/obj/objnone.rs | 2 +-
vm/src/obj/objobject.rs | 2 +-
vm/src/obj/objtuple.rs | 1 -
vm/src/obj/objtype.rs | 2 +-
5 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/vm/src/obj/objmodule.rs b/vm/src/obj/objmodule.rs
index 2d1d8921e..58d8688db 100644
--- a/vm/src/obj/objmodule.rs
+++ b/vm/src/obj/objmodule.rs
@@ -3,7 +3,7 @@ use crate::obj::objtype::PyClassRef;
use crate::pyobject::{DictProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
use crate::vm::VirtualMachine;
-#[derive(Clone, Debug)]
+#[derive(Debug)]
pub struct PyModule {
pub name: String,
pub dict: PyObjectRef,
diff --git a/vm/src/obj/objnone.rs b/vm/src/obj/objnone.rs
index 7b0eefec2..840b00ecc 100644
--- a/vm/src/obj/objnone.rs
+++ b/vm/src/obj/objnone.rs
@@ -6,7 +6,7 @@ use crate::pyobject::{
};
use crate::vm::VirtualMachine;
-#[derive(Clone, Debug)]
+#[derive(Debug)]
pub struct PyNone;
pub type PyNoneRef = PyRef;
diff --git a/vm/src/obj/objobject.rs b/vm/src/obj/objobject.rs
index 84ba73fe6..46a90114d 100644
--- a/vm/src/obj/objobject.rs
+++ b/vm/src/obj/objobject.rs
@@ -11,7 +11,7 @@ use crate::pyobject::{
};
use crate::vm::VirtualMachine;
-#[derive(Clone, Debug)]
+#[derive(Debug)]
pub struct PyInstance;
impl PyValue for PyInstance {
diff --git a/vm/src/obj/objtuple.rs b/vm/src/obj/objtuple.rs
index e5bf5c1ee..a199e34b1 100644
--- a/vm/src/obj/objtuple.rs
+++ b/vm/src/obj/objtuple.rs
@@ -15,7 +15,6 @@ use super::objsequence::{
};
use super::objtype::{self, PyClassRef};
-#[derive(Default)]
pub struct PyTuple {
// TODO: shouldn't be public
// TODO: tuples are immutable, remove this RefCell
diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs
index 9d3c9fe49..a8dd3289a 100644
--- a/vm/src/obj/objtype.rs
+++ b/vm/src/obj/objtype.rs
@@ -16,7 +16,7 @@ use super::objstr::PyStringRef;
use super::objtuple::PyTuple;
use crate::obj::objdict::PyDictRef;
-#[derive(Clone, Debug)]
+#[derive(Debug)]
pub struct PyClass {
pub name: String,
pub mro: Vec,
From a895ab35aeadcdc3b6504b531104765221212e18 Mon Sep 17 00:00:00 2001
From: Adrian Wielgosik
Date: Fri, 22 Mar 2019 19:13:26 +0100
Subject: [PATCH 011/658] Make PyWeak::downgrade take a reference
---
vm/src/obj/objweakref.rs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/vm/src/obj/objweakref.rs b/vm/src/obj/objweakref.rs
index 3a71e3b63..685e32b70 100644
--- a/vm/src/obj/objweakref.rs
+++ b/vm/src/obj/objweakref.rs
@@ -11,9 +11,9 @@ pub struct PyWeak {
}
impl PyWeak {
- pub fn downgrade(obj: PyObjectRef) -> PyWeak {
+ pub fn downgrade(obj: &PyObjectRef) -> PyWeak {
PyWeak {
- referent: Rc::downgrade(&obj),
+ referent: Rc::downgrade(obj),
}
}
@@ -33,7 +33,7 @@ pub type PyWeakRef = PyRef;
impl PyWeakRef {
// TODO callbacks
fn create(cls: PyClassRef, referent: PyObjectRef, vm: &VirtualMachine) -> PyResult {
- PyWeak::downgrade(referent).into_ref_with_type(vm, cls)
+ PyWeak::downgrade(&referent).into_ref_with_type(vm, cls)
}
fn call(self, vm: &VirtualMachine) -> PyObjectRef {
From e39df6daefb3ba1dbdb4e3a75770da57c2572d99 Mon Sep 17 00:00:00 2001
From: Adrian Wielgosik
Date: Fri, 22 Mar 2019 19:18:33 +0100
Subject: [PATCH 012/658] Basic implementation of T.__subclasses__().
Ideally, the weak list should be updated whenever a type is removed,
and the list shouldn't be a Vec, but this should be good enough for
starters.
---
tests/snippets/types_snippet.py | 23 +++++++++++++++++++++++
vm/src/obj/objtype.rs | 26 ++++++++++++++++++++++++--
vm/src/pyobject.rs | 13 +++++++++++--
3 files changed, 58 insertions(+), 4 deletions(-)
diff --git a/tests/snippets/types_snippet.py b/tests/snippets/types_snippet.py
index ac715751e..f441552d1 100644
--- a/tests/snippets/types_snippet.py
+++ b/tests/snippets/types_snippet.py
@@ -26,3 +26,26 @@ assert None.__class__ is type(None)
assert isinstance(type, type)
assert issubclass(type, type)
+
+class A: pass
+class B(A): pass
+class C(A): pass
+class D(B, C): pass
+
+assert A.__subclasses__() == [B, C]
+assert B.__subclasses__() == [D]
+assert C.__subclasses__() == [D]
+assert D.__subclasses__() == []
+
+del D
+
+try: # gc sweep is needed here for CPython...
+ import gc; gc.collect()
+except: # ...while RustPython doesn't have `gc` yet.
+ pass
+
+assert B.__subclasses__() == []
+assert C.__subclasses__() == []
+
+assert type in object.__subclasses__()
+
diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs
index a8dd3289a..89bd8f34a 100644
--- a/vm/src/obj/objtype.rs
+++ b/vm/src/obj/objtype.rs
@@ -10,16 +10,18 @@ use crate::pyobject::{
use crate::vm::VirtualMachine;
use super::objdict;
+use super::objdict::PyDictRef;
use super::objlist::PyList;
use super::objproperty::PropertyBuilder;
use super::objstr::PyStringRef;
use super::objtuple::PyTuple;
-use crate::obj::objdict::PyDictRef;
+use super::objweakref::PyWeak;
#[derive(Debug)]
pub struct PyClass {
pub name: String,
pub mro: Vec,
+ pub subclasses: RefCell>,
}
impl fmt::Display for PyClass {
@@ -146,6 +148,17 @@ impl PyClassRef {
Err(vm.new_attribute_error(format!("{} has no attribute '{}'", self, name)))
}
}
+
+ fn subclasses(self, _vm: &VirtualMachine) -> PyList {
+ let mut subclasses = self.subclasses.borrow_mut();
+ subclasses.retain(|x| x.upgrade().is_some());
+ PyList::from(
+ subclasses
+ .iter()
+ .map(|x| x.upgrade().unwrap())
+ .collect::>(),
+ )
+ }
}
/*
@@ -168,6 +181,8 @@ pub fn init(ctx: &PyContext) {
"__repr__" => ctx.new_rustfunc(PyClassRef::repr),
"__prepare__" => ctx.new_rustfunc(PyClassRef::prepare),
"__getattribute__" => ctx.new_rustfunc(PyClassRef::getattribute),
+ "__subclasses__" => ctx.new_rustfunc(PyClassRef::subclasses),
+ "__getattribute__" => ctx.new_rustfunc(PyClassRef::getattribute),
"__instancecheck__" => ctx.new_rustfunc(PyClassRef::instance_check),
"__subclasscheck__" => ctx.new_rustfunc(PyClassRef::subclass_check),
"__doc__" => ctx.new_str(type_doc.to_string()),
@@ -352,17 +367,24 @@ pub fn new(
bases: Vec,
dict: HashMap,
) -> PyResult {
- let mros = bases.into_iter().map(|x| _mro(&x)).collect();
+ let mros = bases.iter().map(|x| _mro(&x)).collect();
let mro = linearise_mro(mros).unwrap();
let new_type = PyObject {
payload: PyClass {
name: String::from(name),
mro,
+ subclasses: RefCell::new(vec![]),
},
dict: Some(RefCell::new(dict)),
typ,
}
.into_ref();
+ for base in bases {
+ base.subclasses
+ .borrow_mut()
+ .push(PyWeak::downgrade(&new_type));
+ }
+
Ok(new_type.downcast().unwrap())
}
diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs
index da16e1ac8..e4488bdb4 100644
--- a/vm/src/pyobject.rs
+++ b/vm/src/pyobject.rs
@@ -183,13 +183,14 @@ fn init_type_hierarchy() -> (PyClassRef, PyClassRef) {
// and both `type` and `object are instances of `type`.
// to produce this circular dependency, we need an unsafe block.
// (and yes, this will never get dropped. TODO?)
- unsafe {
+ let (type_type, object_type) = unsafe {
let object_type = PyObject {
typ: mem::uninitialized(), // !
dict: Some(RefCell::new(PyAttributes::new())),
payload: PyClass {
name: String::from("object"),
mro: vec![],
+ subclasses: RefCell::new(vec![]),
},
}
.into_ref();
@@ -200,6 +201,7 @@ fn init_type_hierarchy() -> (PyClassRef, PyClassRef) {
payload: PyClass {
name: String::from("type"),
mro: vec![object_type.clone().downcast().unwrap()],
+ subclasses: RefCell::new(vec![]),
},
}
.into_ref();
@@ -214,7 +216,14 @@ fn init_type_hierarchy() -> (PyClassRef, PyClassRef) {
ptr::write(&mut (*type_type_ptr).typ, type_type.clone());
(type_type, object_type)
- }
+ };
+
+ object_type
+ .subclasses
+ .borrow_mut()
+ .push(objweakref::PyWeak::downgrade(&type_type.as_object()));
+
+ (type_type, object_type)
}
// Basic objects:
From d0c4fcb2fa65260c3eb72120cb303c8d1cbf7668 Mon Sep 17 00:00:00 2001
From: Windel Bouwman
Date: Sun, 24 Mar 2019 13:14:38 +0100
Subject: [PATCH 013/658] Doing what is needed for all our non-latin friends.
---
Cargo.lock | 1 +
parser/Cargo.toml | 2 +-
parser/src/lexer.rs | 611 +++++++++++++++++++----------------
src/main.rs | 2 +-
tests/snippets/unicode_fu.py | 13 +
5 files changed, 341 insertions(+), 288 deletions(-)
create mode 100644 tests/snippets/unicode_fu.py
diff --git a/Cargo.lock b/Cargo.lock
index 818d0af89..57dadb57b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -760,6 +760,7 @@ dependencies = [
"num-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
diff --git a/parser/Cargo.toml b/parser/Cargo.toml
index e57d42140..7545a27d4 100644
--- a/parser/Cargo.toml
+++ b/parser/Cargo.toml
@@ -14,4 +14,4 @@ log="0.4.1"
regex="0.2.2"
num-bigint = "0.2"
num-traits = "0.2"
-
+unicode-xid = "0.1.0"
diff --git a/parser/src/lexer.rs b/parser/src/lexer.rs
index 113f7afb1..db8fee2c7 100644
--- a/parser/src/lexer.rs
+++ b/parser/src/lexer.rs
@@ -1,12 +1,15 @@
//! This module takes care of lexing python source text. This means source
//! code is translated into separate tokens.
+extern crate unicode_xid;
+
pub use super::token::Tok;
use num_bigint::BigInt;
use num_traits::Num;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::str::FromStr;
+use unicode_xid::UnicodeXID;
#[derive(Clone, Copy, PartialEq, Debug)]
struct IndentationLevel {
@@ -300,7 +303,7 @@ where
}
}
- while self.is_char() {
+ while self.is_identifier_continuation() {
name.push(self.next_char().unwrap());
}
let end_pos = self.get_pos();
@@ -540,10 +543,21 @@ where
Ok((start_pos, tok, end_pos))
}
- fn is_char(&self) -> bool {
- match self.chr0 {
- Some('a'..='z') | Some('A'..='Z') | Some('_') | Some('0'..='9') => true,
- _ => false,
+ fn is_identifier_start(&self, c: char) -> bool {
+ match c {
+ 'a'..='z' | 'A'..='Z' | '_' => true,
+ c => UnicodeXID::is_xid_start(c),
+ }
+ }
+
+ fn is_identifier_continuation(&self) -> bool {
+ if let Some(c) = self.chr0 {
+ match c {
+ 'a'..='z' | 'A'..='Z' | '_' | '0'..='9' => true,
+ c => UnicodeXID::is_xid_continue(c),
+ }
+ } else {
+ false
}
}
@@ -686,347 +700,372 @@ where
}
}
- match self.chr0 {
- Some('0'..='9') => return Some(self.lex_number()),
- Some('_') | Some('a'..='z') | Some('A'..='Z') => {
+ // Check if we have some character:
+ if let Some(c) = self.chr0 {
+ // First check identifier:
+ if self.is_identifier_start(c) {
return Some(self.lex_identifier());
- }
- Some('#') => {
- self.lex_comment();
- continue;
- }
- Some('"') => {
- return Some(self.lex_string(false, false, false, false));
- }
- Some('\'') => {
- return Some(self.lex_string(false, false, false, false));
- }
- Some('=') => {
- let tok_start = self.get_pos();
- self.next_char();
- match self.chr0 {
- Some('=') => {
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::EqEqual, tok_end)));
+ } else {
+ match c {
+ '0'..='9' => return Some(self.lex_number()),
+ '#' => {
+ self.lex_comment();
+ continue;
}
- _ => {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Equal, tok_end)));
+ '"' => {
+ return Some(self.lex_string(false, false, false, false));
}
- }
- }
- Some('+') => {
- let tok_start = self.get_pos();
- self.next_char();
- if let Some('=') = self.chr0 {
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::PlusEqual, tok_end)));
- } else {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Plus, tok_end)));
- }
- }
- Some('*') => {
- let tok_start = self.get_pos();
- self.next_char();
- match self.chr0 {
- Some('=') => {
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::StarEqual, tok_end)));
+ '\'' => {
+ return Some(self.lex_string(false, false, false, false));
}
- Some('*') => {
+ '=' => {
+ let tok_start = self.get_pos();
self.next_char();
match self.chr0 {
Some('=') => {
self.next_char();
let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::DoubleStarEqual, tok_end)));
+ return Some(Ok((tok_start, Tok::EqEqual, tok_end)));
}
_ => {
let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::DoubleStar, tok_end)));
+ return Some(Ok((tok_start, Tok::Equal, tok_end)));
}
}
}
- _ => {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Star, tok_end)));
- }
- }
- }
- Some('/') => {
- let tok_start = self.get_pos();
- self.next_char();
- match self.chr0 {
- Some('=') => {
+ '+' => {
+ let tok_start = self.get_pos();
self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::SlashEqual, tok_end)));
+ if let Some('=') = self.chr0 {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::PlusEqual, tok_end)));
+ } else {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::Plus, tok_end)));
+ }
}
- Some('/') => {
+ '*' => {
+ let tok_start = self.get_pos();
self.next_char();
match self.chr0 {
Some('=') => {
self.next_char();
let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::DoubleSlashEqual, tok_end)));
+ return Some(Ok((tok_start, Tok::StarEqual, tok_end)));
+ }
+ Some('*') => {
+ self.next_char();
+ match self.chr0 {
+ Some('=') => {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((
+ tok_start,
+ Tok::DoubleStarEqual,
+ tok_end,
+ )));
+ }
+ _ => {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::DoubleStar, tok_end)));
+ }
+ }
}
_ => {
let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::DoubleSlash, tok_end)));
+ return Some(Ok((tok_start, Tok::Star, tok_end)));
}
}
}
- _ => {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Slash, tok_end)));
- }
- }
- }
- Some('%') => {
- let tok_start = self.get_pos();
- self.next_char();
- if let Some('=') = self.chr0 {
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::PercentEqual, tok_end)));
- } else {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Percent, tok_end)));
- }
- }
- Some('|') => {
- let tok_start = self.get_pos();
- self.next_char();
- if let Some('=') = self.chr0 {
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::VbarEqual, tok_end)));
- } else {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Vbar, tok_end)));
- }
- }
- Some('^') => {
- let tok_start = self.get_pos();
- self.next_char();
- if let Some('=') = self.chr0 {
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::CircumflexEqual, tok_end)));
- } else {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::CircumFlex, tok_end)));
- }
- }
- Some('&') => {
- let tok_start = self.get_pos();
- self.next_char();
- if let Some('=') = self.chr0 {
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::AmperEqual, tok_end)));
- } else {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Amper, tok_end)));
- }
- }
- Some('-') => {
- let tok_start = self.get_pos();
- self.next_char();
- match self.chr0 {
- Some('=') => {
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::MinusEqual, tok_end)));
- }
- Some('>') => {
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Rarrow, tok_end)));
- }
- _ => {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Minus, tok_end)));
- }
- }
- }
- Some('@') => {
- let tok_start = self.get_pos();
- self.next_char();
- if let Some('=') = self.chr0 {
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::AtEqual, tok_end)));
- } else {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::At, tok_end)));
- }
- }
- Some('!') => {
- let tok_start = self.get_pos();
- self.next_char();
- match self.chr0 {
- Some('=') => {
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::NotEqual, tok_end)));
- }
- _ => panic!("Invalid token '!'"),
- }
- }
- Some('~') => {
- return Some(self.eat_single_char(Tok::Tilde));
- }
- Some('(') => {
- let result = self.eat_single_char(Tok::Lpar);
- self.nesting += 1;
- return Some(result);
- }
- Some(')') => {
- let result = self.eat_single_char(Tok::Rpar);
- if self.nesting == 0 {
- return Some(Err(LexicalError::NestingError));
- }
- self.nesting -= 1;
- return Some(result);
- }
- Some('[') => {
- let result = self.eat_single_char(Tok::Lsqb);
- self.nesting += 1;
- return Some(result);
- }
- Some(']') => {
- let result = self.eat_single_char(Tok::Rsqb);
- if self.nesting == 0 {
- return Some(Err(LexicalError::NestingError));
- }
- self.nesting -= 1;
- return Some(result);
- }
- Some('{') => {
- let result = self.eat_single_char(Tok::Lbrace);
- self.nesting += 1;
- return Some(result);
- }
- Some('}') => {
- let result = self.eat_single_char(Tok::Rbrace);
- if self.nesting == 0 {
- return Some(Err(LexicalError::NestingError));
- }
- self.nesting -= 1;
- return Some(result);
- }
- Some(':') => {
- return Some(self.eat_single_char(Tok::Colon));
- }
- Some(';') => {
- return Some(self.eat_single_char(Tok::Semi));
- }
- Some('<') => {
- let tok_start = self.get_pos();
- self.next_char();
- match self.chr0 {
- Some('<') => {
+ '/' => {
+ let tok_start = self.get_pos();
self.next_char();
match self.chr0 {
Some('=') => {
self.next_char();
let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::LeftShiftEqual, tok_end)));
+ return Some(Ok((tok_start, Tok::SlashEqual, tok_end)));
+ }
+ Some('/') => {
+ self.next_char();
+ match self.chr0 {
+ Some('=') => {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((
+ tok_start,
+ Tok::DoubleSlashEqual,
+ tok_end,
+ )));
+ }
+ _ => {
+ let tok_end = self.get_pos();
+ return Some(Ok((
+ tok_start,
+ Tok::DoubleSlash,
+ tok_end,
+ )));
+ }
+ }
}
_ => {
let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::LeftShift, tok_end)));
+ return Some(Ok((tok_start, Tok::Slash, tok_end)));
}
}
}
- Some('=') => {
+ '%' => {
+ let tok_start = self.get_pos();
self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::LessEqual, tok_end)));
+ if let Some('=') = self.chr0 {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::PercentEqual, tok_end)));
+ } else {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::Percent, tok_end)));
+ }
}
- _ => {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Less, tok_end)));
+ '|' => {
+ let tok_start = self.get_pos();
+ self.next_char();
+ if let Some('=') = self.chr0 {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::VbarEqual, tok_end)));
+ } else {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::Vbar, tok_end)));
+ }
}
- }
- }
- Some('>') => {
- let tok_start = self.get_pos();
- self.next_char();
- match self.chr0 {
- Some('>') => {
+ '^' => {
+ let tok_start = self.get_pos();
+ self.next_char();
+ if let Some('=') = self.chr0 {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::CircumflexEqual, tok_end)));
+ } else {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::CircumFlex, tok_end)));
+ }
+ }
+ '&' => {
+ let tok_start = self.get_pos();
+ self.next_char();
+ if let Some('=') = self.chr0 {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::AmperEqual, tok_end)));
+ } else {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::Amper, tok_end)));
+ }
+ }
+ '-' => {
+ let tok_start = self.get_pos();
self.next_char();
match self.chr0 {
Some('=') => {
self.next_char();
let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::RightShiftEqual, tok_end)));
+ return Some(Ok((tok_start, Tok::MinusEqual, tok_end)));
+ }
+ Some('>') => {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::Rarrow, tok_end)));
}
_ => {
let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::RightShift, tok_end)));
+ return Some(Ok((tok_start, Tok::Minus, tok_end)));
}
}
}
- Some('=') => {
+ '@' => {
+ let tok_start = self.get_pos();
+ self.next_char();
+ if let Some('=') = self.chr0 {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::AtEqual, tok_end)));
+ } else {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::At, tok_end)));
+ }
+ }
+ '!' => {
+ let tok_start = self.get_pos();
+ self.next_char();
+ if let Some('=') = self.chr0 {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::NotEqual, tok_end)));
+ } else {
+ return Some(Err(LexicalError::UnrecognizedToken { tok: '!' }));
+ }
+ }
+ '~' => {
+ return Some(self.eat_single_char(Tok::Tilde));
+ }
+ '(' => {
+ let result = self.eat_single_char(Tok::Lpar);
+ self.nesting += 1;
+ return Some(result);
+ }
+ ')' => {
+ let result = self.eat_single_char(Tok::Rpar);
+ if self.nesting == 0 {
+ return Some(Err(LexicalError::NestingError));
+ }
+ self.nesting -= 1;
+ return Some(result);
+ }
+ '[' => {
+ let result = self.eat_single_char(Tok::Lsqb);
+ self.nesting += 1;
+ return Some(result);
+ }
+ ']' => {
+ let result = self.eat_single_char(Tok::Rsqb);
+ if self.nesting == 0 {
+ return Some(Err(LexicalError::NestingError));
+ }
+ self.nesting -= 1;
+ return Some(result);
+ }
+ '{' => {
+ let result = self.eat_single_char(Tok::Lbrace);
+ self.nesting += 1;
+ return Some(result);
+ }
+ '}' => {
+ let result = self.eat_single_char(Tok::Rbrace);
+ if self.nesting == 0 {
+ return Some(Err(LexicalError::NestingError));
+ }
+ self.nesting -= 1;
+ return Some(result);
+ }
+ ':' => {
+ return Some(self.eat_single_char(Tok::Colon));
+ }
+ ';' => {
+ return Some(self.eat_single_char(Tok::Semi));
+ }
+ '<' => {
+ let tok_start = self.get_pos();
+ self.next_char();
+ match self.chr0 {
+ Some('<') => {
+ self.next_char();
+ match self.chr0 {
+ Some('=') => {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((
+ tok_start,
+ Tok::LeftShiftEqual,
+ tok_end,
+ )));
+ }
+ _ => {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::LeftShift, tok_end)));
+ }
+ }
+ }
+ Some('=') => {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::LessEqual, tok_end)));
+ }
+ _ => {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::Less, tok_end)));
+ }
+ }
+ }
+ '>' => {
+ let tok_start = self.get_pos();
+ self.next_char();
+ match self.chr0 {
+ Some('>') => {
+ self.next_char();
+ match self.chr0 {
+ Some('=') => {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((
+ tok_start,
+ Tok::RightShiftEqual,
+ tok_end,
+ )));
+ }
+ _ => {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::RightShift, tok_end)));
+ }
+ }
+ }
+ Some('=') => {
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::GreaterEqual, tok_end)));
+ }
+ _ => {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::Greater, tok_end)));
+ }
+ }
+ }
+ ',' => {
+ let tok_start = self.get_pos();
self.next_char();
let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::GreaterEqual, tok_end)));
+ return Some(Ok((tok_start, Tok::Comma, tok_end)));
}
- _ => {
+ '.' => {
+ let tok_start = self.get_pos();
+ self.next_char();
+ if let (Some('.'), Some('.')) = (&self.chr0, &self.chr1) {
+ self.next_char();
+ self.next_char();
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::Ellipsis, tok_end)));
+ } else {
+ let tok_end = self.get_pos();
+ return Some(Ok((tok_start, Tok::Dot, tok_end)));
+ }
+ }
+ '\n' => {
+ let tok_start = self.get_pos();
+ self.next_char();
let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Greater, tok_end)));
- }
- }
- }
- Some(',') => {
- let tok_start = self.get_pos();
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Comma, tok_end)));
- }
- Some('.') => {
- let tok_start = self.get_pos();
- self.next_char();
- if let (Some('.'), Some('.')) = (&self.chr0, &self.chr1) {
- self.next_char();
- self.next_char();
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Ellipsis, tok_end)));
- } else {
- let tok_end = self.get_pos();
- return Some(Ok((tok_start, Tok::Dot, tok_end)));
- }
- }
- Some('\n') => {
- let tok_start = self.get_pos();
- self.next_char();
- let tok_end = self.get_pos();
- self.new_line();
+ self.new_line();
- // Depending on the nesting level, we emit newline or not:
- if self.nesting == 0 {
- self.at_begin_of_line = true;
- return Some(Ok((tok_start, Tok::Newline, tok_end)));
- } else {
- continue;
+ // Depending on the nesting level, we emit newline or not:
+ if self.nesting == 0 {
+ self.at_begin_of_line = true;
+ return Some(Ok((tok_start, Tok::Newline, tok_end)));
+ } else {
+ continue;
+ }
+ }
+ ' ' => {
+ // Skip whitespaces
+ self.next_char();
+ continue;
+ }
+ _ => {
+ let c = self.next_char();
+ return Some(Err(LexicalError::UnrecognizedToken { tok: c.unwrap() }));
+ } // Ignore all the rest..
}
}
- Some(' ') => {
- // Skip whitespaces
- self.next_char();
- continue;
- }
- None => return None,
- _ => {
- let c = self.next_char();
- return Some(Err(LexicalError::UnrecognizedToken { tok: c.unwrap() }));
- } // Ignore all the rest..
+ } else {
+ return None;
}
}
}
diff --git a/src/main.rs b/src/main.rs
index 70adf1008..750faf98a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -153,7 +153,7 @@ fn get_prompt(vm: &VirtualMachine, prompt_name: &str) -> String {
fn run_shell(vm: &VirtualMachine) -> PyResult {
println!(
- "Welcome to the magnificent Rust Python {} interpreter",
+ "Welcome to the magnificent Rust Python {} interpreter \u{1f631} \u{1f596}",
crate_version!()
);
let vars = vm.ctx.new_scope();
diff --git a/tests/snippets/unicode_fu.py b/tests/snippets/unicode_fu.py
new file mode 100644
index 000000000..96d5bf977
--- /dev/null
+++ b/tests/snippets/unicode_fu.py
@@ -0,0 +1,13 @@
+
+# Test the unicode support! 👋
+
+
+áš´=2
+
+assert áš´*8 == 16
+
+ᚴ="👋"
+
+c = áš´*3
+
+assert c == '👋👋👋'
From 565719dcdacaf83cfcaf7781b5b9437acb983270 Mon Sep 17 00:00:00 2001
From: coolreader18 <33094578+coolreader18@users.noreply.github.com>
Date: Sun, 24 Mar 2019 11:26:41 -0500
Subject: [PATCH 014/658] Update cargo dependencies
---
Cargo.lock | 730 +++++++++++++++++++++-------------------
wasm/lib/src/convert.rs | 13 +-
2 files changed, 398 insertions(+), 345 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 818d0af89..f3ea4ba4d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,10 +2,10 @@
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
-version = "0.6.4"
+version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -13,7 +13,7 @@ name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -27,15 +27,15 @@ dependencies = [
[[package]]
name = "arrayref"
-version = "0.3.4"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "arrayvec"
-version = "0.4.7"
+version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -52,39 +52,45 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "atty"
-version = "0.2.10"
+version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "autocfg"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "backtrace"
-version = "0.3.9"
+version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "backtrace-sys"
-version = "0.1.24"
+version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -110,7 +116,7 @@ name = "blake2-rfc"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -119,10 +125,15 @@ name = "block-buffer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "bumpalo"
+version = "2.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "byte-tools"
version = "0.2.0"
@@ -130,7 +141,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
-version = "1.2.6"
+version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -138,30 +149,30 @@ name = "caseless"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cc"
-version = "1.0.25"
+version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
-version = "0.1.3"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clap"
-version = "2.31.2"
+version = "2.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -186,7 +197,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "digest"
-version = "0.7.2"
+version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -194,12 +205,12 @@ dependencies = [
[[package]]
name = "dirs"
-version = "1.0.4"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -207,16 +218,16 @@ name = "docopt"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "either"
-version = "1.5.0"
+version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -226,46 +237,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "env_logger"
-version = "0.5.10"
+version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "env_logger"
-version = "0.6.0"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "failure"
-version = "0.1.2"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "failure_derive"
-version = "0.1.2"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -279,17 +290,8 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "fuchsia-zircon"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "fuchsia-zircon-sys"
-version = "0.3.3"
+name = "fuchsia-cprng"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -307,7 +309,7 @@ dependencies = [
[[package]]
name = "heck"
-version = "0.3.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -315,7 +317,7 @@ dependencies = [
[[package]]
name = "humantime"
-version = "1.1.1"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -323,23 +325,23 @@ dependencies = [
[[package]]
name = "itertools"
-version = "0.7.8"
+version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
-version = "0.4.2"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "js-sys"
-version = "0.3.6"
+version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "wasm-bindgen 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -360,17 +362,17 @@ dependencies = [
"atty 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ena 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop-snap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop-util 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -387,7 +389,7 @@ dependencies = [
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"ena 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop-util 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -404,24 +406,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
-version = "1.2.0"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lexical"
-version = "2.0.0"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "lexical-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lexical-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lexical-core"
-version = "0.3.1"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"stackvector 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -429,7 +431,7 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.42"
+version = "0.2.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -437,32 +439,26 @@ name = "log"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
-version = "0.4.2"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
-version = "2.0.1"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
-]
[[package]]
name = "new_debug_unreachable"
-version = "1.0.1"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
[[package]]
name = "nix"
@@ -470,28 +466,29 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nodrop"
-version = "0.1.12"
+version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "nom"
-version = "4.1.1"
+version = "4.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-bigint"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -519,7 +516,7 @@ name = "num-rational"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "num-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -545,19 +542,19 @@ dependencies = [
[[package]]
name = "phf_generator"
-version = "0.7.22"
+version = "0.7.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_shared"
-version = "0.7.22"
+version = "0.7.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -565,14 +562,6 @@ name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "proc-macro2"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "proc-macro2"
version = "0.4.27"
@@ -586,14 +575,6 @@ name = "quick-error"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "quote"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "quote"
version = "0.6.11"
@@ -604,42 +585,123 @@ dependencies = [
[[package]]
name = "rand"
-version = "0.4.2"
+version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
-version = "0.5.5"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rand_hc"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_isaac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_jitter"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_os"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "rand_core"
-version = "0.2.2"
+name = "rand_pcg"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "rand_core"
-version = "0.3.0"
+name = "rand_xorshift"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rdrand"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "redox_syscall"
-version = "0.1.40"
+version = "0.1.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -647,18 +709,18 @@ name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_users"
-version = "0.2.0"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -666,23 +728,23 @@ name = "regex"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
-version = "1.0.3"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -695,20 +757,20 @@ name = "regex-syntax"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
-version = "0.6.0"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-demangle"
-version = "0.1.9"
+version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -732,9 +794,9 @@ dependencies = [
name = "rustpython"
version = "0.0.1"
dependencies = [
- "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustpython_parser 0.0.1",
"rustpython_vm 0.1.0",
"rustyline 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -756,8 +818,8 @@ version = "0.0.1"
dependencies = [
"lalrpop 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop-util 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -767,24 +829,24 @@ name = "rustpython_vm"
version = "0.1.0"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"caseless 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lexical 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version_runtime 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustpython_derive 0.1.0",
"rustpython_parser 0.0.1",
- "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
"statrs 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -793,15 +855,15 @@ dependencies = [
name = "rustpython_wasm"
version = "0.1.0-pre-alpha.1"
dependencies = [
- "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "js-sys 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "js-sys 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustpython_parser 0.0.1",
"rustpython_vm 0.1.0",
- "wasm-bindgen 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-futures 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "web-sys 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-futures 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "web-sys 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -809,15 +871,15 @@ name = "rustyline"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -845,27 +907,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
-version = "1.0.66"
+version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
-version = "1.0.66"
+version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
-version = "1.0.26"
+version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -875,13 +937,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "siphasher"
-version = "0.2.2"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "smallvec"
+version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -907,7 +974,7 @@ name = "statrs"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -915,24 +982,24 @@ name = "string_cache"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
"precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "string_cache_codegen"
-version = "0.4.1"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -951,16 +1018,6 @@ name = "strsim"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "syn"
-version = "0.14.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "syn"
version = "0.15.29"
@@ -973,12 +1030,12 @@ dependencies = [
[[package]]
name = "synstructure"
-version = "0.9.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -991,14 +1048,6 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "termcolor"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "termcolor"
version = "1.0.4"
@@ -1012,14 +1061,14 @@ name = "termion"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "textwrap"
-version = "0.9.0"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1030,7 +1079,7 @@ name = "thread_local"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1040,13 +1089,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ucd-util"
-version = "0.1.1"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-normalization"
-version = "0.1.7"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "unicode-segmentation"
@@ -1073,7 +1125,7 @@ dependencies = [
[[package]]
name = "utf8-ranges"
-version = "1.0.0"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1086,6 +1138,11 @@ name = "vec_map"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "version_check"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "void"
version = "1.0.2"
@@ -1093,87 +1150,88 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wasm-bindgen"
-version = "0.2.29"
+version = "0.2.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "wasm-bindgen-macro 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-macro 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.29"
+version = "0.2.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bumpalo 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-shared 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-shared 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-futures"
-version = "0.3.6"
+version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "js-sys 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "js-sys 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.29"
+version = "0.2.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-macro-support 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-macro-support 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.29"
+version = "0.2.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-backend 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-shared 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-backend 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-shared 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.29"
+version = "0.2.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wasm-bindgen-webidl"
-version = "0.2.23"
+version = "0.2.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-backend 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-backend 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
"weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "web-sys"
-version = "0.3.6"
+version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "js-sys 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "js-sys 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasm-bindgen-webidl 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-webidl 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1181,7 +1239,7 @@ name = "weedle"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1191,7 +1249,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
-version = "0.3.5"
+version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1210,10 +1268,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-util"
-version = "0.1.1"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1221,21 +1279,13 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "wincolor"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "wincolor"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1244,93 +1294,100 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
-"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
+"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392"
-"checksum arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd1479b7c29641adbd35ff3b5c293922d696a92f25c8c975da3e0acbc87258f"
-"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
+"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
+"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
"checksum ascii-canvas 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b385d69402821a1c254533a011a312531cbcc0e3e24f19bbb4747a5a2daf37e2"
"checksum atty 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0fd4c0631f06448cc45a6bbb3b710ebb7ff8ccb96a0800c994afe23a70d5df2"
-"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
-"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
-"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
+"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
+"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
+"checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4"
+"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
+"checksum bumpalo 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "20bd7761c869bd69b5bd9dbbb1bd84de2f3970b764172efc41e67a06b508c56e"
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
-"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781"
+"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum caseless 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "808dab3318747be122cb31d36de18d4d1c81277a76f8332a02b81a3d73463d7f"
-"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
-"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18"
-"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
+"checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d"
+"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
+"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
"checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
-"checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603"
-"checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a"
+"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
+"checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
"checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
-"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
+"checksum either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c67353c641dc847124ea1902d69bd753dee9bb3beff9aa3662ecf86c971d1fac"
"checksum ena 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe5a5078ac8c506d3e4430763b1ba9b609b1286913e7d08e581d1c2de9b7e5"
-"checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a"
-"checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e"
-"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9"
-"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426"
+"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
+"checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a"
+"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
+"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
-"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
-"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
+"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b"
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
-"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
-"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
-"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
-"checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606"
-"checksum js-sys 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58cfec35fd4a94f3cf357d5cb7da71c71cd52720c2f2a7320090a8db5f06f655"
+"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
+"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
+"checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d"
+"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
+"checksum js-sys 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "d4bda84b98977341bb6ba1086ecbd9eab8bc929de0f2923c118baf76c21dd0c8"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lalrpop 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ba451f7bd819b7afc99d4cf4bdcd5a4861e64955ba9680ac70df3a50625ad6cf"
"checksum lalrpop-snap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "60013fd6be14317d43f47658b1440956a9ca48a9ed0257e0e0a59aac13e43a1f"
"checksum lalrpop-util 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "60c6c48ba857cd700673ce88907cadcdd7e2cd7783ed02378537c5ffd4f6460c"
-"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
-"checksum lexical 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e4fac65df7e751b57bb3a334c346239cb4ce2601907d698726ceeb82a54ba4ef"
-"checksum lexical-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "025babf624c0c2b4bed1373efd684d5d0b2eecd61138d26ec3eec77bf0f2e33d"
-"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
+"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
+"checksum lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c106ed999697325a540c43d66a8d5175668cd96d7eb0bdba03a3bd98256cd698"
+"checksum lexical-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e82e023e062f1d25f807ad182008fba1b46538e999f908a08cc0c29e084462e"
+"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
-"checksum log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6fddaa003a65722a7fb9e26b0ce95921fe4ba590542ced664d8ce2fa26f9f3ac"
-"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
-"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
+"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
+"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
+"checksum new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30"
"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17"
-"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
-"checksum nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c349f68f25f596b9f44cf0e7c69752a5c633b0550c3ff849518bfba0233774a"
-"checksum num-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "10b8423ea72ec64751198856a853e07b37087cfc9b53a87ecb19bff67b6d1320"
+"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
+"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
+"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718"
"checksum num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "107b9be86cd2481930688277b675b0114578227f034674726605b8a482d8baf8"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10"
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
-"checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998"
-"checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930"
+"checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
+"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
-"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
-"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
-"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
-"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
-"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
-"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
-"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
+"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
+"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
+"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
+"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
+"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0"
+"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
+"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
+"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832"
+"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
+"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
+"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
+"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
+"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
-"checksum redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "214a97e49be64fd2c86f568dd0cb2c757d2cc53de95b273b6ad0a1c908482f26"
+"checksum redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828"
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
-"checksum regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3d8c9f33201f46669484bacc312b00e7541bed6aaf296dffe2bb4e0ac6b8ce2a"
+"checksum regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53ee8cfdddb2e0291adfb9f13d31d3bbe0a03c9a402c01b1e24188d86c35b24f"
"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e"
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
-"checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b"
-"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
+"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861"
+"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum rustc_version_runtime 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6de8ecd7fad7731f306f69b6e10ec5a3178c61e464dcc06979427aa4cc891145"
"checksum rustyline 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6010155119d53aac4f5b987cb8f6ea913d0d64d9b237da36f8f96a90cb3f5385"
@@ -1338,55 +1395,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a2d9a9ac5120e0f768801ca2b58ad6eec929dc9d1d616c162f208869c2ce95"
-"checksum serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "0a90213fa7e0f5eac3f7afe2d5ff6b088af515052cc7303bd68c7e3b91a3fb79"
-"checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae"
+"checksum serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "92514fb95f900c9b5126e32d020f5c6d40564c27a5ea6d1d7d9f157a96623560"
+"checksum serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6eabf4b5914e88e24eea240bb7c9f9a2cbc1bbbe8d961d381975ec3c6b806c"
+"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
"checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0"
-"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
+"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
+"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3"
"checksum stackvector 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c049c77bf85fbc036484c97b008276d539d9ebff9dfbde37b632ebcd5b8746b6"
"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5"
"checksum statrs 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "10102ac8d55e35db2b3fafc26f81ba8647da2e15879ab686a67e6d19af2685e8"
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
-"checksum string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35293b05cf1494e8ddd042a7df6756bf18d07f42d234f32e71dce8a7aabb0191"
+"checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
-"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
"checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2"
-"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
+"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
-"checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83"
"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
-"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
+"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
-"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
-"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
+"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
+"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426"
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
-"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
+"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
"checksum utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
+"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
-"checksum wasm-bindgen 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "91f95b8f30407b9ca0c2de157281d3828bbed1fc1f55bea6eb54f40c52ec75ec"
-"checksum wasm-bindgen-backend 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "ab7c242ebcb45bae45340986c48d1853eb2c1c52ff551f7724951b62a2c51429"
-"checksum wasm-bindgen-futures 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d1784e7401a90119b2a4e8ec9c8d37c3594c3e3bb9ba24533ee1969eebaf0485"
-"checksum wasm-bindgen-macro 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "6e353f83716dec9a3597b5719ef88cb6c9e461ec16528f38aa023d3224b4e569"
-"checksum wasm-bindgen-macro-support 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "3cc90b65fe69c3dd5a09684517dc79f42b847baa2d479c234d125e0a629d9b0a"
-"checksum wasm-bindgen-shared 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "a71a37df4f5845025f96f279d20bbe5b19cbcb77f5410a3a90c6c544d889a162"
-"checksum wasm-bindgen-webidl 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)" = "b064b8b2336b5a6bf5f31bc95fc1310842395df29877d910cb6f8f791070f319"
-"checksum web-sys 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d7c588c2e5a091bc4532c5a87032955f9133b644e868b54d08ead0185dcc5b9"
+"checksum wasm-bindgen 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "9742fc4860f47bede1090a5e4b0cfc33afcd70cfdf45dd28f2cfb02d4662b0dd"
+"checksum wasm-bindgen-backend 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d7f35ecbb4180513cdb9b298543321bcb278670730415cbb3205ff2c66a477"
+"checksum wasm-bindgen-futures 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "67bfbec85e48e8915b6acfa1c4d90b770ce033c96dc2067688f3bccd00d3b9e1"
+"checksum wasm-bindgen-macro 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "e3c86b06bcd28e92e87d2c2ad208889b2f69ea33f79810b91ef660cc3de65a4c"
+"checksum wasm-bindgen-macro-support 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "81d7338dd8c67e193d8ef18e5802dc03d8710456baa792c1c2e66847e57fd389"
+"checksum wasm-bindgen-shared 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "0d57c3b66f2f3e4d96b50f49b7b7e2f4cfcddc88b15744433c98c5c105b26672"
+"checksum wasm-bindgen-webidl 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "fc7052a577eefce17a439edfce5c2eedc8432fe7457bbe949624cdf946233fa7"
+"checksum web-sys 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "72d02003924c77af871ad74216f828b6e32af776cbb3f5dab3dcde2f2713c012"
"checksum weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26a4c67f132386d965390b8a734d5d10adbcd30eb5cc74bd9229af8b83f10044"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
-"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
+"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-"checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab"
+"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-"checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767"
"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba"
"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs
index ecdb4b110..909955b6d 100644
--- a/wasm/lib/src/convert.rs
+++ b/wasm/lib/src/convert.rs
@@ -125,12 +125,10 @@ pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue {
|| objtype::isinstance(&py_obj, &vm.ctx.bytearray_type())
{
let bytes = objbytes::get_value(&py_obj);
- let arr = Uint8Array::new_with_length(bytes.len() as u32);
- for (i, byte) in bytes.iter().enumerate() {
- Reflect::set(&arr, &(i as u32).into(), &(*byte).into())
- .expect("setting Uint8Array value failed");
+ unsafe {
+ let view = Uint8Array::view(&bytes);
+ view.slice(0, bytes.len() as u32).into()
}
- arr.into()
} else {
match vm.serialize(&py_obj) {
Ok(json) => js_sys::JSON::parse(&json).unwrap_or(JsValue::UNDEFINED),
@@ -182,9 +180,8 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
.cloned()
.unwrap_or_else(|| js_val.unchecked_ref::().buffer()),
);
- let mut vec = Vec::with_capacity(u8_array.length() as usize);
- // TODO: use Uint8Array::copy_to once updating js_sys doesn't break everything
- u8_array.for_each(&mut |byte, _, _| vec.push(byte));
+ let mut vec = vec![0; u8_array.length() as usize];
+ u8_array.copy_to(&mut vec);
vm.ctx.new_bytes(vec)
} else {
let dict = vm.new_dict();
From c2e1e9b0dc0a4180a1ccb8c8bb5a4c7e5dee27c2 Mon Sep 17 00:00:00 2001
From: Joey
Date: Sun, 24 Mar 2019 08:51:26 -0700
Subject: [PATCH 015/658] Convert range to new args style
---
vm/src/obj/objint.rs | 7 +
vm/src/obj/objrange.rs | 322 ++++++++++++++++-------------------------
2 files changed, 129 insertions(+), 200 deletions(-)
diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs
index 7c19968da..345fe90c3 100644
--- a/vm/src/obj/objint.rs
+++ b/vm/src/obj/objint.rs
@@ -1,3 +1,4 @@
+use std::fmt;
use std::hash::{Hash, Hasher};
use num_bigint::{BigInt, ToBigInt};
@@ -22,6 +23,12 @@ pub struct PyInt {
pub value: BigInt,
}
+impl fmt::Display for PyInt {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ BigInt::fmt(&self.value, f)
+ }
+}
+
pub type PyIntRef = PyRef;
impl PyInt {
diff --git a/vm/src/obj/objrange.rs b/vm/src/obj/objrange.rs
index 468490eea..9ae2fcd54 100644
--- a/vm/src/obj/objrange.rs
+++ b/vm/src/obj/objrange.rs
@@ -3,17 +3,15 @@ use std::ops::Mul;
use num_bigint::{BigInt, Sign};
use num_integer::Integer;
-use num_traits::{One, Signed, ToPrimitive, Zero};
+use num_traits::{One, Signed, Zero};
use crate::function::{OptionalArg, PyFuncArgs};
-use crate::pyobject::{
- Either, PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
-};
+use crate::pyobject::{Either, PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue};
use crate::vm::VirtualMachine;
-use super::objint::{self, PyInt, PyIntRef};
+use super::objint::{PyInt, PyIntRef};
use super::objslice::PySliceRef;
-use super::objtype::{self, PyClassRef};
+use super::objtype::PyClassRef;
#[derive(Debug, Clone)]
pub struct PyRange {
@@ -31,26 +29,6 @@ impl PyValue for PyRange {
}
impl PyRange {
- #[inline]
- pub fn try_len(&self) -> Option {
- match self.step.sign() {
- Sign::Plus if self.start < self.stop => ((&self.stop - &self.start - 1usize)
- / &self.step)
- .to_usize()
- .map(|sz| sz + 1),
- Sign::Minus if self.start > self.stop => ((&self.start - &self.stop - 1usize)
- / (-&self.step))
- .to_usize()
- .map(|sz| sz + 1),
- _ => Some(0),
- }
- }
-
- #[inline]
- pub fn len(&self) -> usize {
- self.try_len().unwrap()
- }
-
#[inline]
fn offset(&self, value: &BigInt) -> Option {
match self.step.sign() {
@@ -60,14 +38,6 @@ impl PyRange {
}
}
- #[inline]
- pub fn contains(&self, value: &BigInt) -> bool {
- match self.offset(value) {
- Some(ref offset) => offset.is_multiple_of(&self.step),
- None => false,
- }
- }
-
#[inline]
pub fn index_of(&self, value: &BigInt) -> Option {
match self.offset(value) {
@@ -78,15 +48,6 @@ impl PyRange {
}
}
- #[inline]
- pub fn count(&self, value: &BigInt) -> usize {
- if self.index_of(value).is_some() {
- 1
- } else {
- 0
- }
- }
-
#[inline]
pub fn is_empty(&self) -> bool {
(self.start <= self.stop && self.step.is_negative())
@@ -113,40 +74,6 @@ impl PyRange {
None
}
}
-
- #[inline]
- pub fn reversed(&self) -> Self {
- // compute the last element that is actually contained within the range
- // this is the new start
- let remainder = ((&self.stop - &self.start) % &self.step).abs();
- let start = if remainder.is_zero() {
- &self.stop - &self.step
- } else {
- &self.stop - &remainder
- };
-
- match self.step.sign() {
- Sign::Plus => PyRange {
- start,
- stop: &self.start - 1,
- step: -&self.step,
- },
- Sign::Minus => PyRange {
- start,
- stop: &self.start + 1,
- step: -&self.step,
- },
- Sign::NoSign => unreachable!(),
- }
- }
-
- pub fn repr(&self) -> String {
- if self.step == BigInt::one() {
- format!("range({}, {})", self.start, self.stop)
- } else {
- format!("range({}, {}, {})", self.start, self.stop, self.step)
- }
- }
}
pub fn get_value(obj: &PyObjectRef) -> PyRange {
@@ -165,20 +92,20 @@ pub fn init(context: &PyContext) {
When step is given, it specifies the increment (or decrement).";
extend_class!(context, range_type, {
- "__bool__" => context.new_rustfunc(range_bool),
- "__contains__" => context.new_rustfunc(range_contains),
+ "__bool__" => context.new_rustfunc(PyRangeRef::bool),
+ "__contains__" => context.new_rustfunc(PyRangeRef::contains),
"__doc__" => context.new_str(range_doc.to_string()),
"__getitem__" => context.new_rustfunc(PyRangeRef::getitem),
- "__iter__" => context.new_rustfunc(range_iter),
- "__len__" => context.new_rustfunc(range_len),
+ "__iter__" => context.new_rustfunc(PyRangeRef::iter),
+ "__len__" => context.new_rustfunc(PyRangeRef::len),
"__new__" => context.new_rustfunc(range_new),
- "__repr__" => context.new_rustfunc(range_repr),
- "__reversed__" => context.new_rustfunc(range_reversed),
- "count" => context.new_rustfunc(range_count),
- "index" => context.new_rustfunc(range_index),
- "start" => context.new_property(range_start),
- "step" => context.new_property(range_step),
- "stop" => context.new_property(range_stop)
+ "__repr__" => context.new_rustfunc(PyRangeRef::repr),
+ "__reversed__" => context.new_rustfunc(PyRangeRef::reversed),
+ "count" => context.new_rustfunc(PyRangeRef::count),
+ "index" => context.new_rustfunc(PyRangeRef::index),
+ "start" => context.new_property(PyRangeRef::start),
+ "stop" => context.new_property(PyRangeRef::stop),
+ "step" => context.new_property(PyRangeRef::step),
});
}
@@ -212,6 +139,113 @@ impl PyRangeRef {
.into_ref_with_type(vm, cls)
}
+ fn start(self, _vm: &VirtualMachine) -> BigInt {
+ self.start.clone()
+ }
+
+ fn stop(self, _vm: &VirtualMachine) -> BigInt {
+ self.stop.clone()
+ }
+
+ fn step(self, _vm: &VirtualMachine) -> BigInt {
+ self.step.clone()
+ }
+
+ fn iter(self: PyRangeRef, _vm: &VirtualMachine) -> PyIteratorValue {
+ PyIteratorValue {
+ position: Cell::new(0),
+ iterated_obj: self.into_object(),
+ }
+ }
+
+ fn reversed(self: PyRangeRef, vm: &VirtualMachine) -> PyIteratorValue {
+ // compute the last element that is actually contained within the range
+ // this is the new start
+ let remainder = ((&self.stop - &self.start) % &self.step).abs();
+ let start = if remainder.is_zero() {
+ &self.stop - &self.step
+ } else {
+ &self.stop - &remainder
+ };
+
+ let reversed = match self.step.sign() {
+ Sign::Plus => PyRange {
+ start,
+ stop: &self.start - 1,
+ step: -&self.step,
+ },
+ Sign::Minus => PyRange {
+ start,
+ stop: &self.start + 1,
+ step: -&self.step,
+ },
+ Sign::NoSign => unreachable!(),
+ };
+ PyIteratorValue {
+ position: Cell::new(0),
+ iterated_obj: reversed.into_ref(vm).into_object(),
+ }
+ }
+
+ fn len(self, _vm: &VirtualMachine) -> PyInt {
+ match self.step.sign() {
+ Sign::Plus if self.start < self.stop => {
+ PyInt::new((&self.stop - &self.start - 1usize) / &self.step + 1)
+ }
+ Sign::Minus if self.start > self.stop => {
+ PyInt::new((&self.start - &self.stop - 1usize) / (-&self.step) + 1)
+ }
+ Sign::Plus | Sign::Minus => PyInt::new(0),
+ Sign::NoSign => unreachable!(),
+ }
+ }
+
+ fn repr(self, _vm: &VirtualMachine) -> String {
+ if self.step.is_one() {
+ format!("range({}, {})", self.start, self.stop)
+ } else {
+ format!("range({}, {}, {})", self.start, self.stop, self.step)
+ }
+ }
+
+ fn bool(self, _vm: &VirtualMachine) -> bool {
+ !self.is_empty()
+ }
+
+ fn contains(self, needle: PyObjectRef, _vm: &VirtualMachine) -> bool {
+ if let Ok(int) = needle.downcast::() {
+ match self.offset(&int.value) {
+ Some(ref offset) => offset.is_multiple_of(&self.step),
+ None => false,
+ }
+ } else {
+ false
+ }
+ }
+
+ fn index(self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
+ if let Ok(int) = needle.downcast::() {
+ match self.index_of(&int.value) {
+ Some(idx) => Ok(PyInt::new(idx)),
+ None => Err(vm.new_value_error(format!("{} is not in range", int))),
+ }
+ } else {
+ Err(vm.new_value_error("sequence.index(x): x not in sequence".to_string()))
+ }
+ }
+
+ fn count(self, item: PyObjectRef, _vm: &VirtualMachine) -> PyInt {
+ if let Ok(int) = item.downcast::() {
+ if self.index_of(&int.value).is_some() {
+ PyInt::new(1)
+ } else {
+ PyInt::new(0)
+ }
+ } else {
+ PyInt::new(0)
+ }
+ }
+
fn getitem(self, subscript: Either, vm: &VirtualMachine) -> PyResult {
match subscript {
Either::A(index) => {
@@ -271,115 +305,3 @@ fn range_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(range.into_object())
}
-
-fn range_iter(range: PyRangeRef, _vm: &VirtualMachine) -> PyIteratorValue {
- PyIteratorValue {
- position: Cell::new(0),
- iterated_obj: range.into_object(),
- }
-}
-
-fn range_reversed(zelf: PyRangeRef, vm: &VirtualMachine) -> PyIteratorValue {
- let range = zelf.reversed();
-
- PyIteratorValue {
- position: Cell::new(0),
- iterated_obj: range.into_ref(vm).into_object(),
- }
-}
-
-fn range_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
-
- if let Some(len) = get_value(zelf).try_len() {
- Ok(vm.ctx.new_int(len))
- } else {
- Err(vm.new_overflow_error("Python int too large to convert to Rust usize".to_string()))
- }
-}
-
-fn range_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
-
- let repr = get_value(zelf).repr();
-
- Ok(vm.ctx.new_str(repr))
-}
-
-fn range_bool(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
-
- let len = get_value(zelf).len();
-
- Ok(vm.ctx.new_bool(len > 0))
-}
-
-fn range_contains(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(
- vm,
- args,
- required = [(zelf, Some(vm.ctx.range_type())), (needle, None)]
- );
-
- let range = get_value(zelf);
-
- let result = if objtype::isinstance(needle, &vm.ctx.int_type()) {
- range.contains(&objint::get_value(needle))
- } else {
- false
- };
-
- Ok(vm.ctx.new_bool(result))
-}
-
-fn range_index(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(
- vm,
- args,
- required = [(zelf, Some(vm.ctx.range_type())), (needle, None)]
- );
-
- let range = get_value(zelf);
-
- if objtype::isinstance(needle, &vm.ctx.int_type()) {
- let needle = objint::get_value(needle);
-
- match range.index_of(&needle) {
- Some(idx) => Ok(vm.ctx.new_int(idx)),
- None => Err(vm.new_value_error(format!("{} is not in range", needle))),
- }
- } else {
- Err(vm.new_value_error("sequence.index(x): x not in sequence".to_string()))
- }
-}
-
-fn range_count(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(
- vm,
- args,
- required = [(zelf, Some(vm.ctx.range_type())), (item, None)]
- );
-
- let range = get_value(zelf);
-
- if objtype::isinstance(item, &vm.ctx.int_type()) {
- Ok(vm.ctx.new_int(range.count(&objint::get_value(item))))
- } else {
- Ok(vm.ctx.new_int(0))
- }
-}
-
-fn range_start(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
- Ok(vm.ctx.new_int(get_value(zelf).start))
-}
-
-fn range_stop(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
- Ok(vm.ctx.new_int(get_value(zelf).stop))
-}
-
-fn range_step(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
- Ok(vm.ctx.new_int(get_value(zelf).step))
-}
From 9a0113deedde20c7791f6c07936dc3e0c4b21e40 Mon Sep 17 00:00:00 2001
From: Joey
Date: Sun, 24 Mar 2019 09:57:26 -0700
Subject: [PATCH 016/658] range: represent w/ int refs
---
tests/snippets/builtin_range.py | 4 ++
vm/src/obj/objint.rs | 4 ++
vm/src/obj/objrange.rs | 122 +++++++++++++++++---------------
3 files changed, 73 insertions(+), 57 deletions(-)
diff --git a/tests/snippets/builtin_range.py b/tests/snippets/builtin_range.py
index 89014880c..2ea71f7a7 100644
--- a/tests/snippets/builtin_range.py
+++ b/tests/snippets/builtin_range.py
@@ -50,3 +50,7 @@ assert 'foo' not in range(10)
assert list(reversed(range(5))) == [4, 3, 2, 1, 0]
assert list(reversed(range(5, 0, -1))) == [1, 2, 3, 4, 5]
assert list(reversed(range(1,10,5))) == [6, 1]
+
+# range retains the original int refs
+i = 2**64
+assert range(i).stop is i
diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs
index 345fe90c3..fddc759bc 100644
--- a/vm/src/obj/objint.rs
+++ b/vm/src/obj/objint.rs
@@ -35,6 +35,10 @@ impl PyInt {
pub fn new>(i: T) -> Self {
PyInt { value: i.into() }
}
+
+ pub fn as_bigint(&self) -> &BigInt {
+ &self.value
+ }
}
impl IntoPyObject for BigInt {
diff --git a/vm/src/obj/objrange.rs b/vm/src/obj/objrange.rs
index 9ae2fcd54..380754b5f 100644
--- a/vm/src/obj/objrange.rs
+++ b/vm/src/obj/objrange.rs
@@ -15,11 +15,9 @@ use super::objtype::PyClassRef;
#[derive(Debug, Clone)]
pub struct PyRange {
- // Unfortunately Rust's built in range type doesn't support things like indexing
- // or ranges where start > end so we need to roll our own.
- pub start: BigInt,
- pub stop: BigInt,
- pub step: BigInt,
+ pub start: PyIntRef,
+ pub stop: PyIntRef,
+ pub step: PyIntRef,
}
impl PyValue for PyRange {
@@ -31,32 +29,36 @@ impl PyValue for PyRange {
impl PyRange {
#[inline]
fn offset(&self, value: &BigInt) -> Option {
- match self.step.sign() {
- Sign::Plus if *value >= self.start && *value < self.stop => Some(value - &self.start),
- Sign::Minus if *value <= self.start && *value > self.stop => Some(&self.start - value),
+ let start = self.start.as_bigint();
+ let stop = self.stop.as_bigint();
+ let step = self.step.as_bigint();
+ match step.sign() {
+ Sign::Plus if value >= start && value < stop => Some(value - start),
+ Sign::Minus if value <= self.start.as_bigint() && value > stop => Some(start - value),
_ => None,
}
}
#[inline]
pub fn index_of(&self, value: &BigInt) -> Option {
+ let step = self.step.as_bigint();
match self.offset(value) {
- Some(ref offset) if offset.is_multiple_of(&self.step) => {
- Some((offset / &self.step).abs())
- }
+ Some(ref offset) if offset.is_multiple_of(step) => Some((offset / step).abs()),
Some(_) | None => None,
}
}
#[inline]
pub fn is_empty(&self) -> bool {
- (self.start <= self.stop && self.step.is_negative())
- || (self.start >= self.stop && self.step.is_positive())
+ let start = self.start.as_bigint();
+ let stop = self.stop.as_bigint();
+ let step = self.step.as_bigint();
+ (start <= stop && step.is_negative()) || (start >= stop && step.is_positive())
}
#[inline]
pub fn forward(&self) -> bool {
- self.start < self.stop
+ self.start.as_bigint() < self.stop.as_bigint()
}
#[inline]
@@ -64,10 +66,14 @@ impl PyRange {
where
&'a BigInt: Mul,
{
- let result = &self.start + &self.step * index;
+ let start = self.start.as_bigint();
+ let stop = self.stop.as_bigint();
+ let step = self.step.as_bigint();
- if (self.forward() && !self.is_empty() && result < self.stop)
- || (!self.forward() && !self.is_empty() && result > self.stop)
+ let result = start + step * index;
+
+ if (self.forward() && !self.is_empty() && &result < stop)
+ || (!self.forward() && !self.is_empty() && &result > stop)
{
Some(result)
} else {
@@ -114,9 +120,9 @@ type PyRangeRef = PyRef;
impl PyRangeRef {
fn new(cls: PyClassRef, stop: PyIntRef, vm: &VirtualMachine) -> PyResult {
PyRange {
- start: Zero::zero(),
- stop: stop.value.clone(),
- step: One::one(),
+ start: PyInt::new(BigInt::zero()).into_ref(vm),
+ stop: stop.clone(),
+ step: PyInt::new(BigInt::one()).into_ref(vm),
}
.into_ref_with_type(vm, cls)
}
@@ -129,25 +135,24 @@ impl PyRangeRef {
vm: &VirtualMachine,
) -> PyResult {
PyRange {
- start: start.value.clone(),
- stop: stop.value.clone(),
+ start: start,
+ stop: stop,
step: step
.into_option()
- .map(|i| i.value.clone())
- .unwrap_or_else(One::one),
+ .unwrap_or_else(|| PyInt::new(BigInt::one()).into_ref(vm)),
}
.into_ref_with_type(vm, cls)
}
- fn start(self, _vm: &VirtualMachine) -> BigInt {
+ fn start(self, _vm: &VirtualMachine) -> PyIntRef {
self.start.clone()
}
- fn stop(self, _vm: &VirtualMachine) -> BigInt {
+ fn stop(self, _vm: &VirtualMachine) -> PyIntRef {
self.stop.clone()
}
- fn step(self, _vm: &VirtualMachine) -> BigInt {
+ fn step(self, _vm: &VirtualMachine) -> PyIntRef {
self.step.clone()
}
@@ -159,28 +164,31 @@ impl PyRangeRef {
}
fn reversed(self: PyRangeRef, vm: &VirtualMachine) -> PyIteratorValue {
+ let start = self.start.as_bigint();
+ let stop = self.stop.as_bigint();
+ let step = self.step.as_bigint();
+
// compute the last element that is actually contained within the range
// this is the new start
- let remainder = ((&self.stop - &self.start) % &self.step).abs();
- let start = if remainder.is_zero() {
- &self.stop - &self.step
+ let remainder = ((stop - start) % step).abs();
+ let new_start = if remainder.is_zero() {
+ stop - step
} else {
- &self.stop - &remainder
+ stop - &remainder
};
- let reversed = match self.step.sign() {
- Sign::Plus => PyRange {
- start,
- stop: &self.start - 1,
- step: -&self.step,
- },
- Sign::Minus => PyRange {
- start,
- stop: &self.start + 1,
- step: -&self.step,
- },
+ let new_stop: BigInt = match step.sign() {
+ Sign::Plus => start - 1,
+ Sign::Minus => start + 1,
Sign::NoSign => unreachable!(),
};
+
+ let reversed = PyRange {
+ start: PyInt::new(new_start).into_ref(vm),
+ stop: PyInt::new(new_stop).into_ref(vm),
+ step: PyInt::new(-step).into_ref(vm),
+ };
+
PyIteratorValue {
position: Cell::new(0),
iterated_obj: reversed.into_ref(vm).into_object(),
@@ -188,20 +196,20 @@ impl PyRangeRef {
}
fn len(self, _vm: &VirtualMachine) -> PyInt {
- match self.step.sign() {
- Sign::Plus if self.start < self.stop => {
- PyInt::new((&self.stop - &self.start - 1usize) / &self.step + 1)
- }
- Sign::Minus if self.start > self.stop => {
- PyInt::new((&self.start - &self.stop - 1usize) / (-&self.step) + 1)
- }
+ let start = self.start.as_bigint();
+ let stop = self.stop.as_bigint();
+ let step = self.step.as_bigint();
+
+ match step.sign() {
+ Sign::Plus if start < stop => PyInt::new((stop - start - 1usize) / step + 1),
+ Sign::Minus if start > stop => PyInt::new((start - stop - 1usize) / (-step) + 1),
Sign::Plus | Sign::Minus => PyInt::new(0),
Sign::NoSign => unreachable!(),
}
}
fn repr(self, _vm: &VirtualMachine) -> String {
- if self.step.is_one() {
+ if self.step.as_bigint().is_one() {
format!("range({}, {})", self.start, self.stop)
} else {
format!("range({}, {}, {})", self.start, self.stop, self.step)
@@ -215,7 +223,7 @@ impl PyRangeRef {
fn contains(self, needle: PyObjectRef, _vm: &VirtualMachine) -> bool {
if let Ok(int) = needle.downcast::() {
match self.offset(&int.value) {
- Some(ref offset) => offset.is_multiple_of(&self.step),
+ Some(ref offset) => offset.is_multiple_of(self.step.as_bigint()),
None => false,
}
} else {
@@ -256,9 +264,9 @@ impl PyRangeRef {
}
}
Either::B(slice) => {
- let new_start = if let Some(int) = slice.start.clone() {
+ let new_start = if let Some(int) = slice.start.as_ref() {
if let Some(i) = self.get(int) {
- i
+ PyInt::new(i).into_ref(vm)
} else {
self.start.clone()
}
@@ -266,9 +274,9 @@ impl PyRangeRef {
self.start.clone()
};
- let new_end = if let Some(int) = slice.stop.clone() {
+ let new_end = if let Some(int) = slice.stop.as_ref() {
if let Some(i) = self.get(int) {
- i
+ PyInt::new(i).into_ref(vm)
} else {
self.stop.clone()
}
@@ -276,8 +284,8 @@ impl PyRangeRef {
self.stop.clone()
};
- let new_step = if let Some(int) = slice.step.clone() {
- int * self.step.clone()
+ let new_step = if let Some(int) = slice.step.as_ref() {
+ PyInt::new(int * self.step.as_bigint()).into_ref(vm)
} else {
self.step.clone()
};
From f2d562a4ccf4b3ae4d6bf6bf3f9e6d157d95ce29 Mon Sep 17 00:00:00 2001
From: Joey
Date: Sun, 24 Mar 2019 10:05:25 -0700
Subject: [PATCH 017/658] pyint: use as_bigint() everywhere
---
vm/src/frame.rs | 2 +-
vm/src/obj/objbool.rs | 4 ++--
vm/src/obj/objenumerate.rs | 2 +-
vm/src/obj/objint.rs | 3 +--
vm/src/obj/objrange.rs | 8 ++++----
vm/src/obj/objsequence.rs | 2 +-
6 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/vm/src/frame.rs b/vm/src/frame.rs
index 2a0951ab3..b9e6cf965 100644
--- a/vm/src/frame.rs
+++ b/vm/src/frame.rs
@@ -413,7 +413,7 @@ impl Frame {
if x.is(&vm.ctx.none()) {
None
} else if let Some(i) = x.payload::() {
- Some(i.value.clone())
+ Some(i.as_bigint().clone())
} else {
panic!("Expect Int or None as BUILD_SLICE arguments")
}
diff --git a/vm/src/obj/objbool.rs b/vm/src/obj/objbool.rs
index e21a3a329..d4ef4b0fb 100644
--- a/vm/src/obj/objbool.rs
+++ b/vm/src/obj/objbool.rs
@@ -25,7 +25,7 @@ pub fn boolval(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult {
Ok(if let Ok(f) = vm.get_method(obj.clone(), "__bool__") {
let bool_res = vm.invoke(f, PyFuncArgs::default())?;
match bool_res.payload::() {
- Some(i) => !i.value.is_zero(),
+ Some(i) => !i.as_bigint().is_zero(),
None => return Err(vm.new_type_error(String::from("TypeError"))),
}
} else {
@@ -59,7 +59,7 @@ pub fn not(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult {
// Retrieve inner int value:
pub fn get_value(obj: &PyObjectRef) -> bool {
- !obj.payload::().unwrap().value.is_zero()
+ !obj.payload::().unwrap().as_bigint().is_zero()
}
fn bool_repr(vm: &VirtualMachine, args: PyFuncArgs) -> Result {
diff --git a/vm/src/obj/objenumerate.rs b/vm/src/obj/objenumerate.rs
index 0b0e5d448..68d1e49f6 100644
--- a/vm/src/obj/objenumerate.rs
+++ b/vm/src/obj/objenumerate.rs
@@ -32,7 +32,7 @@ fn enumerate_new(
vm: &VirtualMachine,
) -> PyResult {
let counter = match start {
- OptionalArg::Present(start) => start.value.clone(),
+ OptionalArg::Present(start) => start.as_bigint().clone(),
OptionalArg::Missing => BigInt::zero(),
};
diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs
index fddc759bc..dd40f06a4 100644
--- a/vm/src/obj/objint.rs
+++ b/vm/src/obj/objint.rs
@@ -19,8 +19,7 @@ use crate::obj::objtype::PyClassRef;
#[derive(Debug)]
pub struct PyInt {
- // TODO: shouldn't be public
- pub value: BigInt,
+ value: BigInt,
}
impl fmt::Display for PyInt {
diff --git a/vm/src/obj/objrange.rs b/vm/src/obj/objrange.rs
index 380754b5f..04c9c273b 100644
--- a/vm/src/obj/objrange.rs
+++ b/vm/src/obj/objrange.rs
@@ -222,7 +222,7 @@ impl PyRangeRef {
fn contains(self, needle: PyObjectRef, _vm: &VirtualMachine) -> bool {
if let Ok(int) = needle.downcast::() {
- match self.offset(&int.value) {
+ match self.offset(int.as_bigint()) {
Some(ref offset) => offset.is_multiple_of(self.step.as_bigint()),
None => false,
}
@@ -233,7 +233,7 @@ impl PyRangeRef {
fn index(self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if let Ok(int) = needle.downcast::() {
- match self.index_of(&int.value) {
+ match self.index_of(int.as_bigint()) {
Some(idx) => Ok(PyInt::new(idx)),
None => Err(vm.new_value_error(format!("{} is not in range", int))),
}
@@ -244,7 +244,7 @@ impl PyRangeRef {
fn count(self, item: PyObjectRef, _vm: &VirtualMachine) -> PyInt {
if let Ok(int) = item.downcast::() {
- if self.index_of(&int.value).is_some() {
+ if self.index_of(int.as_bigint()).is_some() {
PyInt::new(1)
} else {
PyInt::new(0)
@@ -257,7 +257,7 @@ impl PyRangeRef {
fn getitem(self, subscript: Either, vm: &VirtualMachine) -> PyResult {
match subscript {
Either::A(index) => {
- if let Some(value) = self.get(index.value.clone()) {
+ if let Some(value) = self.get(index.as_bigint()) {
Ok(PyInt::new(value).into_ref(vm).into_object())
} else {
Err(vm.new_index_error("range object index out of range".to_string()))
diff --git a/vm/src/obj/objsequence.rs b/vm/src/obj/objsequence.rs
index 83d0f9f9f..b8d91e590 100644
--- a/vm/src/obj/objsequence.rs
+++ b/vm/src/obj/objsequence.rs
@@ -144,7 +144,7 @@ pub fn get_item(
subscript: PyObjectRef,
) -> PyResult {
if let Some(i) = subscript.payload::() {
- return match i.value.to_i32() {
+ return match i.as_bigint().to_i32() {
Some(value) => {
if let Some(pos_index) = elements.to_vec().get_pos(value) {
let obj = elements[pos_index].clone();
From ca11e7dea79ed413138ee85acdd06b1070801ae6 Mon Sep 17 00:00:00 2001
From: Windel Bouwman
Date: Sun, 24 Mar 2019 20:16:38 +0100
Subject: [PATCH 018/658] Add support for emoji as name.
---
Cargo.lock | 42 ++++++++++++++++++++++++++++++++++++++++++
parser/Cargo.toml | 1 +
parser/src/lexer.rs | 24 +++++++++++++++++-------
3 files changed, 60 insertions(+), 7 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 57dadb57b..6193772c4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -760,6 +760,7 @@ dependencies = [
"num-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unic-emoji-char 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1044,6 +1045,42 @@ name = "ucd-util"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "unic-char-property"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unic-char-range 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unic-char-range"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "unic-common"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "unic-emoji-char"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unic-char-property 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unic-char-range 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unic-ucd-version 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unic-ucd-version"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unic-common 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "unicode-normalization"
version = "0.1.7"
@@ -1364,6 +1401,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
+"checksum unic-char-property 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
+"checksum unic-char-range 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
+"checksum unic-common 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
+"checksum unic-emoji-char 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b07221e68897210270a38bde4babb655869637af0f69407f96053a34f76494d"
+"checksum unic-ucd-version 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
diff --git a/parser/Cargo.toml b/parser/Cargo.toml
index 7545a27d4..f2f8e5a6b 100644
--- a/parser/Cargo.toml
+++ b/parser/Cargo.toml
@@ -15,3 +15,4 @@ regex="0.2.2"
num-bigint = "0.2"
num-traits = "0.2"
unicode-xid = "0.1.0"
+unic-emoji-char = "0.9.0"
diff --git a/parser/src/lexer.rs b/parser/src/lexer.rs
index db8fee2c7..defa5e232 100644
--- a/parser/src/lexer.rs
+++ b/parser/src/lexer.rs
@@ -1,6 +1,7 @@
//! This module takes care of lexing python source text. This means source
//! code is translated into separate tokens.
+extern crate unic_emoji_char;
extern crate unicode_xid;
pub use super::token::Tok;
@@ -9,6 +10,7 @@ use num_traits::Num;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::str::FromStr;
+use unic_emoji_char::is_emoji_presentation;
use unicode_xid::UnicodeXID;
#[derive(Clone, Copy, PartialEq, Debug)]
@@ -545,7 +547,7 @@ where
fn is_identifier_start(&self, c: char) -> bool {
match c {
- 'a'..='z' | 'A'..='Z' | '_' => true,
+ '_' => true,
c => UnicodeXID::is_xid_start(c),
}
}
@@ -553,7 +555,7 @@ where
fn is_identifier_continuation(&self) -> bool {
if let Some(c) = self.chr0 {
match c {
- 'a'..='z' | 'A'..='Z' | '_' | '0'..='9' => true,
+ '_' | '0'..='9' => true,
c => UnicodeXID::is_xid_continue(c),
}
} else {
@@ -705,6 +707,18 @@ where
// First check identifier:
if self.is_identifier_start(c) {
return Some(self.lex_identifier());
+ } else if is_emoji_presentation(c) {
+ let tok_start = self.get_pos();
+ self.next_char();
+ let tok_end = self.get_pos();
+ println!("Emoji: {}", c);
+ return Some(Ok((
+ tok_start,
+ Tok::Name {
+ name: c.to_string(),
+ },
+ tok_end,
+ )));
} else {
match c {
'0'..='9' => return Some(self.lex_number()),
@@ -801,11 +815,7 @@ where
}
_ => {
let tok_end = self.get_pos();
- return Some(Ok((
- tok_start,
- Tok::DoubleSlash,
- tok_end,
- )));
+ return Some(Ok((tok_start, Tok::DoubleSlash, tok_end)));
}
}
}
From 3562b8f59c2eccb034ac5c0f3de7638fcd586140 Mon Sep 17 00:00:00 2001
From: Adam Kelly
Date: Mon, 25 Mar 2019 11:21:01 +0000
Subject: [PATCH 019/658] Store class attributes inside PyClass struct.
---
vm/src/obj/objtype.rs | 65 ++++++++++++++++++++++---------------------
vm/src/pyobject.rs | 12 ++++++--
2 files changed, 42 insertions(+), 35 deletions(-)
diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs
index 89bd8f34a..6399d68c9 100644
--- a/vm/src/obj/objtype.rs
+++ b/vm/src/obj/objtype.rs
@@ -22,6 +22,7 @@ pub struct PyClass {
pub name: String,
pub mro: Vec,
pub subclasses: RefCell>,
+ pub attributes: RefCell,
}
impl fmt::Display for PyClass {
@@ -149,6 +150,25 @@ impl PyClassRef {
}
}
+ fn set_attr(
+ self,
+ attr_name: PyStringRef,
+ value: PyObjectRef,
+ vm: &VirtualMachine,
+ ) -> PyResult<()> {
+ if let Some(attr) = class_get_attr(&self.type_pyref(), &attr_name.value) {
+ if let Some(descriptor) = class_get_attr(&attr.type_pyref(), "__set__") {
+ vm.invoke(descriptor, vec![attr, self.into_object(), value])?;
+ return Ok(());
+ }
+ }
+
+ self.attributes
+ .borrow_mut()
+ .insert(attr_name.to_string(), value);
+ Ok(())
+ }
+
fn subclasses(self, _vm: &VirtualMachine) -> PyList {
let mut subclasses = self.subclasses.borrow_mut();
subclasses.retain(|x| x.upgrade().is_some());
@@ -181,6 +201,7 @@ pub fn init(ctx: &PyContext) {
"__repr__" => ctx.new_rustfunc(PyClassRef::repr),
"__prepare__" => ctx.new_rustfunc(PyClassRef::prepare),
"__getattribute__" => ctx.new_rustfunc(PyClassRef::getattribute),
+ "__setattr__" => ctx.new_rustfunc(PyClassRef::set_attr),
"__subclasses__" => ctx.new_rustfunc(PyClassRef::subclasses),
"__getattribute__" => ctx.new_rustfunc(PyClassRef::getattribute),
"__instancecheck__" => ctx.new_rustfunc(PyClassRef::instance_check),
@@ -260,32 +281,13 @@ pub fn type_call(class: PyClassRef, args: Args, kwargs: KwArgs, vm: &VirtualMach
Ok(obj)
}
-// Very private helper function for class_get_attr
-fn class_get_attr_in_dict(class: &PyClassRef, attr_name: &str) -> Option {
- if let Some(ref dict) = class.as_object().dict {
- dict.borrow().get(attr_name).cloned()
- } else {
- panic!("Only classes should be in MRO!");
- }
-}
-
-// Very private helper function for class_has_attr
-fn class_has_attr_in_dict(class: &PyClassRef, attr_name: &str) -> bool {
- if let Some(ref dict) = class.as_object().dict {
- dict.borrow().contains_key(attr_name)
- } else {
- panic!("All classes are expected to have dicts!");
- }
-}
-
// This is the internal get_attr implementation for fast lookup on a class.
-pub fn class_get_attr(zelf: &PyClassRef, attr_name: &str) -> Option {
- let mro = &zelf.mro;
- if let Some(item) = class_get_attr_in_dict(zelf, attr_name) {
+pub fn class_get_attr(class: &PyClassRef, attr_name: &str) -> Option {
+ if let Some(item) = class.attributes.borrow().get(attr_name).cloned() {
return Some(item);
}
- for class in mro {
- if let Some(item) = class_get_attr_in_dict(class, attr_name) {
+ for class in &class.mro {
+ if let Some(item) = class.attributes.borrow().get(attr_name).cloned() {
return Some(item);
}
}
@@ -293,12 +295,12 @@ pub fn class_get_attr(zelf: &PyClassRef, attr_name: &str) -> Option
}
// This is the internal has_attr implementation for fast lookup on a class.
-pub fn class_has_attr(zelf: &PyClassRef, attr_name: &str) -> bool {
- class_has_attr_in_dict(zelf, attr_name)
- || zelf
+pub fn class_has_attr(class: &PyClassRef, attr_name: &str) -> bool {
+ class.attributes.borrow().contains_key(attr_name)
+ || class
.mro
.iter()
- .any(|d| class_has_attr_in_dict(d, attr_name))
+ .any(|c| c.attributes.borrow().contains_key(attr_name))
}
pub fn get_attributes(cls: PyClassRef) -> PyAttributes {
@@ -309,10 +311,8 @@ pub fn get_attributes(cls: PyClassRef) -> PyAttributes {
base_classes.reverse();
for bc in base_classes {
- if let Some(ref dict) = &bc.as_object().dict {
- for (name, value) in dict.borrow().iter() {
- attributes.insert(name.to_string(), value.clone());
- }
+ for (name, value) in bc.attributes.borrow().iter() {
+ attributes.insert(name.to_string(), value.clone());
}
}
@@ -374,8 +374,9 @@ pub fn new(
name: String::from(name),
mro,
subclasses: RefCell::new(vec![]),
+ attributes: RefCell::new(dict),
},
- dict: Some(RefCell::new(dict)),
+ dict: None,
typ,
}
.into_ref();
diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs
index e4488bdb4..81fec3406 100644
--- a/vm/src/pyobject.rs
+++ b/vm/src/pyobject.rs
@@ -186,22 +186,24 @@ fn init_type_hierarchy() -> (PyClassRef, PyClassRef) {
let (type_type, object_type) = unsafe {
let object_type = PyObject {
typ: mem::uninitialized(), // !
- dict: Some(RefCell::new(PyAttributes::new())),
+ dict: None,
payload: PyClass {
name: String::from("object"),
mro: vec![],
subclasses: RefCell::new(vec![]),
+ attributes: RefCell::new(PyAttributes::new()),
},
}
.into_ref();
let type_type = PyObject {
typ: mem::uninitialized(), // !
- dict: Some(RefCell::new(PyAttributes::new())),
+ dict: None,
payload: PyClass {
name: String::from("type"),
mro: vec![object_type.clone().downcast().unwrap()],
subclasses: RefCell::new(vec![]),
+ attributes: RefCell::new(PyAttributes::new()),
},
}
.into_ref();
@@ -655,7 +657,11 @@ impl PyContext {
value: V,
) {
let obj = obj.into();
- if let Some(PyModule { ref dict, .. }) = obj.payload::() {
+ if let Some(PyClass { ref attributes, .. }) = obj.payload::() {
+ attributes
+ .borrow_mut()
+ .insert(attr_name.to_string(), value.into());
+ } else if let Some(PyModule { ref dict, .. }) = obj.payload::() {
dict.set_item(self, attr_name, value.into())
} else if let Some(ref dict) = obj.dict {
dict.borrow_mut()
From 17c3f9f024f79f972b20f019c4464b9b2a28593b Mon Sep 17 00:00:00 2001
From: Adam Kelly
Date: Mon, 25 Mar 2019 16:34:07 +0000
Subject: [PATCH 020/658] builtin_locals can just return a reference to the
locals dict.
---
vm/src/builtins.rs | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs
index 9dfe7afd6..acd0719d8 100644
--- a/vm/src/builtins.rs
+++ b/vm/src/builtins.rs
@@ -11,7 +11,6 @@ use num_traits::{Signed, ToPrimitive};
use crate::compile;
use crate::import::import_module;
use crate::obj::objbool;
-use crate::obj::objdict;
use crate::obj::objint;
use crate::obj::objiter;
use crate::obj::objstr::{self, PyStringRef};
@@ -29,14 +28,7 @@ use crate::obj::objcode::PyCodeRef;
use crate::stdlib::io::io_open;
fn get_locals(vm: &VirtualMachine) -> PyObjectRef {
- let d = vm.new_dict();
- // TODO: implement dict_iter_items?
- let locals = vm.get_locals();
- let key_value_pairs = objdict::get_key_value_pairs(&locals);
- for (key, value) in key_value_pairs {
- objdict::set_item(&d, vm, &key, &value);
- }
- d
+ vm.get_locals()
}
fn dir_locals(vm: &VirtualMachine) -> PyObjectRef {
From 602f2a83da41a4f9d857a8abd55fd581117ab016 Mon Sep 17 00:00:00 2001
From: Adrian Wielgosik
Date: Mon, 25 Mar 2019 17:35:21 +0100
Subject: [PATCH 021/658] Update grcov
---
tests/.travis-runner.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/.travis-runner.sh b/tests/.travis-runner.sh
index 8a004d3b1..36b9f43ac 100755
--- a/tests/.travis-runner.sh
+++ b/tests/.travis-runner.sh
@@ -31,7 +31,7 @@ then
zip -0 ccov.zip `find . \( -name "rustpython*.gc*" \) -print`
# Install grcov
- curl -L https://github.com/mozilla/grcov/releases/download/v0.4.1/grcov-linux-x86_64.tar.bz2 | tar jxf -
+ curl -L https://github.com/mozilla/grcov/releases/download/v0.4.2/grcov-linux-x86_64.tar.bz2 | tar jxf -
./grcov ccov.zip -s . -t lcov --llvm --branch --ignore-not-existing --ignore-dir "/*" -p "x" > lcov.info
From bbb716247266e6c0eca7993e2aacb456c3b79208 Mon Sep 17 00:00:00 2001
From: Adam Kelly
Date: Mon, 25 Mar 2019 16:37:20 +0000
Subject: [PATCH 022/658] Various dictionary changes.
* vm.ctx.new_dict returns a PyDictRef
* Special case for module goes away.
* Instances get a real dictionary.
---
vm/src/builtins.rs | 4 +-
vm/src/frame.rs | 14 +++--
vm/src/function.rs | 9 +++
vm/src/import.rs | 2 +-
vm/src/obj/objdict.rs | 110 +++++++++++++++++++--------------
vm/src/obj/objmodule.rs | 26 ++++----
vm/src/obj/objobject.rs | 38 +++++-------
vm/src/obj/objproperty.rs | 4 +-
vm/src/obj/objsequence.rs | 2 +
vm/src/obj/objtype.rs | 4 +-
vm/src/pyobject.rs | 94 +++++++++++++---------------
vm/src/stdlib/json.rs | 2 +-
vm/src/vm.rs | 8 +--
wasm/lib/src/browser_module.rs | 1 +
wasm/lib/src/convert.rs | 4 +-
15 files changed, 164 insertions(+), 158 deletions(-)
diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs
index acd0719d8..4d9fb7989 100644
--- a/vm/src/builtins.rs
+++ b/vm/src/builtins.rs
@@ -815,9 +815,9 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
let prepare = vm.get_attribute(metaclass.clone().into_object(), "__prepare__")?;
let namespace = vm.invoke(prepare, vec![name_arg.clone(), bases.clone()])?;
- let cells = vm.new_dict();
+ let cells = vm.ctx.new_dict();
- vm.invoke_with_locals(function, cells.clone(), namespace.clone())?;
+ vm.invoke_with_locals(function, cells.clone().into_object(), namespace.clone())?;
let class = vm.call_method(
metaclass.as_object(),
"__call__",
diff --git a/vm/src/frame.rs b/vm/src/frame.rs
index b9e6cf965..3584a57a8 100644
--- a/vm/src/frame.rs
+++ b/vm/src/frame.rs
@@ -119,7 +119,7 @@ impl Scope {
}
pub fn child_scope(&self, ctx: &PyContext) -> Scope {
- self.child_scope_with_locals(ctx.new_dict())
+ self.child_scope_with_locals(ctx.new_dict().into_object())
}
}
@@ -142,7 +142,7 @@ impl NameProtocol for Scope {
return Some(value);
}
- vm.builtins.get_item(name)
+ vm.get_attribute(vm.builtins.clone(), name).ok()
}
fn load_cell(&self, _vm: &VirtualMachine, name: &str) -> Option {
@@ -386,7 +386,7 @@ impl Frame {
Ok(None)
}
bytecode::Instruction::BuildMap { size, unpack } => {
- let map_obj = vm.ctx.new_dict();
+ let map_obj = vm.ctx.new_dict().into_object();
for _x in 0..*size {
let obj = self.pop_value();
if *unpack {
@@ -572,7 +572,7 @@ impl Frame {
let annotations = if flags.contains(bytecode::FunctionOpArg::HAS_ANNOTATIONS) {
self.pop_value()
} else {
- vm.new_dict()
+ vm.ctx.new_dict().into_object()
};
let defaults = if flags.contains(bytecode::FunctionOpArg::HAS_DEFAULTS) {
@@ -839,8 +839,10 @@ impl Frame {
let module = vm.import(module)?;
// Grab all the names from the module and put them in the context
- for (k, v) in module.get_key_value_pairs().iter() {
- self.scope.store_name(&vm, &objstr::get_value(k), v.clone());
+ if let Some(dict) = &module.dict {
+ for (k, v) in dict.get_key_value_pairs().iter() {
+ self.scope.store_name(&vm, &objstr::get_value(k), v.clone());
+ }
}
Ok(None)
}
diff --git a/vm/src/function.rs b/vm/src/function.rs
index 1e2a38f71..ed959d85c 100644
--- a/vm/src/function.rs
+++ b/vm/src/function.rs
@@ -247,6 +247,15 @@ where
}
}
+impl IntoIterator for KwArgs {
+ type Item = (String, T);
+ type IntoIter = std::collections::hash_map::IntoIter;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.0.into_iter()
+ }
+}
+
/// A list of positional argument values.
///
/// A built-in function with a `Args` parameter is analagous to a Python
diff --git a/vm/src/import.rs b/vm/src/import.rs
index 936b89680..987555915 100644
--- a/vm/src/import.rs
+++ b/vm/src/import.rs
@@ -40,7 +40,7 @@ fn import_uncached_module(vm: &VirtualMachine, current_path: PathBuf, module: &s
let attrs = vm.ctx.new_dict();
attrs.set_item(&vm.ctx, "__name__", vm.new_str(module.to_string()));
- vm.run_code_obj(code_obj, Scope::new(None, attrs.clone()))?;
+ vm.run_code_obj(code_obj, Scope::new(None, attrs.clone().into_object()))?;
Ok(vm.ctx.new_module(module, attrs))
}
diff --git a/vm/src/obj/objdict.rs b/vm/src/obj/objdict.rs
index 0c8d5fe5e..061c3477e 100644
--- a/vm/src/obj/objdict.rs
+++ b/vm/src/obj/objdict.rs
@@ -3,9 +3,9 @@ use std::collections::HashMap;
use std::fmt;
use std::ops::{Deref, DerefMut};
-use crate::function::{OptionalArg, PyFuncArgs};
+use crate::function::{KwArgs, OptionalArg};
use crate::pyobject::{
- PyAttributes, PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
+ DictProtocol, PyAttributes, PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue,
};
use crate::vm::{ReprGuard, VirtualMachine};
@@ -124,57 +124,48 @@ pub fn py_dict_to_attributes(dict: &PyObjectRef) -> PyAttributes {
attrs
}
-pub fn attributes_to_py_dict(vm: &VirtualMachine, attributes: PyAttributes) -> PyResult {
- let dict = vm.ctx.new_dict();
- for (key, value) in attributes {
- let key = vm.ctx.new_str(key);
- set_item(&dict, vm, &key, &value);
- }
- Ok(dict)
-}
-
// Python dict methods:
-fn dict_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(
- vm,
- args,
- required = [(_ty, Some(vm.ctx.type_type()))],
- optional = [(dict_obj, None)]
- );
- let dict = vm.ctx.new_dict();
- if let Some(dict_obj) = dict_obj {
- if objtype::isinstance(&dict_obj, &vm.ctx.dict_type()) {
- for (needle, value) in get_key_value_pairs(&dict_obj) {
- set_item(&dict, vm, &needle, &value);
- }
- } else {
- let iter = objiter::get_iter(vm, dict_obj)?;
- loop {
- fn err(vm: &VirtualMachine) -> PyObjectRef {
- vm.new_type_error("Iterator must have exactly two elements".to_string())
+impl PyDictRef {
+ fn new(
+ _class: PyClassRef, // TODO Support subclasses of int.
+ dict_obj: OptionalArg,
+ kwargs: KwArgs,
+ vm: &VirtualMachine,
+ ) -> PyResult {
+ let dict = vm.ctx.new_dict();
+ 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) {
+ set_item(dict.as_object(), vm, &needle, &value);
}
- let element = match objiter::get_next_object(vm, &iter)? {
- Some(obj) => obj,
- None => break,
- };
- let elem_iter = objiter::get_iter(vm, &element)?;
- let needle = objiter::get_next_object(vm, &elem_iter)?.ok_or_else(|| err(vm))?;
- let value = objiter::get_next_object(vm, &elem_iter)?.ok_or_else(|| err(vm))?;
- if objiter::get_next_object(vm, &elem_iter)?.is_some() {
- return Err(err(vm));
+ } else {
+ let iter = objiter::get_iter(vm, &dict_obj)?;
+ loop {
+ fn err(vm: &VirtualMachine) -> PyObjectRef {
+ vm.new_type_error("Iterator must have exactly two elements".to_string())
+ }
+ let element = match objiter::get_next_object(vm, &iter)? {
+ Some(obj) => obj,
+ None => break,
+ };
+ let elem_iter = objiter::get_iter(vm, &element)?;
+ let needle =
+ objiter::get_next_object(vm, &elem_iter)?.ok_or_else(|| err(vm))?;
+ let value = objiter::get_next_object(vm, &elem_iter)?.ok_or_else(|| err(vm))?;
+ if objiter::get_next_object(vm, &elem_iter)?.is_some() {
+ return Err(err(vm));
+ }
+ set_item(dict.as_object(), vm, &needle, &value);
}
- set_item(&dict, vm, &needle, &value);
}
}
+ for (needle, value) in kwargs.into_iter() {
+ let py_needle = vm.new_str(needle);
+ set_item(&dict.as_object(), vm, &py_needle, &value);
+ }
+ Ok(dict)
}
- for (needle, value) in args.kwargs {
- let py_needle = vm.new_str(needle);
- set_item(&dict, vm, &py_needle, &value);
- }
- Ok(dict)
-}
-impl PyDictRef {
fn bool(self, _vm: &VirtualMachine) -> bool {
!self.entries.borrow().is_empty()
}
@@ -302,6 +293,31 @@ impl PyDictRef {
}
}
+impl DictProtocol for PyDictRef {
+ fn contains_key(&self, k: &str) -> bool {
+ content_contains_key_str(&self.entries.borrow(), k)
+ }
+
+ fn get_item(&self, k: &str) -> Option {
+ content_get_key_str(&self.entries.borrow(), k)
+ }
+
+ fn get_key_value_pairs(&self) -> Vec<(PyObjectRef, PyObjectRef)> {
+ get_key_value_pairs(self.as_object())
+ }
+
+ // Item set/get:
+ fn set_item(&self, ctx: &PyContext, key: &str, v: PyObjectRef) {
+ let key = ctx.new_str(key.to_string());
+ set_item_in_content(&mut self.entries.borrow_mut(), &key, &v);
+ }
+
+ fn del_item(&self, key: &str) {
+ let mut elements = get_mut_elements(self.as_object());
+ elements.remove(key).unwrap();
+ }
+}
+
pub fn init(context: &PyContext) {
extend_class!(context, &context.dict_type, {
"__bool__" => context.new_rustfunc(PyDictRef::bool),
@@ -310,7 +326,7 @@ pub fn init(context: &PyContext) {
"__delitem__" => context.new_rustfunc(PyDictRef::delitem),
"__getitem__" => context.new_rustfunc(PyDictRef::getitem),
"__iter__" => context.new_rustfunc(PyDictRef::iter),
- "__new__" => context.new_rustfunc(dict_new),
+ "__new__" => context.new_rustfunc(PyDictRef::new),
"__repr__" => context.new_rustfunc(PyDictRef::repr),
"__setitem__" => context.new_rustfunc(PyDictRef::setitem),
"clear" => context.new_rustfunc(PyDictRef::clear),
diff --git a/vm/src/obj/objmodule.rs b/vm/src/obj/objmodule.rs
index 58d8688db..b641f0426 100644
--- a/vm/src/obj/objmodule.rs
+++ b/vm/src/obj/objmodule.rs
@@ -1,12 +1,10 @@
-use crate::obj::objstr::PyStringRef;
use crate::obj::objtype::PyClassRef;
-use crate::pyobject::{DictProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
+use crate::pyobject::{DictProtocol, PyContext, PyRef, PyResult, PyValue};
use crate::vm::VirtualMachine;
#[derive(Debug)]
pub struct PyModule {
pub name: String,
- pub dict: PyObjectRef,
}
pub type PyModuleRef = PyRef;
@@ -18,23 +16,21 @@ impl PyValue for PyModule {
impl PyModuleRef {
fn dir(self: PyModuleRef, vm: &VirtualMachine) -> PyResult {
- let keys = self
- .dict
- .get_key_value_pairs()
- .iter()
- .map(|(k, _v)| k.clone())
- .collect();
- Ok(vm.ctx.new_list(keys))
- }
-
- fn set_attr(self, attr: PyStringRef, value: PyObjectRef, vm: &VirtualMachine) {
- self.dict.set_item(&vm.ctx, &attr.value, value)
+ if let Some(dict) = &self.into_object().dict {
+ let keys = dict
+ .get_key_value_pairs()
+ .iter()
+ .map(|(k, _v)| k.clone())
+ .collect();
+ Ok(vm.ctx.new_list(keys))
+ } else {
+ panic!("Modules should definitely have a dict.");
+ }
}
}
pub fn init(context: &PyContext) {
extend_class!(&context, &context.module_type, {
"__dir__" => context.new_rustfunc(PyModuleRef::dir),
- "__setattr__" => context.new_rustfunc(PyModuleRef::set_attr)
});
}
diff --git a/vm/src/obj/objobject.rs b/vm/src/obj/objobject.rs
index 46a90114d..60473fad0 100644
--- a/vm/src/obj/objobject.rs
+++ b/vm/src/obj/objobject.rs
@@ -1,5 +1,5 @@
+use super::objdict::{self, PyDictRef};
use super::objlist::PyList;
-use super::objmodule::PyModule;
use super::objstr::{self, PyStringRef};
use super::objtype;
use crate::function::PyFuncArgs;
@@ -23,11 +23,12 @@ impl PyValue for PyInstance {
pub fn new_instance(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResult {
// more or less __new__ operator
let cls = PyClassRef::try_from_object(vm, args.shift())?;
- Ok(if cls.is(&vm.ctx.object) {
- PyObject::new_without_dict(PyInstance, cls)
+ let dict = if cls.is(&vm.ctx.object) {
+ None
} else {
- PyObject::new(PyInstance, cls)
- })
+ Some(vm.ctx.new_dict())
+ };
+ Ok(PyObject::new(PyInstance, cls, dict))
}
fn object_eq(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -114,7 +115,7 @@ fn object_setattr(
}
if let Some(ref dict) = obj.clone().dict {
- dict.borrow_mut().insert(attr_name.value.clone(), value);
+ dict.set_item(&vm.ctx, &attr_name.value, value);
Ok(())
} else {
let type_name = objtype::get_type_name(obj.type_ref());
@@ -135,7 +136,7 @@ fn object_delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine)
}
if let Some(ref dict) = obj.dict {
- dict.borrow_mut().remove(&attr_name.value);
+ dict.del_item(&attr_name.value);
Ok(())
} else {
let type_name = objtype::get_type_name(obj.type_ref());
@@ -227,13 +228,9 @@ fn object_class_setter(
Err(vm.new_type_error(format!("can't change class of type '{}'", type_repr)))
}
-fn object_dict(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- if let Some(ref dict) = args.args[0].dict {
- let new_dict = vm.new_dict();
- for (attr, value) in dict.borrow().iter() {
- new_dict.set_item(&vm.ctx, &attr, value.clone());
- }
- Ok(new_dict)
+fn object_dict(object: PyObjectRef, vm: &VirtualMachine) -> PyResult {
+ if let Some(ref dict) = object.dict {
+ Ok(dict.clone())
} else {
Err(vm.new_type_error("TypeError: no dictionary.".to_string()))
}
@@ -273,15 +270,8 @@ fn object_getattribute(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
}
fn object_getattr(obj: &PyObjectRef, attr_name: &str) -> Option {
- // TODO:
- // This is an all kinds of wrong work-around for the temporary difference in
- // shape between modules and object. It will disappear once that is fixed.
- if let Some(PyModule { ref dict, .. }) = obj.payload::() {
- return dict.get_item(attr_name);
- }
-
if let Some(ref dict) = obj.dict {
- dict.borrow().get(attr_name).cloned()
+ dict.get_item(attr_name)
} else {
None
}
@@ -293,8 +283,8 @@ pub fn get_attributes(obj: &PyObjectRef) -> PyAttributes {
// Get instance attributes:
if let Some(dict) = &obj.dict {
- for (name, value) in dict.borrow().iter() {
- attributes.insert(name.to_string(), value.clone());
+ for (key, value) in objdict::get_key_value_pairs(dict.as_object()) {
+ attributes.insert(key.to_string(), value.clone());
}
}
diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs
index c5459a9fb..e6b11904e 100644
--- a/vm/src/obj/objproperty.rs
+++ b/vm/src/obj/objproperty.rs
@@ -200,7 +200,7 @@ impl<'a> PropertyBuilder<'a> {
deleter: None,
};
- PyObject::new(payload, self.ctx.property_type())
+ PyObject::new(payload, self.ctx.property_type(), None)
} else {
let payload = PyReadOnlyProperty {
getter: self.getter.expect(
@@ -208,7 +208,7 @@ impl<'a> PropertyBuilder<'a> {
),
};
- PyObject::new(payload, self.ctx.readonly_property_type())
+ PyObject::new(payload, self.ctx.readonly_property_type(), None)
}
}
}
diff --git a/vm/src/obj/objsequence.rs b/vm/src/obj/objsequence.rs
index b8d91e590..80f4bf40f 100644
--- a/vm/src/obj/objsequence.rs
+++ b/vm/src/obj/objsequence.rs
@@ -164,11 +164,13 @@ pub fn get_item(
Ok(PyObject::new(
PyList::from(elements.to_vec().get_slice_items(vm, &subscript)?),
sequence.type_pyref(),
+ None,
))
} else if sequence.payload::().is_some() {
Ok(PyObject::new(
PyTuple::from(elements.to_vec().get_slice_items(vm, &subscript)?),
sequence.type_pyref(),
+ None,
))
} else {
panic!("sequence get_item called for non-sequence")
diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs
index 6399d68c9..d87ca3843 100644
--- a/vm/src/obj/objtype.rs
+++ b/vm/src/obj/objtype.rs
@@ -110,8 +110,8 @@ impl PyClassRef {
format!("", self.name)
}
- fn prepare(_name: PyStringRef, _bases: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
- vm.new_dict()
+ fn prepare(_name: PyStringRef, _bases: PyObjectRef, vm: &VirtualMachine) -> PyDictRef {
+ vm.ctx.new_dict()
}
fn getattribute(self, name_ref: PyStringRef, vm: &VirtualMachine) -> PyResult {
diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs
index 81fec3406..78e82c51b 100644
--- a/vm/src/pyobject.rs
+++ b/vm/src/pyobject.rs
@@ -24,7 +24,7 @@ use crate::obj::objclassmethod;
use crate::obj::objcode;
use crate::obj::objcode::PyCodeRef;
use crate::obj::objcomplex::{self, PyComplex};
-use crate::obj::objdict::{self, PyDict};
+use crate::obj::objdict::{self, PyDict, PyDictRef};
use crate::obj::objellipsis;
use crate::obj::objenumerate;
use crate::obj::objfilter;
@@ -271,7 +271,7 @@ impl PyContext {
fn create_object(payload: T, cls: &PyClassRef) -> PyRef {
PyRef {
- obj: PyObject::new(payload, cls.clone()),
+ obj: PyObject::new(payload, cls.clone(), None),
_payload: PhantomData,
}
}
@@ -521,32 +521,32 @@ impl PyContext {
self.object.clone()
}
- pub fn new_object(&self) -> PyObjectRef {
- self.new_instance(self.object.clone(), None)
- }
-
pub fn new_int>(&self, i: T) -> PyObjectRef {
- PyObject::new(PyInt::new(i), self.int_type())
+ PyObject::new(PyInt::new(i), self.int_type(), None)
}
pub fn new_float(&self, value: f64) -> PyObjectRef {
- PyObject::new(PyFloat::from(value), self.float_type())
+ PyObject::new(PyFloat::from(value), self.float_type(), None)
}
pub fn new_complex(&self, value: Complex64) -> PyObjectRef {
- PyObject::new(PyComplex::from(value), self.complex_type())
+ PyObject::new(PyComplex::from(value), self.complex_type(), None)
}
pub fn new_str(&self, s: String) -> PyObjectRef {
- PyObject::new(objstr::PyString { value: s }, self.str_type())
+ PyObject::new(objstr::PyString { value: s }, self.str_type(), None)
}
pub fn new_bytes(&self, data: Vec) -> PyObjectRef {
- PyObject::new(objbytes::PyBytes::new(data), self.bytes_type())
+ PyObject::new(objbytes::PyBytes::new(data), self.bytes_type(), None)
}
pub fn new_bytearray(&self, data: Vec) -> PyObjectRef {
- PyObject::new(objbytearray::PyByteArray::new(data), self.bytearray_type())
+ PyObject::new(
+ objbytearray::PyByteArray::new(data),
+ self.bytearray_type(),
+ None,
+ )
}
pub fn new_bool(&self, b: bool) -> PyObjectRef {
@@ -558,21 +558,23 @@ impl PyContext {
}
pub fn new_tuple(&self, elements: Vec) -> PyObjectRef {
- PyObject::new(PyTuple::from(elements), self.tuple_type())
+ PyObject::new(PyTuple::from(elements), self.tuple_type(), None)
}
pub fn new_list(&self, elements: Vec) -> PyObjectRef {
- PyObject::new(PyList::from(elements), self.list_type())
+ PyObject::new(PyList::from(elements), self.list_type(), None)
}
pub fn new_set(&self) -> PyObjectRef {
// Initialized empty, as calling __hash__ is required for adding each object to the set
// which requires a VM context - this is done in the objset code itself.
- PyObject::new(PySet::default(), self.set_type())
+ PyObject::new(PySet::default(), self.set_type(), None)
}
- pub fn new_dict(&self) -> PyObjectRef {
- PyObject::new(PyDict::default(), self.dict_type())
+ pub fn new_dict(&self) -> PyDictRef {
+ PyObject::new(PyDict::default(), self.dict_type(), None)
+ .downcast()
+ .unwrap()
}
pub fn new_class(&self, name: &str, base: PyClassRef) -> PyClassRef {
@@ -580,16 +582,16 @@ impl PyContext {
}
pub fn new_scope(&self) -> Scope {
- Scope::new(None, self.new_dict())
+ Scope::new(None, self.new_dict().into_object())
}
- pub fn new_module(&self, name: &str, dict: PyObjectRef) -> PyObjectRef {
+ pub fn new_module(&self, name: &str, dict: PyDictRef) -> PyObjectRef {
PyObject::new(
PyModule {
name: name.to_string(),
- dict,
},
self.module_type.clone(),
+ Some(dict),
)
}
@@ -600,6 +602,7 @@ impl PyContext {
PyObject::new(
PyBuiltinFunction::new(f.into_func()),
self.builtin_function_or_method_type(),
+ None,
)
}
@@ -611,7 +614,7 @@ impl PyContext {
}
pub fn new_code_object(&self, code: bytecode::CodeObject) -> PyObjectRef {
- PyObject::new(objcode::PyCode::new(code), self.code_type())
+ PyObject::new(objcode::PyCode::new(code), self.code_type(), None)
}
pub fn new_function(
@@ -623,18 +626,22 @@ impl PyContext {
PyObject::new(
PyFunction::new(code_obj, scope, defaults),
self.function_type(),
+ Some(self.new_dict()),
)
}
pub fn new_bound_method(&self, function: PyObjectRef, object: PyObjectRef) -> PyObjectRef {
- PyObject::new(PyMethod::new(object, function), self.bound_method_type())
+ PyObject::new(
+ PyMethod::new(object, function),
+ self.bound_method_type(),
+ None,
+ )
}
- pub fn new_instance(&self, class: PyClassRef, dict: Option) -> PyObjectRef {
- let dict = dict.unwrap_or_default();
+ pub fn new_instance(&self, class: PyClassRef, dict: Option) -> PyObjectRef {
PyObject {
typ: class,
- dict: Some(RefCell::new(dict)),
+ dict: dict,
payload: objobject::PyInstance,
}
.into_ref()
@@ -661,11 +668,8 @@ impl PyContext {
attributes
.borrow_mut()
.insert(attr_name.to_string(), value.into());
- } else if let Some(PyModule { ref dict, .. }) = obj.payload::() {
- dict.set_item(self, attr_name, value.into())
} else if let Some(ref dict) = obj.dict {
- dict.borrow_mut()
- .insert(attr_name.to_string(), value.into());
+ dict.set_item(self, attr_name, value.into());
} else {
unimplemented!("set_attr unimplemented for: {:?}", obj);
};
@@ -707,7 +711,7 @@ where
T: ?Sized + PyObjectPayload,
{
pub typ: PyClassRef,
- pub dict: Option>, // __dict__ member
+ pub dict: Option, // __dict__ member
pub payload: T,
}
@@ -917,8 +921,6 @@ impl DictProtocol for PyObjectRef {
fn get_item(&self, k: &str) -> Option {
if let Some(dict) = self.payload::() {
objdict::content_get_key_str(&dict.entries.borrow(), k)
- } else if let Some(PyModule { ref dict, .. }) = self.payload::() {
- dict.get_item(k)
} else {
panic!("TODO {:?}", k)
}
@@ -927,8 +929,6 @@ impl DictProtocol for PyObjectRef {
fn get_key_value_pairs(&self) -> Vec<(PyObjectRef, PyObjectRef)> {
if self.payload_is::() {
objdict::get_key_value_pairs(self)
- } else if let Some(PyModule { ref dict, .. }) = self.payload::() {
- dict.get_key_value_pairs()
} else {
panic!("TODO")
}
@@ -939,8 +939,6 @@ impl DictProtocol for PyObjectRef {
if let Some(dict) = self.payload::() {
let key = ctx.new_str(key.to_string());
objdict::set_item_in_content(&mut dict.entries.borrow_mut(), &key, &v);
- } else if let Some(PyModule { ref dict, .. }) = self.payload::() {
- dict.set_item(ctx, key, v);
} else {
panic!("TODO {:?}", self);
}
@@ -1121,7 +1119,7 @@ where
T: PyValue + Sized,
{
fn into_pyobject(self, vm: &VirtualMachine) -> PyResult {
- Ok(PyObject::new(self, T::class(vm)))
+ Ok(PyObject::new(self, T::class(vm), None))
}
}
@@ -1143,19 +1141,10 @@ impl PyObject
where
T: Sized + PyObjectPayload,
{
- pub fn new(payload: T, typ: PyClassRef) -> PyObjectRef {
+ pub fn new(payload: T, typ: PyClassRef, dict: Option) -> PyObjectRef {
PyObject {
typ,
- dict: Some(RefCell::new(PyAttributes::new())),
- payload,
- }
- .into_ref()
- }
-
- pub fn new_without_dict(payload: T, typ: PyClassRef) -> PyObjectRef {
- PyObject {
- typ,
- dict: None,
+ dict: dict,
payload,
}
.into_ref()
@@ -1184,7 +1173,7 @@ pub trait PyValue: fmt::Debug + Sized + 'static {
fn into_ref(self, vm: &VirtualMachine) -> PyRef {
PyRef {
- obj: PyObject::new(self, Self::class(vm)),
+ obj: PyObject::new(self, Self::class(vm), None),
_payload: PhantomData,
}
}
@@ -1192,8 +1181,13 @@ pub trait PyValue: fmt::Debug + Sized + 'static {
fn into_ref_with_type(self, vm: &VirtualMachine, cls: PyClassRef) -> PyResult> {
let class = Self::class(vm);
if objtype::issubclass(&cls, &class) {
+ let dict = if cls.is(&class) {
+ None
+ } else {
+ Some(vm.ctx.new_dict())
+ };
Ok(PyRef {
- obj: PyObject::new(self, cls),
+ obj: PyObject::new(self, cls, dict),
_payload: PhantomData,
})
} else {
diff --git a/vm/src/stdlib/json.rs b/vm/src/stdlib/json.rs
index 2c5c95d34..eac3619c2 100644
--- a/vm/src/stdlib/json.rs
+++ b/vm/src/stdlib/json.rs
@@ -177,7 +177,7 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> {
};
dict.set_item(&self.vm.ctx, &key, value);
}
- Ok(dict)
+ Ok(dict.into_object())
}
fn visit_unit(self) -> Result
diff --git a/vm/src/vm.rs b/vm/src/vm.rs
index 7713c561d..0ee9798ab 100644
--- a/vm/src/vm.rs
+++ b/vm/src/vm.rs
@@ -141,10 +141,6 @@ impl VirtualMachine {
self.ctx.new_bool(b)
}
- pub fn new_dict(&self) -> PyObjectRef {
- self.ctx.new_dict()
- }
-
pub fn new_empty_exception(&self, exc_type: PyClassRef) -> PyResult {
info!("New exception created: no msg");
let args = PyFuncArgs::default();
@@ -454,11 +450,11 @@ impl VirtualMachine {
// Do we support `**kwargs` ?
let kwargs = match code_object.varkeywords {
bytecode::Varargs::Named(ref kwargs_name) => {
- let d = self.new_dict();
+ let d = self.ctx.new_dict().into_object();
locals.set_item(&self.ctx, kwargs_name, d.clone());
Some(d)
}
- bytecode::Varargs::Unnamed => Some(self.new_dict()),
+ bytecode::Varargs::Unnamed => Some(self.ctx.new_dict().into_object()),
bytecode::Varargs::None => None,
};
diff --git a/wasm/lib/src/browser_module.rs b/wasm/lib/src/browser_module.rs
index a309284cf..0e13aeb3a 100644
--- a/wasm/lib/src/browser_module.rs
+++ b/wasm/lib/src/browser_module.rs
@@ -363,6 +363,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
doc: window().document().expect("Document missing from window"),
},
document_class.clone(),
+ None,
);
let element = py_class!(ctx, "Element", ctx.object(), {
diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs
index ecdb4b110..588c7571c 100644
--- a/wasm/lib/src/convert.rs
+++ b/wasm/lib/src/convert.rs
@@ -187,13 +187,13 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
u8_array.for_each(&mut |byte, _, _| vec.push(byte));
vm.ctx.new_bytes(vec)
} else {
- let dict = vm.new_dict();
+ let dict = vm.ctx.new_dict();
for pair in object_entries(&Object::from(js_val)) {
let (key, val) = pair.expect("iteration over object to not fail");
let py_val = js_to_py(vm, val);
dict.set_item(&vm.ctx, &String::from(js_sys::JsString::from(key)), py_val);
}
- dict
+ dict.into_object()
}
} else if js_val.is_function() {
let func = js_sys::Function::from(js_val);
From 55e0fb1f19f84d377f9aa5368d606e40f2a49371 Mon Sep 17 00:00:00 2001
From: Adam Kelly
Date: Mon, 25 Mar 2019 16:39:25 +0000
Subject: [PATCH 023/658] AST class for nodes instead of just using object
everywhere.
---
vm/src/stdlib/ast.rs | 459 ++++++++++++++++++++++---------------------
1 file changed, 238 insertions(+), 221 deletions(-)
diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs
index a3010a519..0011407ab 100644
--- a/vm/src/stdlib/ast.rs
+++ b/vm/src/stdlib/ast.rs
@@ -11,9 +11,20 @@ use rustpython_parser::{ast, parser};
use crate::function::PyFuncArgs;
use crate::obj::objstr;
-use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
+use crate::obj::objtype::PyClassRef;
+use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
use crate::vm::VirtualMachine;
+#[derive(Debug)]
+struct AstNode;
+// type AstNodeRef = PyRef;
+
+impl PyValue for AstNode {
+ fn class(vm: &VirtualMachine) -> PyClassRef {
+ vm.class("ast", "AST")
+ }
+}
+
/*
* Idea: maybe we can create a sort of struct with some helper functions?
struct AstToPyAst {
@@ -30,35 +41,35 @@ impl AstToPyAst {
}
*/
-fn program_to_ast(ctx: &PyContext, program: &ast::Program) -> PyObjectRef {
+fn program_to_ast(vm: &VirtualMachine, program: &ast::Program) -> PyObjectRef {
let mut body = vec![];
for statement in &program.statements {
- body.push(statement_to_ast(ctx, statement));
+ body.push(statement_to_ast(&vm, statement));
}
// TODO: create Module node:
// let ast_node = ctx.new_instance(this.Module);
- let ast_node = ctx.new_object();
- let py_body = ctx.new_list(body);
- ctx.set_attr(&ast_node, "body", py_body);
+ let ast_node = create_node(vm, "program");
+ let py_body = vm.ctx.new_list(body);
+ vm.ctx.set_attr(&ast_node, "body", py_body);
ast_node
}
// Create a node class instance
-fn create_node(ctx: &PyContext, _name: &str) -> PyObjectRef {
+fn create_node(vm: &VirtualMachine, _name: &str) -> PyObjectRef {
// TODO: instantiate a class of type given by name
// TODO: lookup in the current module?
- ctx.new_object()
+ PyObject::new(AstNode, AstNode::class(vm), Some(vm.ctx.new_dict()))
}
-fn statements_to_ast(ctx: &PyContext, statements: &[ast::LocatedStatement]) -> PyObjectRef {
+fn statements_to_ast(vm: &VirtualMachine, statements: &[ast::LocatedStatement]) -> PyObjectRef {
let mut py_statements = vec![];
for statement in statements {
- py_statements.push(statement_to_ast(ctx, statement));
+ py_statements.push(statement_to_ast(vm, statement));
}
- ctx.new_list(py_statements)
+ vm.ctx.new_list(py_statements)
}
-fn statement_to_ast(ctx: &PyContext, statement: &ast::LocatedStatement) -> PyObjectRef {
+fn statement_to_ast(vm: &VirtualMachine, statement: &ast::LocatedStatement) -> PyObjectRef {
let node = match &statement.node {
ast::Statement::ClassDef {
name,
@@ -66,17 +77,18 @@ fn statement_to_ast(ctx: &PyContext, statement: &ast::LocatedStatement) -> PyObj
decorator_list,
..
} => {
- let node = create_node(ctx, "ClassDef");
+ let node = create_node(vm, "ClassDef");
// Set name:
- ctx.set_attr(&node, "name", ctx.new_str(name.to_string()));
+ vm.ctx
+ .set_attr(&node, "name", vm.ctx.new_str(name.to_string()));
// Set body:
- let py_body = statements_to_ast(ctx, body);
- ctx.set_attr(&node, "body", py_body);
+ let py_body = statements_to_ast(vm, body);
+ vm.ctx.set_attr(&node, "body", py_body);
- let py_decorator_list = expressions_to_ast(ctx, decorator_list);
- ctx.set_attr(&node, "decorator_list", py_decorator_list);
+ let py_decorator_list = expressions_to_ast(vm, decorator_list);
+ vm.ctx.set_attr(&node, "decorator_list", py_decorator_list);
node
}
ast::Statement::FunctionDef {
@@ -86,80 +98,83 @@ fn statement_to_ast(ctx: &PyContext, statement: &ast::LocatedStatement) -> PyObj
decorator_list,
returns,
} => {
- let node = create_node(ctx, "FunctionDef");
+ let node = create_node(vm, "FunctionDef");
// Set name:
- ctx.set_attr(&node, "name", ctx.new_str(name.to_string()));
+ vm.ctx
+ .set_attr(&node, "name", vm.ctx.new_str(name.to_string()));
- ctx.set_attr(&node, "args", parameters_to_ast(ctx, args));
+ vm.ctx.set_attr(&node, "args", parameters_to_ast(vm, args));
// Set body:
- let py_body = statements_to_ast(ctx, body);
- ctx.set_attr(&node, "body", py_body);
+ let py_body = statements_to_ast(vm, body);
+ vm.ctx.set_attr(&node, "body", py_body);
- let py_decorator_list = expressions_to_ast(ctx, decorator_list);
- ctx.set_attr(&node, "decorator_list", py_decorator_list);
+ let py_decorator_list = expressions_to_ast(vm, decorator_list);
+ vm.ctx.set_attr(&node, "decorator_list", py_decorator_list);
let py_returns = if let Some(hint) = returns {
- expression_to_ast(ctx, hint)
+ expression_to_ast(vm, hint)
} else {
- ctx.none()
+ vm.ctx.none()
};
- ctx.set_attr(&node, "returns", py_returns);
+ vm.ctx.set_attr(&node, "returns", py_returns);
node
}
- ast::Statement::Continue => create_node(ctx, "Continue"),
- ast::Statement::Break => create_node(ctx, "Break"),
- ast::Statement::Pass => create_node(ctx, "Pass"),
+ ast::Statement::Continue => create_node(vm, "Continue"),
+ ast::Statement::Break => create_node(vm, "Break"),
+ ast::Statement::Pass => create_node(vm, "Pass"),
ast::Statement::Assert { test, msg } => {
- let node = create_node(ctx, "Pass");
+ let node = create_node(vm, "Pass");
- ctx.set_attr(&node, "test", expression_to_ast(ctx, test));
+ vm.ctx.set_attr(&node, "test", expression_to_ast(vm, test));
let py_msg = match msg {
- Some(msg) => expression_to_ast(ctx, msg),
- None => ctx.none(),
+ Some(msg) => expression_to_ast(vm, msg),
+ None => vm.ctx.none(),
};
- ctx.set_attr(&node, "msg", py_msg);
+ vm.ctx.set_attr(&node, "msg", py_msg);
node
}
ast::Statement::Delete { targets } => {
- let node = create_node(ctx, "Delete");
+ let node = create_node(vm, "Delete");
- let py_targets =
- ctx.new_tuple(targets.iter().map(|v| expression_to_ast(ctx, v)).collect());
- ctx.set_attr(&node, "targets", py_targets);
+ let py_targets = vm
+ .ctx
+ .new_tuple(targets.iter().map(|v| expression_to_ast(vm, v)).collect());
+ vm.ctx.set_attr(&node, "targets", py_targets);
node
}
ast::Statement::Return { value } => {
- let node = create_node(ctx, "Return");
+ let node = create_node(vm, "Return");
let py_value = if let Some(value) = value {
- ctx.new_tuple(value.iter().map(|v| expression_to_ast(ctx, v)).collect())
+ vm.ctx
+ .new_tuple(value.iter().map(|v| expression_to_ast(vm, v)).collect())
} else {
- ctx.none()
+ vm.ctx.none()
};
- ctx.set_attr(&node, "value", py_value);
+ vm.ctx.set_attr(&node, "value", py_value);
node
}
ast::Statement::If { test, body, orelse } => {
- let node = create_node(ctx, "If");
+ let node = create_node(vm, "If");
- let py_test = expression_to_ast(ctx, test);
- ctx.set_attr(&node, "test", py_test);
+ let py_test = expression_to_ast(vm, test);
+ vm.ctx.set_attr(&node, "test", py_test);
- let py_body = statements_to_ast(ctx, body);
- ctx.set_attr(&node, "body", py_body);
+ let py_body = statements_to_ast(vm, body);
+ vm.ctx.set_attr(&node, "body", py_body);
let py_orelse = if let Some(orelse) = orelse {
- statements_to_ast(ctx, orelse)
+ statements_to_ast(vm, orelse)
} else {
- ctx.none()
+ vm.ctx.none()
};
- ctx.set_attr(&node, "orelse", py_orelse);
+ vm.ctx.set_attr(&node, "orelse", py_orelse);
node
}
@@ -169,49 +184,49 @@ fn statement_to_ast(ctx: &PyContext, statement: &ast::LocatedStatement) -> PyObj
body,
orelse,
} => {
- let node = create_node(ctx, "For");
+ let node = create_node(vm, "For");
- let py_target = expression_to_ast(ctx, target);
- ctx.set_attr(&node, "target", py_target);
+ let py_target = expression_to_ast(vm, target);
+ vm.ctx.set_attr(&node, "target", py_target);
- let py_iter = expressions_to_ast(ctx, iter);
- ctx.set_attr(&node, "iter", py_iter);
+ let py_iter = expressions_to_ast(vm, iter);
+ vm.ctx.set_attr(&node, "iter", py_iter);
- let py_body = statements_to_ast(ctx, body);
- ctx.set_attr(&node, "body", py_body);
+ let py_body = statements_to_ast(vm, body);
+ vm.ctx.set_attr(&node, "body", py_body);
let py_orelse = if let Some(orelse) = orelse {
- statements_to_ast(ctx, orelse)
+ statements_to_ast(vm, orelse)
} else {
- ctx.none()
+ vm.ctx.none()
};
- ctx.set_attr(&node, "orelse", py_orelse);
+ vm.ctx.set_attr(&node, "orelse", py_orelse);
node
}
ast::Statement::While { test, body, orelse } => {
- let node = create_node(ctx, "While");
+ let node = create_node(vm, "While");
- let py_test = expression_to_ast(ctx, test);
- ctx.set_attr(&node, "test", py_test);
+ let py_test = expression_to_ast(vm, test);
+ vm.ctx.set_attr(&node, "test", py_test);
- let py_body = statements_to_ast(ctx, body);
- ctx.set_attr(&node, "body", py_body);
+ let py_body = statements_to_ast(vm, body);
+ vm.ctx.set_attr(&node, "body", py_body);
let py_orelse = if let Some(orelse) = orelse {
- statements_to_ast(ctx, orelse)
+ statements_to_ast(vm, orelse)
} else {
- ctx.none()
+ vm.ctx.none()
};
- ctx.set_attr(&node, "orelse", py_orelse);
+ vm.ctx.set_attr(&node, "orelse", py_orelse);
node
}
ast::Statement::Expression { expression } => {
- let node = create_node(ctx, "Expr");
+ let node = create_node(vm, "Expr");
- let value = expression_to_ast(ctx, expression);
- ctx.set_attr(&node, "value", value);
+ let value = expression_to_ast(vm, expression);
+ vm.ctx.set_attr(&node, "value", value);
node
}
@@ -221,38 +236,38 @@ fn statement_to_ast(ctx: &PyContext, statement: &ast::LocatedStatement) -> PyObj
};
// set lineno on node:
- let lineno = ctx.new_int(statement.location.get_row());
- ctx.set_attr(&node, "lineno", lineno);
+ let lineno = vm.ctx.new_int(statement.location.get_row());
+ vm.ctx.set_attr(&node, "lineno", lineno);
node
}
-fn expressions_to_ast(ctx: &PyContext, expressions: &[ast::Expression]) -> PyObjectRef {
+fn expressions_to_ast(vm: &VirtualMachine, expressions: &[ast::Expression]) -> PyObjectRef {
let mut py_expression_nodes = vec![];
for expression in expressions {
- py_expression_nodes.push(expression_to_ast(ctx, expression));
+ py_expression_nodes.push(expression_to_ast(vm, expression));
}
- ctx.new_list(py_expression_nodes)
+ vm.ctx.new_list(py_expression_nodes)
}
-fn expression_to_ast(ctx: &PyContext, expression: &ast::Expression) -> PyObjectRef {
+fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyObjectRef {
let node = match &expression {
ast::Expression::Call { function, args, .. } => {
- let node = create_node(ctx, "Call");
+ let node = create_node(vm, "Call");
- let py_func_ast = expression_to_ast(ctx, function);
- ctx.set_attr(&node, "func", py_func_ast);
+ let py_func_ast = expression_to_ast(vm, function);
+ vm.ctx.set_attr(&node, "func", py_func_ast);
- let py_args = expressions_to_ast(ctx, args);
- ctx.set_attr(&node, "args", py_args);
+ let py_args = expressions_to_ast(vm, args);
+ vm.ctx.set_attr(&node, "args", py_args);
node
}
ast::Expression::Binop { a, op, b } => {
- let node = create_node(ctx, "BinOp");
+ let node = create_node(vm, "BinOp");
- let py_a = expression_to_ast(ctx, a);
- ctx.set_attr(&node, "left", py_a);
+ let py_a = expression_to_ast(vm, a);
+ vm.ctx.set_attr(&node, "left", py_a);
// Operator:
let str_op = match op {
@@ -270,15 +285,15 @@ fn expression_to_ast(ctx: &PyContext, expression: &ast::Expression) -> PyObjectR
ast::Operator::BitAnd => "BitAnd",
ast::Operator::FloorDiv => "FloorDiv",
};
- let py_op = ctx.new_str(str_op.to_string());
- ctx.set_attr(&node, "op", py_op);
+ let py_op = vm.ctx.new_str(str_op.to_string());
+ vm.ctx.set_attr(&node, "op", py_op);
- let py_b = expression_to_ast(ctx, b);
- ctx.set_attr(&node, "right", py_b);
+ let py_b = expression_to_ast(vm, b);
+ vm.ctx.set_attr(&node, "right", py_b);
node
}
ast::Expression::Unop { op, a } => {
- let node = create_node(ctx, "UnaryOp");
+ let node = create_node(vm, "UnaryOp");
let str_op = match op {
ast::UnaryOperator::Not => "Not",
@@ -286,37 +301,37 @@ fn expression_to_ast(ctx: &PyContext, expression: &ast::Expression) -> PyObjectR
ast::UnaryOperator::Neg => "USub",
ast::UnaryOperator::Pos => "UAdd",
};
- let py_op = ctx.new_str(str_op.to_string());
- ctx.set_attr(&node, "op", py_op);
+ let py_op = vm.ctx.new_str(str_op.to_string());
+ vm.ctx.set_attr(&node, "op", py_op);
- let py_a = expression_to_ast(ctx, a);
- ctx.set_attr(&node, "operand", py_a);
+ let py_a = expression_to_ast(vm, a);
+ vm.ctx.set_attr(&node, "operand", py_a);
node
}
ast::Expression::BoolOp { a, op, b } => {
- let node = create_node(ctx, "BoolOp");
+ let node = create_node(vm, "BoolOp");
// Attach values:
- let py_a = expression_to_ast(ctx, a);
- let py_b = expression_to_ast(ctx, b);
- let py_values = ctx.new_tuple(vec![py_a, py_b]);
- ctx.set_attr(&node, "values", py_values);
+ let py_a = expression_to_ast(vm, a);
+ let py_b = expression_to_ast(vm, b);
+ let py_values = vm.ctx.new_tuple(vec![py_a, py_b]);
+ vm.ctx.set_attr(&node, "values", py_values);
let str_op = match op {
ast::BooleanOperator::And => "And",
ast::BooleanOperator::Or => "Or",
};
- let py_op = ctx.new_str(str_op.to_string());
- ctx.set_attr(&node, "op", py_op);
+ let py_op = vm.ctx.new_str(str_op.to_string());
+ vm.ctx.set_attr(&node, "op", py_op);
node
}
ast::Expression::Compare { a, op, b } => {
- let node = create_node(ctx, "Compare");
+ let node = create_node(vm, "Compare");
- let py_a = expression_to_ast(ctx, a);
- ctx.set_attr(&node, "left", py_a);
+ let py_a = expression_to_ast(vm, a);
+ vm.ctx.set_attr(&node, "left", py_a);
// Operator:
let str_op = match op {
@@ -331,282 +346,283 @@ fn expression_to_ast(ctx: &PyContext, expression: &ast::Expression) -> PyObjectR
ast::Comparison::Is => "Is",
ast::Comparison::IsNot => "IsNot",
};
- let py_ops = ctx.new_list(vec![ctx.new_str(str_op.to_string())]);
- ctx.set_attr(&node, "ops", py_ops);
+ let py_ops = vm.ctx.new_list(vec![vm.ctx.new_str(str_op.to_string())]);
+ vm.ctx.set_attr(&node, "ops", py_ops);
- let py_b = ctx.new_list(vec![expression_to_ast(ctx, b)]);
- ctx.set_attr(&node, "comparators", py_b);
+ let py_b = vm.ctx.new_list(vec![expression_to_ast(vm, b)]);
+ vm.ctx.set_attr(&node, "comparators", py_b);
node
}
ast::Expression::Identifier { name } => {
- let node = create_node(ctx, "Identifier");
+ let node = create_node(vm, "Identifier");
// Id:
- let py_name = ctx.new_str(name.clone());
- ctx.set_attr(&node, "id", py_name);
+ let py_name = vm.ctx.new_str(name.clone());
+ vm.ctx.set_attr(&node, "id", py_name);
node
}
ast::Expression::Lambda { args, body } => {
- let node = create_node(ctx, "Lambda");
+ let node = create_node(vm, "Lambda");
- ctx.set_attr(&node, "args", parameters_to_ast(ctx, args));
+ vm.ctx.set_attr(&node, "args", parameters_to_ast(vm, args));
- let py_body = expression_to_ast(ctx, body);
- ctx.set_attr(&node, "body", py_body);
+ let py_body = expression_to_ast(vm, body);
+ vm.ctx.set_attr(&node, "body", py_body);
node
}
ast::Expression::IfExpression { test, body, orelse } => {
- let node = create_node(ctx, "IfExp");
+ let node = create_node(vm, "IfExp");
- let py_test = expression_to_ast(ctx, test);
- ctx.set_attr(&node, "test", py_test);
+ let py_test = expression_to_ast(vm, test);
+ vm.ctx.set_attr(&node, "test", py_test);
- let py_body = expression_to_ast(ctx, body);
- ctx.set_attr(&node, "body", py_body);
+ let py_body = expression_to_ast(vm, body);
+ vm.ctx.set_attr(&node, "body", py_body);
- let py_orelse = expression_to_ast(ctx, orelse);
- ctx.set_attr(&node, "orelse", py_orelse);
+ let py_orelse = expression_to_ast(vm, orelse);
+ vm.ctx.set_attr(&node, "orelse", py_orelse);
node
}
ast::Expression::Number { value } => {
- let node = create_node(ctx, "Num");
+ let node = create_node(vm, "Num");
let py_n = match value {
- ast::Number::Integer { value } => ctx.new_int(value.clone()),
- ast::Number::Float { value } => ctx.new_float(*value),
+ ast::Number::Integer { value } => vm.ctx.new_int(value.clone()),
+ ast::Number::Float { value } => vm.ctx.new_float(*value),
ast::Number::Complex { real, imag } => {
- ctx.new_complex(Complex64::new(*real, *imag))
+ vm.ctx.new_complex(Complex64::new(*real, *imag))
}
};
- ctx.set_attr(&node, "n", py_n);
+ vm.ctx.set_attr(&node, "n", py_n);
node
}
ast::Expression::True => {
- let node = create_node(ctx, "NameConstant");
+ let node = create_node(vm, "NameConstant");
- ctx.set_attr(&node, "value", ctx.new_bool(true));
+ vm.ctx.set_attr(&node, "value", vm.ctx.new_bool(true));
node
}
ast::Expression::False => {
- let node = create_node(ctx, "NameConstant");
+ let node = create_node(vm, "NameConstant");
- ctx.set_attr(&node, "value", ctx.new_bool(false));
+ vm.ctx.set_attr(&node, "value", vm.ctx.new_bool(false));
node
}
ast::Expression::None => {
- let node = create_node(ctx, "NameConstant");
+ let node = create_node(vm, "NameConstant");
- ctx.set_attr(&node, "value", ctx.none());
+ vm.ctx.set_attr(&node, "value", vm.ctx.none());
node
}
- ast::Expression::Ellipsis => create_node(ctx, "Ellipsis"),
+ ast::Expression::Ellipsis => create_node(vm, "Ellipsis"),
ast::Expression::List { elements } => {
- let node = create_node(ctx, "List");
+ let node = create_node(vm, "List");
- let elts = elements.iter().map(|e| expression_to_ast(ctx, e)).collect();
- let py_elts = ctx.new_list(elts);
- ctx.set_attr(&node, "elts", py_elts);
+ let elts = elements.iter().map(|e| expression_to_ast(vm, e)).collect();
+ let py_elts = vm.ctx.new_list(elts);
+ vm.ctx.set_attr(&node, "elts", py_elts);
node
}
ast::Expression::Tuple { elements } => {
- let node = create_node(ctx, "Tuple");
+ let node = create_node(vm, "Tuple");
- let elts = elements.iter().map(|e| expression_to_ast(ctx, e)).collect();
- let py_elts = ctx.new_list(elts);
- ctx.set_attr(&node, "elts", py_elts);
+ let elts = elements.iter().map(|e| expression_to_ast(vm, e)).collect();
+ let py_elts = vm.ctx.new_list(elts);
+ vm.ctx.set_attr(&node, "elts", py_elts);
node
}
ast::Expression::Set { elements } => {
- let node = create_node(ctx, "Set");
+ let node = create_node(vm, "Set");
- let elts = elements.iter().map(|e| expression_to_ast(ctx, e)).collect();
- let py_elts = ctx.new_list(elts);
- ctx.set_attr(&node, "elts", py_elts);
+ let elts = elements.iter().map(|e| expression_to_ast(vm, e)).collect();
+ let py_elts = vm.ctx.new_list(elts);
+ vm.ctx.set_attr(&node, "elts", py_elts);
node
}
ast::Expression::Dict { elements } => {
- let node = create_node(ctx, "Dict");
+ let node = create_node(vm, "Dict");
let mut keys = Vec::new();
let mut values = Vec::new();
for (k, v) in elements {
- keys.push(expression_to_ast(ctx, k));
- values.push(expression_to_ast(ctx, v));
+ keys.push(expression_to_ast(vm, k));
+ values.push(expression_to_ast(vm, v));
}
- let py_keys = ctx.new_list(keys);
- ctx.set_attr(&node, "keys", py_keys);
+ let py_keys = vm.ctx.new_list(keys);
+ vm.ctx.set_attr(&node, "keys", py_keys);
- let py_values = ctx.new_list(values);
- ctx.set_attr(&node, "values", py_values);
+ let py_values = vm.ctx.new_list(values);
+ vm.ctx.set_attr(&node, "values", py_values);
node
}
ast::Expression::Comprehension { kind, generators } => {
let node = match kind.deref() {
ast::ComprehensionKind::GeneratorExpression { .. } => {
- create_node(ctx, "GeneratorExp")
+ create_node(vm, "GeneratorExp")
}
- ast::ComprehensionKind::List { .. } => create_node(ctx, "ListComp"),
- ast::ComprehensionKind::Set { .. } => create_node(ctx, "SetComp"),
- ast::ComprehensionKind::Dict { .. } => create_node(ctx, "DictComp"),
+ ast::ComprehensionKind::List { .. } => create_node(vm, "ListComp"),
+ ast::ComprehensionKind::Set { .. } => create_node(vm, "SetComp"),
+ ast::ComprehensionKind::Dict { .. } => create_node(vm, "DictComp"),
};
let g = generators
.iter()
- .map(|g| comprehension_to_ast(ctx, g))
+ .map(|g| comprehension_to_ast(vm, g))
.collect();
- let py_generators = ctx.new_list(g);
- ctx.set_attr(&node, "generators", py_generators);
+ let py_generators = vm.ctx.new_list(g);
+ vm.ctx.set_attr(&node, "generators", py_generators);
node
}
ast::Expression::Yield { value } => {
- let node = create_node(ctx, "Yield");
+ let node = create_node(vm, "Yield");
let py_value = match value {
- Some(value) => expression_to_ast(ctx, value),
- None => ctx.none(),
+ Some(value) => expression_to_ast(vm, value),
+ None => vm.ctx.none(),
};
- ctx.set_attr(&node, "value", py_value);
+ vm.ctx.set_attr(&node, "value", py_value);
node
}
ast::Expression::YieldFrom { value } => {
- let node = create_node(ctx, "YieldFrom");
+ let node = create_node(vm, "YieldFrom");
- let py_value = expression_to_ast(ctx, value);
- ctx.set_attr(&node, "value", py_value);
+ let py_value = expression_to_ast(vm, value);
+ vm.ctx.set_attr(&node, "value", py_value);
node
}
ast::Expression::Subscript { a, b } => {
- let node = create_node(ctx, "Subscript");
+ let node = create_node(vm, "Subscript");
- let py_value = expression_to_ast(ctx, a);
- ctx.set_attr(&node, "value", py_value);
+ let py_value = expression_to_ast(vm, a);
+ vm.ctx.set_attr(&node, "value", py_value);
- let py_slice = expression_to_ast(ctx, b);
- ctx.set_attr(&node, "slice", py_slice);
+ let py_slice = expression_to_ast(vm, b);
+ vm.ctx.set_attr(&node, "slice", py_slice);
node
}
ast::Expression::Attribute { value, name } => {
- let node = create_node(ctx, "Attribute");
+ let node = create_node(vm, "Attribute");
- let py_value = expression_to_ast(ctx, value);
- ctx.set_attr(&node, "value", py_value);
+ let py_value = expression_to_ast(vm, value);
+ vm.ctx.set_attr(&node, "value", py_value);
- let py_attr = ctx.new_str(name.to_string());
- ctx.set_attr(&node, "attr", py_attr);
+ let py_attr = vm.ctx.new_str(name.to_string());
+ vm.ctx.set_attr(&node, "attr", py_attr);
node
}
ast::Expression::Starred { value } => {
- let node = create_node(ctx, "Starred");
+ let node = create_node(vm, "Starred");
- let py_value = expression_to_ast(ctx, value);
- ctx.set_attr(&node, "value", py_value);
+ let py_value = expression_to_ast(vm, value);
+ vm.ctx.set_attr(&node, "value", py_value);
node
}
ast::Expression::Slice { elements } => {
- let node = create_node(ctx, "Slice");
+ let node = create_node(vm, "Slice");
- let py_value = expressions_to_ast(ctx, elements);
- ctx.set_attr(&node, "bounds", py_value);
+ let py_value = expressions_to_ast(vm, elements);
+ vm.ctx.set_attr(&node, "bounds", py_value);
node
}
- ast::Expression::String { value } => string_to_ast(ctx, value),
+ ast::Expression::String { value } => string_to_ast(vm, value),
ast::Expression::Bytes { value } => {
- let node = create_node(ctx, "Bytes");
- ctx.set_attr(&node, "s", ctx.new_bytes(value.clone()));
+ let node = create_node(vm, "Bytes");
+ vm.ctx.set_attr(&node, "s", vm.ctx.new_bytes(value.clone()));
node
}
};
// TODO: retrieve correct lineno:
- let lineno = ctx.new_int(1);
- ctx.set_attr(&node, "lineno", lineno);
+ let lineno = vm.ctx.new_int(1);
+ vm.ctx.set_attr(&node, "lineno", lineno);
node
}
-fn parameters_to_ast(ctx: &PyContext, args: &ast::Parameters) -> PyObjectRef {
- let node = create_node(ctx, "arguments");
+fn parameters_to_ast(vm: &VirtualMachine, args: &ast::Parameters) -> PyObjectRef {
+ let node = create_node(vm, "arguments");
- ctx.set_attr(
+ vm.ctx.set_attr(
&node,
"args",
- ctx.new_list(args.args.iter().map(|a| parameter_to_ast(ctx, a)).collect()),
+ vm.ctx
+ .new_list(args.args.iter().map(|a| parameter_to_ast(vm, a)).collect()),
);
node
}
-fn parameter_to_ast(ctx: &PyContext, parameter: &ast::Parameter) -> PyObjectRef {
- let node = create_node(ctx, "arg");
+fn parameter_to_ast(vm: &VirtualMachine, parameter: &ast::Parameter) -> PyObjectRef {
+ let node = create_node(vm, "arg");
- let py_arg = ctx.new_str(parameter.arg.to_string());
- ctx.set_attr(&node, "arg", py_arg);
+ let py_arg = vm.ctx.new_str(parameter.arg.to_string());
+ vm.ctx.set_attr(&node, "arg", py_arg);
let py_annotation = if let Some(annotation) = ¶meter.annotation {
- expression_to_ast(ctx, annotation)
+ expression_to_ast(vm, annotation)
} else {
- ctx.none()
+ vm.ctx.none()
};
- ctx.set_attr(&node, "annotation", py_annotation);
+ vm.ctx.set_attr(&node, "annotation", py_annotation);
node
}
-fn comprehension_to_ast(ctx: &PyContext, comprehension: &ast::Comprehension) -> PyObjectRef {
- let node = create_node(ctx, "comprehension");
+fn comprehension_to_ast(vm: &VirtualMachine, comprehension: &ast::Comprehension) -> PyObjectRef {
+ let node = create_node(vm, "comprehension");
- let py_target = expression_to_ast(ctx, &comprehension.target);
- ctx.set_attr(&node, "target", py_target);
+ let py_target = expression_to_ast(vm, &comprehension.target);
+ vm.ctx.set_attr(&node, "target", py_target);
- let py_iter = expression_to_ast(ctx, &comprehension.iter);
- ctx.set_attr(&node, "iter", py_iter);
+ let py_iter = expression_to_ast(vm, &comprehension.iter);
+ vm.ctx.set_attr(&node, "iter", py_iter);
- let py_ifs = expressions_to_ast(ctx, &comprehension.ifs);
- ctx.set_attr(&node, "ifs", py_ifs);
+ let py_ifs = expressions_to_ast(vm, &comprehension.ifs);
+ vm.ctx.set_attr(&node, "ifs", py_ifs);
node
}
-fn string_to_ast(ctx: &PyContext, string: &ast::StringGroup) -> PyObjectRef {
+fn string_to_ast(vm: &VirtualMachine, string: &ast::StringGroup) -> PyObjectRef {
match string {
ast::StringGroup::Constant { value } => {
- let node = create_node(ctx, "Str");
- ctx.set_attr(&node, "s", ctx.new_str(value.clone()));
+ let node = create_node(vm, "Str");
+ vm.ctx.set_attr(&node, "s", vm.ctx.new_str(value.clone()));
node
}
ast::StringGroup::FormattedValue { value, .. } => {
- let node = create_node(ctx, "FormattedValue");
- let py_value = expression_to_ast(ctx, value);
- ctx.set_attr(&node, "value", py_value);
+ let node = create_node(vm, "FormattedValue");
+ let py_value = expression_to_ast(vm, value);
+ vm.ctx.set_attr(&node, "value", py_value);
node
}
ast::StringGroup::Joined { values } => {
- let node = create_node(ctx, "JoinedStr");
- let py_values = ctx.new_list(
+ let node = create_node(vm, "JoinedStr");
+ let py_values = vm.ctx.new_list(
values
.iter()
- .map(|value| string_to_ast(ctx, value))
+ .map(|value| string_to_ast(vm, value))
.collect(),
);
- ctx.set_attr(&node, "values", py_values);
+ vm.ctx.set_attr(&node, "values", py_values);
node
}
}
@@ -619,7 +635,7 @@ fn ast_parse(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
let internal_ast = parser::parse_program(&source_string)
.map_err(|err| vm.new_value_error(format!("{}", err)))?;
// source.clone();
- let ast_node = program_to_ast(&vm.ctx, &internal_ast);
+ let ast_node = program_to_ast(&vm, &internal_ast);
Ok(ast_node)
}
@@ -628,6 +644,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
"parse" => ctx.new_rustfunc(ast_parse),
"Module" => py_class!(ctx, "_ast.Module", ctx.object(), {}),
"FunctionDef" => py_class!(ctx, "_ast.FunctionDef", ctx.object(), {}),
- "Call" => py_class!(ctx, "_ast.Call", ctx.object(), {})
+ "Call" => py_class!(ctx, "_ast.Call", ctx.object(), {}),
+ "AST" => py_class!(ctx, "_ast.AST", ctx.object(), {}),
})
}
From e44b02b88f726408478377fc62f094661d59c8ce Mon Sep 17 00:00:00 2001
From: Adrian Wielgosik
Date: Mon, 25 Mar 2019 17:52:37 +0100
Subject: [PATCH 024/658] Avoid trace log in tests
---
tests/test_snippets.py | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tests/test_snippets.py b/tests/test_snippets.py
index 4be73b7bd..bc4c43a77 100644
--- a/tests/test_snippets.py
+++ b/tests/test_snippets.py
@@ -65,8 +65,7 @@ def run_via_cpython_bytecode(filename, test_type):
# Step2: run cpython bytecode:
env = os.environ.copy()
- log_level = 'info' if test_type == _TestType.benchmark else 'debug'
- env['RUST_LOG'] = '{},cargo=error,jobserver=error'.format(log_level)
+ env['RUST_LOG'] = 'info,cargo=error,jobserver=error'
env['RUST_BACKTRACE'] = '1'
with pushd(CPYTHON_RUNNER_DIR):
subprocess.check_call(['cargo', 'run', bytecode_filename], env=env)
@@ -74,8 +73,7 @@ def run_via_cpython_bytecode(filename, test_type):
def run_via_rustpython(filename, test_type):
env = os.environ.copy()
- log_level = 'info' if test_type == _TestType.benchmark else 'trace'
- env['RUST_LOG'] = '{},cargo=error,jobserver=error'.format(log_level)
+ env['RUST_LOG'] = 'info,cargo=error,jobserver=error'
env['RUST_BACKTRACE'] = '1'
if env.get('CODE_COVERAGE', 'false') == 'true':
subprocess.check_call(
From 4ab59a8e4c369104ab8518f651038877ada301f1 Mon Sep 17 00:00:00 2001
From: Adrian Wielgosik
Date: Mon, 25 Mar 2019 17:53:13 +0100
Subject: [PATCH 025/658] Do not run benchmarks in the main test suite
---
tests/test_snippets.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/tests/test_snippets.py b/tests/test_snippets.py
index bc4c43a77..7aa9c2456 100644
--- a/tests/test_snippets.py
+++ b/tests/test_snippets.py
@@ -17,7 +17,6 @@ import compile_code
class _TestType(enum.Enum):
functional = 1
- benchmark = 2
logger = logging.getLogger('tests')
@@ -25,7 +24,6 @@ ROOT_DIR = '..'
TEST_ROOT = os.path.abspath(os.path.join(ROOT_DIR, 'tests'))
TEST_DIRS = {
_TestType.functional: os.path.join(TEST_ROOT, 'snippets'),
- _TestType.benchmark: os.path.join(TEST_ROOT, 'benchmarks'),
}
CPYTHON_RUNNER_DIR = os.path.abspath(os.path.join(ROOT_DIR, 'py_code_object'))
RUSTPYTHON_RUNNER_DIR = os.path.abspath(os.path.join(ROOT_DIR))
From 16e04cf298a67f1c2686fe846177789425a26df4 Mon Sep 17 00:00:00 2001
From: Adrian Wielgosik
Date: Mon, 25 Mar 2019 17:54:04 +0100
Subject: [PATCH 026/658] Run rustpython tests without cargo middleman
---
tests/test_snippets.py | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/tests/test_snippets.py b/tests/test_snippets.py
index 7aa9c2456..7edbd7b7e 100644
--- a/tests/test_snippets.py
+++ b/tests/test_snippets.py
@@ -73,12 +73,13 @@ def run_via_rustpython(filename, test_type):
env = os.environ.copy()
env['RUST_LOG'] = 'info,cargo=error,jobserver=error'
env['RUST_BACKTRACE'] = '1'
+
+ target = 'release'
if env.get('CODE_COVERAGE', 'false') == 'true':
- subprocess.check_call(
- ['cargo', 'run', filename], env=env)
- else:
- subprocess.check_call(
- ['cargo', 'run', '--release', filename], env=env)
+ target = 'debug'
+ binary = os.path.abspath(os.path.join(ROOT_DIR, 'target', target, 'rustpython'))
+
+ subprocess.check_call([binary, filename], env=env)
def create_test_function(cls, filename, method, test_type):
@@ -120,4 +121,7 @@ def get_test_files():
# @populate('cpython_bytecode')
@populate('rustpython')
class SampleTestCase(unittest.TestCase):
- pass
+ @classmethod
+ def setUpClass(cls):
+ subprocess.check_call(['cargo', 'build'])
+ subprocess.check_call(['cargo', 'build', '--release'])
From 2131a8130cfcf344a81437d7c7413211976dc25e Mon Sep 17 00:00:00 2001
From: Adrian Wielgosik
Date: Mon, 25 Mar 2019 17:55:17 +0100
Subject: [PATCH 027/658] Clean up some tests
---
tests/snippets/append.py | 2 --
tests/snippets/strings.py | 8 ++++++++
tests/snippets/xfail_3.1.2.17.py | 7 -------
3 files changed, 8 insertions(+), 9 deletions(-)
delete mode 100644 tests/snippets/append.py
delete mode 100644 tests/snippets/xfail_3.1.2.17.py
diff --git a/tests/snippets/append.py b/tests/snippets/append.py
deleted file mode 100644
index a0490cb6d..000000000
--- a/tests/snippets/append.py
+++ /dev/null
@@ -1,2 +0,0 @@
-x = []
-x.append(1)
diff --git a/tests/snippets/strings.py b/tests/snippets/strings.py
index 4483b37f6..31511db11 100644
--- a/tests/snippets/strings.py
+++ b/tests/snippets/strings.py
@@ -1,3 +1,5 @@
+from testutils import assert_raises
+
assert "a" == 'a'
assert """a""" == "a"
assert len(""" " "" " "" """) == 11
@@ -124,3 +126,9 @@ assert 'a' <= 'a'
assert 'z' > 'b'
assert 'z' >= 'b'
assert 'a' >= 'a'
+
+def try_mutate_str():
+ word = "word"
+ word[0] = 'x'
+
+assert_raises(TypeError, try_mutate_str)
diff --git a/tests/snippets/xfail_3.1.2.17.py b/tests/snippets/xfail_3.1.2.17.py
deleted file mode 100644
index fc956bef4..000000000
--- a/tests/snippets/xfail_3.1.2.17.py
+++ /dev/null
@@ -1,7 +0,0 @@
-word = "Python"
-
-word[0] = "J" # Should raise a error, immutable
-word[2:] = "Jy" # Should raise a error, immutable
-
-
-
From 6ae10ed938a12dfdcede666a147fb4bba99666b7 Mon Sep 17 00:00:00 2001
From: Windel Bouwman
Date: Mon, 25 Mar 2019 20:23:13 +0100
Subject: [PATCH 028/658] Fix build and add extend_class macro usage for set
and frozenset
---
vm/src/obj/objset.rs | 180 +++++++++++++++----------------------------
1 file changed, 62 insertions(+), 118 deletions(-)
diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs
index 300dc9bca..72ee8c897 100644
--- a/vm/src/obj/objset.rs
+++ b/vm/src/obj/objset.rs
@@ -85,12 +85,12 @@ fn create_set(
PySet {
elements: RefCell::new(elements),
},
- PySet::class(vm).into_object(),
+ PySet::class(vm),
))
} else if objtype::issubclass(&cls, &vm.ctx.frozenset_type()) {
Ok(PyObject::new(
PyFrozenSet { elements: elements },
- PyFrozenSet::class(vm).into_object(),
+ PyFrozenSet::class(vm),
))
} else {
Err(vm.new_type_error(format!("{} is not a subtype of set or frozenset", cls)))
@@ -593,65 +593,43 @@ pub fn init(context: &PyContext) {
set(iterable) -> new set object\n\n\
Build an unordered collection of unique elements.";
- context.set_attr(set_type, "__contains__", context.new_rustfunc(set_contains));
- context.set_attr(set_type, "__len__", context.new_rustfunc(set_len));
- context.set_attr(set_type, "__new__", context.new_rustfunc(set_new));
- context.set_attr(set_type, "__repr__", context.new_rustfunc(set_repr));
- context.set_attr(set_type, "__eq__", context.new_rustfunc(set_eq));
- context.set_attr(set_type, "__ge__", context.new_rustfunc(set_ge));
- context.set_attr(set_type, "__gt__", context.new_rustfunc(set_gt));
- context.set_attr(set_type, "__le__", context.new_rustfunc(set_le));
- context.set_attr(set_type, "__lt__", context.new_rustfunc(set_lt));
- context.set_attr(set_type, "issubset", context.new_rustfunc(set_le));
- context.set_attr(set_type, "issuperset", context.new_rustfunc(set_ge));
- context.set_attr(set_type, "union", context.new_rustfunc(set_union));
- context.set_attr(set_type, "__or__", context.new_rustfunc(set_union));
- context.set_attr(
- set_type,
- "intersection",
- context.new_rustfunc(set_intersection),
- );
- context.set_attr(set_type, "__and__", context.new_rustfunc(set_intersection));
- context.set_attr(set_type, "difference", context.new_rustfunc(set_difference));
- context.set_attr(set_type, "__sub__", context.new_rustfunc(set_difference));
- context.set_attr(
- set_type,
- "symmetric_difference",
- context.new_rustfunc(set_symmetric_difference),
- );
- context.set_attr(
- set_type,
- "__xor__",
- context.new_rustfunc(set_symmetric_difference),
- );
- context.set_attr(set_type, "__doc__", context.new_str(set_doc.to_string()));
- context.set_attr(set_type, "add", context.new_rustfunc(set_add));
- context.set_attr(set_type, "remove", context.new_rustfunc(set_remove));
- context.set_attr(set_type, "discard", context.new_rustfunc(set_discard));
- context.set_attr(set_type, "clear", context.new_rustfunc(set_clear));
- context.set_attr(set_type, "copy", context.new_rustfunc(set_copy));
- context.set_attr(set_type, "pop", context.new_rustfunc(set_pop));
- context.set_attr(set_type, "update", context.new_rustfunc(set_update));
- context.set_attr(set_type, "__ior__", context.new_rustfunc(set_ior));
- context.set_attr(
- set_type,
- "intersection_update",
- context.new_rustfunc(set_intersection_update),
- );
- context.set_attr(set_type, "__iand__", context.new_rustfunc(set_iand));
- context.set_attr(
- set_type,
- "difference_update",
- context.new_rustfunc(set_difference_update),
- );
- context.set_attr(set_type, "__isub__", context.new_rustfunc(set_isub));
- context.set_attr(
- set_type,
- "symmetric_difference_update",
- context.new_rustfunc(set_symmetric_difference_update),
- );
- context.set_attr(set_type, "__ixor__", context.new_rustfunc(set_ixor));
- context.set_attr(set_type, "__iter__", context.new_rustfunc(set_iter));
+ extend_class!(context, set_type, {
+ "__contains__" => context.new_rustfunc(set_contains),
+ "__len__" => context.new_rustfunc(set_len),
+ "__new__" => context.new_rustfunc(set_new),
+ "__repr__" => context.new_rustfunc(set_repr),
+ "__eq__" => context.new_rustfunc(set_eq),
+ "__ge__" => context.new_rustfunc(set_ge),
+ "__gt__" => context.new_rustfunc(set_gt),
+ "__le__" => context.new_rustfunc(set_le),
+ "__lt__" => context.new_rustfunc(set_lt),
+ "issubset" => context.new_rustfunc(set_le),
+ "issuperset" => context.new_rustfunc(set_ge),
+ "union" => context.new_rustfunc(set_union),
+ "__or__" => context.new_rustfunc(set_union),
+ "intersection" => context.new_rustfunc(set_intersection),
+ "__and__" => context.new_rustfunc(set_intersection),
+ "difference" => context.new_rustfunc(set_difference),
+ "__sub__" => context.new_rustfunc(set_difference),
+ "symmetric_difference" => context.new_rustfunc(set_symmetric_difference),
+ "__xor__" => context.new_rustfunc(set_symmetric_difference),
+ "__doc__" => context.new_str(set_doc.to_string()),
+ "add" => context.new_rustfunc(set_add),
+ "remove" => context.new_rustfunc(set_remove),
+ "discard" => context.new_rustfunc(set_discard),
+ "clear" => context.new_rustfunc(set_clear),
+ "copy" => context.new_rustfunc(set_copy),
+ "pop" => context.new_rustfunc(set_pop),
+ "update" => context.new_rustfunc(set_update),
+ "__ior__" => context.new_rustfunc(set_ior),
+ "intersection_update" => context.new_rustfunc(set_intersection_update),
+ "__iand__" => context.new_rustfunc(set_iand),
+ "difference_update" => context.new_rustfunc(set_difference_update),
+ "__isub__" => context.new_rustfunc(set_isub),
+ "symmetric_difference_update" => context.new_rustfunc(set_symmetric_difference_update),
+ "__ixor__" => context.new_rustfunc(set_ixor),
+ "__iter__" => context.new_rustfunc(set_iter)
+ });
let frozenset_type = &context.frozenset_type;
@@ -659,61 +637,27 @@ pub fn init(context: &PyContext) {
frozenset(iterable) -> frozenset object\n\n\
Build an immutable unordered collection of unique elements.";
- context.set_attr(frozenset_type, "__new__", context.new_rustfunc(set_new));
- context.set_attr(frozenset_type, "__eq__", context.new_rustfunc(set_eq));
- context.set_attr(frozenset_type, "__ge__", context.new_rustfunc(set_ge));
- context.set_attr(frozenset_type, "__gt__", context.new_rustfunc(set_gt));
- context.set_attr(frozenset_type, "__le__", context.new_rustfunc(set_le));
- context.set_attr(frozenset_type, "__lt__", context.new_rustfunc(set_lt));
- context.set_attr(frozenset_type, "issubset", context.new_rustfunc(set_le));
- context.set_attr(frozenset_type, "issuperset", context.new_rustfunc(set_ge));
- context.set_attr(frozenset_type, "union", context.new_rustfunc(set_union));
- context.set_attr(frozenset_type, "__or__", context.new_rustfunc(set_union));
- context.set_attr(
- frozenset_type,
- "intersection",
- context.new_rustfunc(set_intersection),
- );
- context.set_attr(
- frozenset_type,
- "__and__",
- context.new_rustfunc(set_intersection),
- );
- context.set_attr(
- frozenset_type,
- "difference",
- context.new_rustfunc(set_difference),
- );
- context.set_attr(
- frozenset_type,
- "__sub__",
- context.new_rustfunc(set_difference),
- );
- context.set_attr(
- frozenset_type,
- "symmetric_difference",
- context.new_rustfunc(set_symmetric_difference),
- );
- context.set_attr(
- frozenset_type,
- "__xor__",
- context.new_rustfunc(set_symmetric_difference),
- );
- context.set_attr(
- frozenset_type,
- "__contains__",
- context.new_rustfunc(set_contains),
- );
- context.set_attr(frozenset_type, "__len__", context.new_rustfunc(set_len));
- context.set_attr(
- frozenset_type,
- "__doc__",
- context.new_str(frozenset_doc.to_string()),
- );
- context.set_attr(
- frozenset_type,
- "__repr__",
- context.new_rustfunc(frozenset_repr),
- );
- context.set_attr(frozenset_type, "copy", context.new_rustfunc(set_copy));
+ extend_class!(context, frozenset_type, {
+ "__new__" => context.new_rustfunc(set_new),
+ "__eq__" => context.new_rustfunc(set_eq),
+ "__ge__" => context.new_rustfunc(set_ge),
+ "__gt__" => context.new_rustfunc(set_gt),
+ "__le__" => context.new_rustfunc(set_le),
+ "__lt__" => context.new_rustfunc(set_lt),
+ "issubset" => context.new_rustfunc(set_le),
+ "issuperset" => context.new_rustfunc(set_ge),
+ "union" => context.new_rustfunc(set_union),
+ "__or__" => context.new_rustfunc(set_union),
+ "intersection" => context.new_rustfunc(set_intersection),
+ "__and__" => context.new_rustfunc(set_intersection),
+ "difference" => context.new_rustfunc(set_difference),
+ "__sub__" => context.new_rustfunc(set_difference),
+ "symmetric_difference" => context.new_rustfunc(set_symmetric_difference),
+ "__xor__" => context.new_rustfunc(set_symmetric_difference),
+ "__contains__" => context.new_rustfunc(set_contains),
+ "__len__" => context.new_rustfunc(set_len),
+ "__doc__" => context.new_str(frozenset_doc.to_string()),
+ "__repr__" => context.new_rustfunc(frozenset_repr),
+ "copy" => context.new_rustfunc(set_copy)
+ });
}
From 17b816fbf83069332441c98daee231a9772cf809 Mon Sep 17 00:00:00 2001
From: Adam Kelly
Date: Mon, 25 Mar 2019 20:37:47 +0000
Subject: [PATCH 029/658] Fix objset compilation error caused by merge race.
---
vm/src/obj/objset.rs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs
index 72ee8c897..7071cc6e4 100644
--- a/vm/src/obj/objset.rs
+++ b/vm/src/obj/objset.rs
@@ -86,11 +86,13 @@ fn create_set(
elements: RefCell::new(elements),
},
PySet::class(vm),
+ None,
))
} else if objtype::issubclass(&cls, &vm.ctx.frozenset_type()) {
Ok(PyObject::new(
PyFrozenSet { elements: elements },
PyFrozenSet::class(vm),
+ None,
))
} else {
Err(vm.new_type_error(format!("{} is not a subtype of set or frozenset", cls)))
From ac2a5e281c55cc9fce29491e1795152e498f2395 Mon Sep 17 00:00:00 2001
From: coolreader18 <33094578+coolreader18@users.noreply.github.com>
Date: Sun, 24 Mar 2019 13:36:13 -0400
Subject: [PATCH 030/658] Add comment explaining bytes -> Uint8Array conversion
---
wasm/lib/src/convert.rs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs
index 909955b6d..641eb3538 100644
--- a/wasm/lib/src/convert.rs
+++ b/wasm/lib/src/convert.rs
@@ -126,6 +126,10 @@ pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue {
{
let bytes = objbytes::get_value(&py_obj);
unsafe {
+ // `Uint8Array::view` is an `unsafe fn` because it provides
+ // a direct view into the WASM linear memory; if you were to allocate
+ // something with Rust that view would probably become invalid. It's safe
+ // because we then copy the array using `Uint8Array::slice`.
let view = Uint8Array::view(&bytes);
view.slice(0, bytes.len() as u32).into()
}
From cc4f3fdb4097a6701158da7c30a8bf1f70e2f954 Mon Sep 17 00:00:00 2001
From: Joey Hain
Date: Mon, 25 Mar 2019 19:18:01 -0700
Subject: [PATCH 031/658] Clean up TypeProtocol
---
vm/src/builtins.rs | 14 +++++++-------
vm/src/exceptions.rs | 2 +-
vm/src/frame.rs | 6 +++---
vm/src/function.rs | 2 +-
vm/src/macros.rs | 2 +-
vm/src/obj/objfloat.rs | 2 +-
vm/src/obj/objfunction.rs | 2 +-
vm/src/obj/objint.rs | 10 +++++-----
vm/src/obj/objiter.rs | 2 +-
vm/src/obj/objnone.rs | 10 +++++-----
vm/src/obj/objobject.rs | 24 ++++++++++++------------
vm/src/obj/objproperty.rs | 10 ++++++----
vm/src/obj/objsequence.rs | 4 ++--
vm/src/obj/objset.rs | 30 +++++++++++++++---------------
vm/src/obj/objstr.rs | 6 +++---
vm/src/obj/objsuper.rs | 2 +-
vm/src/obj/objtype.rs | 28 +++++++++-------------------
vm/src/pyobject.rs | 36 ++++++++++++++++++------------------
vm/src/stdlib/json.rs | 2 +-
vm/src/vm.rs | 16 ++++++++--------
20 files changed, 101 insertions(+), 109 deletions(-)
diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs
index 4d9fb7989..fbd2d5356 100644
--- a/vm/src/builtins.rs
+++ b/vm/src/builtins.rs
@@ -88,7 +88,7 @@ fn builtin_bin(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
fn builtin_callable(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(obj, None)]);
- let is_callable = objtype::class_has_attr(&obj.type_pyref(), "__call__");
+ let is_callable = objtype::class_has_attr(&obj.class(), "__call__");
Ok(vm.new_bool(is_callable))
}
@@ -240,7 +240,7 @@ fn make_scope(
} else if vm.isinstance(arg, &dict_type)? {
Some(arg)
} else {
- let arg_typ = arg.typ();
+ let arg_typ = arg.class();
let actual_type = vm.to_pystr(&arg_typ)?;
let expected_type_name = vm.to_pystr(&dict_type)?;
return Err(vm.new_type_error(format!(
@@ -368,7 +368,7 @@ fn builtin_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
Err(..) => Err(vm.new_type_error(format!(
"object of type '{}' has no method {:?}",
- objtype::get_type_name(&obj.typ()),
+ objtype::get_type_name(&obj.class()),
len_method_name
))),
}
@@ -607,7 +607,7 @@ fn builtin_reversed(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
// TODO: fallback to using __len__ and __getitem__, if object supports sequence protocol
Err(..) => Err(vm.new_type_error(format!(
"'{}' object is not reversible",
- objtype::get_type_name(&obj.typ()),
+ objtype::get_type_name(&obj.class()),
))),
}
}
@@ -802,9 +802,9 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
};
for base in bases.clone() {
- if objtype::issubclass(&base.type_pyref(), &metaclass) {
- metaclass = base.type_pyref();
- } else if !objtype::issubclass(&metaclass, &base.type_pyref()) {
+ if objtype::issubclass(&base.class(), &metaclass) {
+ metaclass = base.class();
+ } else if !objtype::issubclass(&metaclass, &base.class()) {
return Err(vm.new_type_error("metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases".to_string()));
}
}
diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs
index 3eb962edf..7177527da 100644
--- a/vm/src/exceptions.rs
+++ b/vm/src/exceptions.rs
@@ -68,7 +68,7 @@ fn exception_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
args,
required = [(exc, Some(vm.ctx.exceptions.exception_type.clone()))]
);
- let type_name = objtype::get_type_name(&exc.typ());
+ let type_name = objtype::get_type_name(&exc.class());
let msg = if let Ok(m) = vm.get_attribute(exc.clone(), "msg") {
match vm.to_pystr(&m) {
Ok(msg) => msg,
diff --git a/vm/src/frame.rs b/vm/src/frame.rs
index 3584a57a8..53479f8fc 100644
--- a/vm/src/frame.rs
+++ b/vm/src/frame.rs
@@ -949,7 +949,7 @@ impl Frame {
// let args = PyFuncArgs::default();
// TODO: what happens when we got an error during handling exception?
let args = if let Some(exc) = exc {
- let exc_type = exc.typ();
+ let exc_type = exc.class().into_object();
let exc_val = exc.clone();
let exc_tb = vm.ctx.none(); // TODO: retrieve traceback?
vec![exc_type, exc_val, exc_tb]
@@ -1093,7 +1093,7 @@ impl Frame {
Ok(found) => Ok(found),
Err(_) => Err(vm.new_type_error(format!(
"{} has no __contains__ method",
- objtype::get_type_name(&haystack.typ())
+ objtype::get_type_name(&haystack.class())
))),
}
}
@@ -1103,7 +1103,7 @@ impl Frame {
Ok(found) => Ok(vm.ctx.new_bool(!objbool::get_value(&found))),
Err(_) => Err(vm.new_type_error(format!(
"{} has no __contains__ method",
- objtype::get_type_name(&haystack.typ())
+ objtype::get_type_name(&haystack.class())
))),
}
}
diff --git a/vm/src/function.rs b/vm/src/function.rs
index ed959d85c..1c61ffc87 100644
--- a/vm/src/function.rs
+++ b/vm/src/function.rs
@@ -99,7 +99,7 @@ impl PyFuncArgs {
Ok(Some(kwarg))
} else {
let expected_ty_name = vm.to_pystr(&ty)?;
- let actual_ty_name = vm.to_pystr(&kwarg.typ())?;
+ let actual_ty_name = vm.to_pystr(&kwarg.class())?;
Err(vm.new_type_error(format!(
"argument of type {} is required for named parameter `{}` (got: {})",
expected_ty_name, key, actual_ty_name
diff --git a/vm/src/macros.rs b/vm/src/macros.rs
index 0c205ffc8..a63186797 100644
--- a/vm/src/macros.rs
+++ b/vm/src/macros.rs
@@ -20,7 +20,7 @@ macro_rules! type_check {
let arg = &$args.args[$arg_count];
if !$crate::obj::objtype::isinstance(arg, &expected_type) {
- let arg_typ = arg.typ();
+ let arg_typ = arg.class();
let expected_type_name = $vm.to_pystr(&expected_type)?;
let actual_type = $vm.to_pystr(&arg_typ)?;
return Err($vm.new_type_error(format!(
diff --git a/vm/src/obj/objfloat.rs b/vm/src/obj/objfloat.rs
index 958d368a8..5e68f5960 100644
--- a/vm/src/obj/objfloat.rs
+++ b/vm/src/obj/objfloat.rs
@@ -190,7 +190,7 @@ impl PyFloatRef {
}
}
} else {
- let type_name = objtype::get_type_name(&arg.typ());
+ let type_name = objtype::get_type_name(&arg.class());
return Err(vm.new_type_error(format!("can't convert {} to float", type_name)));
};
PyFloat { value }.into_ref_with_type(vm, cls)
diff --git a/vm/src/obj/objfunction.rs b/vm/src/obj/objfunction.rs
index 1488ee79c..507d7697a 100644
--- a/vm/src/obj/objfunction.rs
+++ b/vm/src/obj/objfunction.rs
@@ -76,7 +76,7 @@ fn bind_method(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
required = [(function, None), (obj, None), (cls, None)]
);
- if obj.is(&vm.get_none()) && !cls.is(&obj.typ()) {
+ if obj.is(&vm.get_none()) && !cls.is(&obj.class()) {
Ok(function.clone())
} else {
Ok(vm.ctx.new_bound_method(function.clone(), obj.clone()))
diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs
index dd40f06a4..f31997ead 100644
--- a/vm/src/obj/objint.rs
+++ b/vm/src/obj/objint.rs
@@ -213,8 +213,8 @@ impl PyIntRef {
if !objtype::isinstance(&other, &vm.ctx.int_type()) {
return Err(vm.new_type_error(format!(
"unsupported operand type(s) for << '{}' and '{}'",
- objtype::get_type_name(&self.as_object().typ()),
- objtype::get_type_name(&other.typ())
+ objtype::get_type_name(&self.as_object().class()),
+ objtype::get_type_name(&other.class())
)));
}
@@ -236,8 +236,8 @@ impl PyIntRef {
if !objtype::isinstance(&other, &vm.ctx.int_type()) {
return Err(vm.new_type_error(format!(
"unsupported operand type(s) for >> '{}' and '{}'",
- objtype::get_type_name(&self.as_object().typ()),
- objtype::get_type_name(&other.typ())
+ objtype::get_type_name(&self.as_object().class()),
+ objtype::get_type_name(&other.class())
)));
}
@@ -420,7 +420,7 @@ pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, base: u32) -> PyResult PyResult {
vm.call_method(iter_target, "__iter__", vec![])
- // let type_str = objstr::get_value(&vm.to_str(iter_target.typ()).unwrap());
+ // let type_str = objstr::get_value(&vm.to_str(iter_target.class()).unwrap());
// let type_error = vm.new_type_error(format!("Cannot iterate over {}", type_str));
// return Err(type_error);
}
diff --git a/vm/src/obj/objnone.rs b/vm/src/obj/objnone.rs
index 840b00ecc..aff20f465 100644
--- a/vm/src/obj/objnone.rs
+++ b/vm/src/obj/objnone.rs
@@ -12,7 +12,7 @@ pub type PyNoneRef = PyRef;
impl PyValue for PyNone {
fn class(vm: &VirtualMachine) -> PyClassRef {
- vm.ctx.none().type_pyref()
+ vm.ctx.none().class()
}
}
@@ -44,7 +44,7 @@ impl PyNoneRef {
fn get_attribute(self, name: PyStringRef, vm: &VirtualMachine) -> PyResult {
trace!("None.__getattribute__({:?}, {:?})", self, name);
- let cls = self.typ();
+ let cls = self.class();
// Properties use a comparision with None to determine if they are either invoked by am
// instance binding or a class binding. But if the object itself is None then this detection
@@ -69,7 +69,7 @@ impl PyNoneRef {
}
if let Some(attr) = class_get_attr(&cls, &name.value) {
- let attr_class = attr.type_pyref();
+ let attr_class = attr.class();
if class_has_attr(&attr_class, "__set__") {
if let Some(get_func) = class_get_attr(&attr_class, "__get__") {
return call_descriptor(
@@ -88,7 +88,7 @@ impl PyNoneRef {
// Ok(obj_attr)
// } else
if let Some(attr) = class_get_attr(&cls, &name.value) {
- let attr_class = attr.type_pyref();
+ let attr_class = attr.class();
if let Some(get_func) = class_get_attr(&attr_class, "__get__") {
call_descriptor(attr, get_func, self.into_object(), cls.into_object(), vm)
} else {
@@ -107,7 +107,7 @@ fn none_new(_: PyClassRef, vm: &VirtualMachine) -> PyNoneRef {
}
pub fn init(context: &PyContext) {
- extend_class!(context, &context.none.typ(), {
+ extend_class!(context, &context.none.class(), {
"__new__" => context.new_rustfunc(none_new),
"__repr__" => context.new_rustfunc(PyNoneRef::repr),
"__bool__" => context.new_rustfunc(PyNoneRef::bool),
diff --git a/vm/src/obj/objobject.rs b/vm/src/obj/objobject.rs
index 60473fad0..14dbb2e26 100644
--- a/vm/src/obj/objobject.rs
+++ b/vm/src/obj/objobject.rs
@@ -104,10 +104,10 @@ fn object_setattr(
vm: &VirtualMachine,
) -> PyResult<()> {
trace!("object.__setattr__({:?}, {}, {:?})", obj, attr_name, value);
- let cls = obj.type_pyref();
+ let cls = obj.class();
if let Some(attr) = objtype::class_get_attr(&cls, &attr_name.value) {
- if let Some(descriptor) = objtype::class_get_attr(&attr.type_pyref(), "__set__") {
+ if let Some(descriptor) = objtype::class_get_attr(&attr.class(), "__set__") {
return vm
.invoke(descriptor, vec![attr, obj.clone(), value])
.map(|_| ());
@@ -118,7 +118,7 @@ fn object_setattr(
dict.set_item(&vm.ctx, &attr_name.value, value);
Ok(())
} else {
- let type_name = objtype::get_type_name(obj.type_ref());
+ let type_name = objtype::get_type_name(&obj.class());
Err(vm.new_attribute_error(format!(
"'{}' object has no attribute '{}'",
type_name, &attr_name.value
@@ -127,10 +127,10 @@ fn object_setattr(
}
fn object_delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
- let cls = obj.type_pyref();
+ let cls = obj.class();
if let Some(attr) = objtype::class_get_attr(&cls, &attr_name.value) {
- if let Some(descriptor) = objtype::class_get_attr(&attr.type_pyref(), "__delete__") {
+ if let Some(descriptor) = objtype::class_get_attr(&attr.class(), "__delete__") {
return vm.invoke(descriptor, vec![attr, obj.clone()]).map(|_| ());
}
}
@@ -139,7 +139,7 @@ fn object_delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine)
dict.del_item(&attr_name.value);
Ok(())
} else {
- let type_name = objtype::get_type_name(obj.type_ref());
+ let type_name = objtype::get_type_name(&obj.class());
Err(vm.new_attribute_error(format!(
"'{}' object has no attribute '{}'",
type_name, &attr_name.value
@@ -154,7 +154,7 @@ fn object_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
fn object_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(obj, Some(vm.ctx.object()))]);
- let type_name = objtype::get_type_name(&obj.typ());
+ let type_name = objtype::get_type_name(&obj.class());
let address = obj.get_id();
Ok(vm.new_str(format!("<{} object at 0x{:x}>", type_name, address)))
}
@@ -216,7 +216,7 @@ fn object_init(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
}
fn object_class(obj: PyObjectRef, _vm: &VirtualMachine) -> PyObjectRef {
- obj.typ()
+ obj.class().into_object()
}
fn object_class_setter(
@@ -224,7 +224,7 @@ fn object_class_setter(
_value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult {
- let type_repr = vm.to_pystr(&instance.typ())?;
+ let type_repr = vm.to_pystr(&instance.class())?;
Err(vm.new_type_error(format!("can't change class of type '{}'", type_repr)))
}
@@ -247,10 +247,10 @@ fn object_getattribute(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
);
let name = objstr::get_value(&name_str);
trace!("object.__getattribute__({:?}, {:?})", obj, name);
- let cls = obj.type_pyref();
+ let cls = obj.class();
if let Some(attr) = objtype::class_get_attr(&cls, &name) {
- let attr_class = attr.type_pyref();
+ let attr_class = attr.class();
if objtype::class_has_attr(&attr_class, "__set__") {
if let Some(descriptor) = objtype::class_get_attr(&attr_class, "__get__") {
return vm.invoke(descriptor, vec![attr, obj.clone(), cls.into_object()]);
@@ -279,7 +279,7 @@ fn object_getattr(obj: &PyObjectRef, attr_name: &str) -> Option {
pub fn get_attributes(obj: &PyObjectRef) -> PyAttributes {
// Get class attributes:
- let mut attributes = objtype::get_attributes(obj.type_pyref());
+ let mut attributes = objtype::get_attributes(obj.class());
// Get instance attributes:
if let Some(dict) = &obj.dict {
diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs
index e6b11904e..9d7217110 100644
--- a/vm/src/obj/objproperty.rs
+++ b/vm/src/obj/objproperty.rs
@@ -6,7 +6,9 @@ use crate::function::IntoPyNativeFunc;
use crate::function::OptionalArg;
use crate::obj::objstr::PyStringRef;
use crate::obj::objtype::PyClassRef;
-use crate::pyobject::{IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue};
+use crate::pyobject::{
+ IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
+};
use crate::vm::VirtualMachine;
/// Read-only property, doesn't have __set__ or __delete__
@@ -137,7 +139,7 @@ impl PyPropertyRef {
setter: self.setter.clone(),
deleter: self.deleter.clone(),
}
- .into_ref_with_type(vm, self.typ())
+ .into_ref_with_type(vm, TypeProtocol::class(&self))
}
fn setter(self, setter: Option, vm: &VirtualMachine) -> PyResult {
@@ -146,7 +148,7 @@ impl PyPropertyRef {
setter: setter.or_else(|| self.setter.clone()),
deleter: self.deleter.clone(),
}
- .into_ref_with_type(vm, self.typ())
+ .into_ref_with_type(vm, TypeProtocol::class(&self))
}
fn deleter(self, deleter: Option, vm: &VirtualMachine) -> PyResult {
@@ -155,7 +157,7 @@ impl PyPropertyRef {
setter: self.setter.clone(),
deleter: deleter.or_else(|| self.deleter.clone()),
}
- .into_ref_with_type(vm, self.typ())
+ .into_ref_with_type(vm, TypeProtocol::class(&self))
}
}
diff --git a/vm/src/obj/objsequence.rs b/vm/src/obj/objsequence.rs
index 80f4bf40f..a07b2454d 100644
--- a/vm/src/obj/objsequence.rs
+++ b/vm/src/obj/objsequence.rs
@@ -163,13 +163,13 @@ pub fn get_item(
if sequence.payload::().is_some() {
Ok(PyObject::new(
PyList::from(elements.to_vec().get_slice_items(vm, &subscript)?),
- sequence.type_pyref(),
+ sequence.class(),
None,
))
} else if sequence.payload::().is_some() {
Ok(PyObject::new(
PyTuple::from(elements.to_vec().get_slice_items(vm, &subscript)?),
- sequence.type_pyref(),
+ sequence.class(),
None,
))
} else {
diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs
index 7071cc6e4..ad82c34de 100644
--- a/vm/src/obj/objset.rs
+++ b/vm/src/obj/objset.rs
@@ -231,16 +231,16 @@ fn set_new(cls: PyClassRef, iterable: OptionalArg, vm: &VirtualMach
fn set_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
trace!("set.len called with: {:?}", args);
arg_check!(vm, args, required = [(s, None)]);
- validate_set_or_frozenset(vm, s.type_pyref())?;
+ validate_set_or_frozenset(vm, s.class())?;
let elements = get_elements(s);
Ok(vm.context().new_int(elements.len()))
}
fn set_copy(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
trace!("set.copy called with: {:?}", obj);
- validate_set_or_frozenset(vm, obj.type_pyref())?;
+ validate_set_or_frozenset(vm, obj.class())?;
let elements = get_elements(&obj).clone();
- create_set(vm, elements, obj.type_pyref())
+ create_set(vm, elements, obj.class())
}
fn set_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -265,7 +265,7 @@ fn set_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
pub fn set_contains(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(set, None), (needle, None)]);
- validate_set_or_frozenset(vm, set.type_pyref())?;
+ validate_set_or_frozenset(vm, set.class())?;
for element in get_elements(set).iter() {
match vm._eq(needle.clone(), element.1.clone()) {
Ok(value) => {
@@ -333,8 +333,8 @@ fn set_compare_inner(
) -> PyResult {
arg_check!(vm, args, required = [(zelf, None), (other, None)]);
- validate_set_or_frozenset(vm, zelf.type_pyref())?;
- validate_set_or_frozenset(vm, other.type_pyref())?;
+ validate_set_or_frozenset(vm, zelf.class())?;
+ validate_set_or_frozenset(vm, other.class())?;
let get_zelf = |swap: bool| -> &PyObjectRef {
if swap {
@@ -370,13 +370,13 @@ fn set_compare_inner(
}
fn set_union(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
- validate_set_or_frozenset(vm, zelf.type_pyref())?;
- validate_set_or_frozenset(vm, other.type_pyref())?;
+ validate_set_or_frozenset(vm, zelf.class())?;
+ validate_set_or_frozenset(vm, other.class())?;
let mut elements = get_elements(&zelf).clone();
elements.extend(get_elements(&other).clone());
- create_set(vm, elements, zelf.type_pyref())
+ create_set(vm, elements, zelf.class())
}
fn set_intersection(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
@@ -392,8 +392,8 @@ fn set_symmetric_difference(
other: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult {
- validate_set_or_frozenset(vm, zelf.type_pyref())?;
- validate_set_or_frozenset(vm, other.type_pyref())?;
+ validate_set_or_frozenset(vm, zelf.class())?;
+ validate_set_or_frozenset(vm, other.class())?;
let mut elements = HashMap::new();
for element in get_elements(&zelf).iter() {
@@ -410,7 +410,7 @@ fn set_symmetric_difference(
}
}
- create_set(vm, elements, zelf.type_pyref())
+ create_set(vm, elements, zelf.class())
}
enum SetCombineOperation {
@@ -424,8 +424,8 @@ fn set_combine_inner(
vm: &VirtualMachine,
op: SetCombineOperation,
) -> PyResult {
- validate_set_or_frozenset(vm, zelf.type_pyref())?;
- validate_set_or_frozenset(vm, other.type_pyref())?;
+ validate_set_or_frozenset(vm, zelf.class())?;
+ validate_set_or_frozenset(vm, other.class())?;
let mut elements = HashMap::new();
for element in get_elements(&zelf).iter() {
@@ -439,7 +439,7 @@ fn set_combine_inner(
}
}
- create_set(vm, elements, zelf.type_pyref())
+ create_set(vm, elements, zelf.class())
}
fn set_pop(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
diff --git a/vm/src/obj/objstr.rs b/vm/src/obj/objstr.rs
index 67ee8e5e7..aa62812a2 100644
--- a/vm/src/obj/objstr.rs
+++ b/vm/src/obj/objstr.rs
@@ -715,7 +715,7 @@ fn str_format(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
let zelf = &args.args[0];
if !objtype::isinstance(&zelf, &vm.ctx.str_type()) {
- let zelf_typ = zelf.typ();
+ let zelf_typ = zelf.class();
let actual_type = vm.to_pystr(&zelf_typ)?;
return Err(vm.new_type_error(format!(
"descriptor 'format' requires a 'str' object but received a '{}'",
@@ -738,7 +738,7 @@ fn call_object_format(vm: &VirtualMachine, argument: PyObjectRef, format_spec: &
let returned_type = vm.ctx.new_str(format_spec.to_string());
let result = vm.call_method(&argument, "__format__", vec![returned_type])?;
if !objtype::isinstance(&result, &vm.ctx.str_type()) {
- let result_type = result.typ();
+ let result_type = result.class();
let actual_type = vm.to_pystr(&result_type)?;
return Err(vm.new_type_error(format!("__format__ must return a str, not {}", actual_type)));
}
@@ -809,7 +809,7 @@ fn str_new(
OptionalArg::Present(ref input) => vm.to_str(input)?.into_object(),
OptionalArg::Missing => vm.new_str("".to_string()),
};
- if string.typ().is(&cls) {
+ if string.class().is(&cls) {
TryFromObject::try_from_object(vm, string)
} else {
let payload = string.payload::().unwrap();
diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs
index f04fb6605..fad365e24 100644
--- a/vm/src/obj/objsuper.rs
+++ b/vm/src/obj/objsuper.rs
@@ -112,7 +112,7 @@ fn super_new(
// Check type argument:
if !objtype::isinstance(py_type.as_object(), &vm.get_type()) {
- let type_name = objtype::get_type_name(py_type.as_object().type_ref());
+ let type_name = objtype::get_type_name(&py_type.as_object().class());
return Err(vm.new_type_error(format!(
"super() argument 1 must be type, not {}",
type_name
diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs
index d87ca3843..857ec402f 100644
--- a/vm/src/obj/objtype.rs
+++ b/vm/src/obj/objtype.rs
@@ -39,12 +39,6 @@ impl PyValue for PyClass {
}
}
-impl TypeProtocol for PyClassRef {
- fn type_ref(&self) -> &PyObjectRef {
- &self.as_object().type_ref()
- }
-}
-
struct IterMro<'a> {
cls: &'a PyClassRef,
offset: Option,
@@ -117,10 +111,10 @@ impl PyClassRef {
fn getattribute(self, name_ref: PyStringRef, vm: &VirtualMachine) -> PyResult {
let name = &name_ref.value;
trace!("type.__getattribute__({:?}, {:?})", self, name);
- let mcl = self.type_pyref();
+ let mcl = self.class();
if let Some(attr) = class_get_attr(&mcl, &name) {
- let attr_class = attr.type_pyref();
+ let attr_class = attr.class();
if class_has_attr(&attr_class, "__set__") {
if let Some(descriptor) = class_get_attr(&attr_class, "__get__") {
return vm.invoke(
@@ -132,7 +126,7 @@ impl PyClassRef {
}
if let Some(attr) = class_get_attr(&self, &name) {
- let attr_class = attr.type_pyref();
+ let attr_class = attr.class();
if let Some(descriptor) = class_get_attr(&attr_class, "__get__") {
let none = vm.get_none();
return vm.invoke(descriptor, vec![attr, none, self.into_object()]);
@@ -156,8 +150,8 @@ impl PyClassRef {
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
- if let Some(attr) = class_get_attr(&self.type_pyref(), &attr_name.value) {
- if let Some(descriptor) = class_get_attr(&attr.type_pyref(), "__set__") {
+ if let Some(attr) = class_get_attr(&self.class(), &attr_name.value) {
+ if let Some(descriptor) = class_get_attr(&attr.class(), "__set__") {
vm.invoke(descriptor, vec![attr, self.into_object(), value])?;
return Ok(());
}
@@ -218,7 +212,7 @@ fn _mro(cls: &PyClassRef) -> Vec {
/// Determines if `obj` actually an instance of `cls`, this doesn't call __instancecheck__, so only
/// use this if `cls` is known to have not overridden the base __instancecheck__ magic method.
pub fn isinstance(obj: &PyObjectRef, cls: &PyClassRef) -> bool {
- issubclass(&obj.type_pyref(), &cls)
+ issubclass(&obj.class(), &cls)
}
/// Determines if `subclass` is actually a subclass of `cls`, this doesn't call __subclasscheck__,
@@ -229,18 +223,14 @@ pub fn issubclass(subclass: &PyClassRef, cls: &PyClassRef) -> bool {
subclass.is(cls) || mro.iter().any(|c| c.is(cls.as_object()))
}
-pub fn get_type_name(typ: &PyObjectRef) -> String {
- if let Some(PyClass { name, .. }) = &typ.payload::() {
- name.clone()
- } else {
- panic!("Cannot get type_name of non-type type {:?}", typ);
- }
+pub fn get_type_name(typ: &PyClassRef) -> String {
+ typ.name.clone()
}
pub fn type_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
debug!("type.__new__ {:?}", args);
if args.args.len() == 2 {
- Ok(args.args[1].typ())
+ Ok(args.args[1].class().into_object())
} else if args.args.len() == 4 {
let (typ, name, bases, dict) = args.bind(vm)?;
type_new_class(vm, typ, name, bases, dict).map(|x| x.into_object())
diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs
index 78e82c51b..739012c5e 100644
--- a/vm/src/pyobject.rs
+++ b/vm/src/pyobject.rs
@@ -88,7 +88,7 @@ impl fmt::Display for PyObject {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::TypeProtocol;
if let Some(PyClass { ref name, .. }) = self.payload::() {
- let type_name = objtype::get_type_name(&self.typ());
+ let type_name = objtype::get_type_name(&self.class());
// We don't have access to a vm, so just assume that if its parent's name
// is type, it's a type
if type_name == "type" {
@@ -101,7 +101,7 @@ impl fmt::Display for PyObject {
if let Some(PyModule { ref name, .. }) = self.payload::() {
return write!(f, "module '{}'", name);
}
- write!(f, "'{}' object", objtype::get_type_name(&self.typ()))
+ write!(f, "'{}' object", objtype::get_type_name(&self.class()))
}
}
@@ -163,7 +163,7 @@ pub struct PyNotImplemented;
impl PyValue for PyNotImplemented {
fn class(vm: &VirtualMachine) -> PyClassRef {
- vm.ctx.not_implemented().type_pyref()
+ vm.ctx.not_implemented().class()
}
}
@@ -772,7 +772,7 @@ impl PyRef {
pub fn typ(&self) -> PyClassRef {
PyRef {
- obj: self.obj.typ(),
+ obj: self.obj.class().into_object(),
_payload: PhantomData,
}
}
@@ -802,7 +802,7 @@ where
} else {
let class = T::class(vm);
let expected_type = vm.to_pystr(&class)?;
- let actual_type = vm.to_pystr(&obj.typ())?;
+ let actual_type = vm.to_pystr(&obj.class())?;
Err(vm.new_type_error(format!(
"Expected type {}, not {}",
expected_type, actual_type,
@@ -877,18 +877,12 @@ impl IdProtocol for PyRef {
}
pub trait TypeProtocol {
- fn typ(&self) -> PyObjectRef {
- self.type_ref().clone()
- }
- fn type_pyref(&self) -> PyClassRef {
- self.typ().downcast().unwrap()
- }
- fn type_ref(&self) -> &PyObjectRef;
+ fn class(&self) -> PyClassRef;
}
impl TypeProtocol for PyObjectRef {
- fn type_ref(&self) -> &PyObjectRef {
- (**self).type_ref()
+ fn class(&self) -> PyClassRef {
+ (**self).class()
}
}
@@ -896,8 +890,14 @@ impl TypeProtocol for PyObject
where
T: ?Sized + PyObjectPayload,
{
- fn type_ref(&self) -> &PyObjectRef {
- self.typ.as_object()
+ fn class(&self) -> PyClassRef {
+ self.typ.clone()
+ }
+}
+
+impl TypeProtocol for PyRef {
+ fn class(&self) -> PyClassRef {
+ self.obj.typ.clone()
}
}
@@ -956,7 +956,7 @@ pub trait BufferProtocol {
impl BufferProtocol for PyObjectRef {
fn readonly(&self) -> bool {
- match objtype::get_type_name(&self.typ()).as_ref() {
+ match objtype::get_type_name(&self.class()).as_ref() {
"bytes" => false,
"bytearray" | "memoryview" => true,
_ => panic!("Bytes-Like type expected not {:?}", self),
@@ -1249,7 +1249,7 @@ where
"must be {} or {}, not {}",
A::class(vm),
B::class(vm),
- obj.type_pyref()
+ obj.class()
))
})
}
diff --git a/vm/src/stdlib/json.rs b/vm/src/stdlib/json.rs
index eac3619c2..b881b7a72 100644
--- a/vm/src/stdlib/json.rs
+++ b/vm/src/stdlib/json.rs
@@ -74,7 +74,7 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
} else {
Err(serde::ser::Error::custom(format!(
"Object of type '{:?}' is not serializable",
- self.pyobject.typ()
+ self.pyobject.class()
)))
}
}
diff --git a/vm/src/vm.rs b/vm/src/vm.rs
index 0ee9798ab..92c264bcd 100644
--- a/vm/src/vm.rs
+++ b/vm/src/vm.rs
@@ -174,8 +174,8 @@ impl VirtualMachine {
b: PyObjectRef,
op: &str,
) -> PyObjectRef {
- let a_type_name = objtype::get_type_name(&a.typ());
- let b_type_name = objtype::get_type_name(&b.typ());
+ let a_type_name = objtype::get_type_name(&a.class());
+ let b_type_name = objtype::get_type_name(&b.class());
self.new_type_error(format!(
"Unsupported operand types for '{}': '{}' and '{}'",
op, a_type_name, b_type_name
@@ -270,7 +270,7 @@ impl VirtualMachine {
pub fn isinstance(&self, obj: &PyObjectRef, cls: &PyClassRef) -> PyResult {
// cpython first does an exact check on the type, although documentation doesn't state that
// https://github.com/python/cpython/blob/a24107b04c1277e3c1105f98aff5bfa3a98b33a0/Objects/abstract.c#L2408
- if Rc::ptr_eq(&obj.typ(), cls.as_object()) {
+ if Rc::ptr_eq(&obj.class().into_object(), cls.as_object()) {
Ok(true)
} else {
let ret = self.call_method(cls.as_object(), "__instancecheck__", vec![obj.clone()])?;
@@ -286,10 +286,10 @@ impl VirtualMachine {
}
pub fn call_get_descriptor(&self, attr: PyObjectRef, obj: PyObjectRef) -> PyResult {
- let attr_class = attr.type_pyref();
+ let attr_class = attr.class();
if let Some(descriptor) = objtype::class_get_attr(&attr_class, "__get__") {
- let cls = obj.typ();
- self.invoke(descriptor, vec![attr, obj.clone(), cls])
+ let cls = obj.class();
+ self.invoke(descriptor, vec![attr, obj.clone(), cls.into_object()])
} else {
Ok(attr)
}
@@ -300,7 +300,7 @@ impl VirtualMachine {
T: Into,
{
// This is only used in the vm for magic methods, which use a greatly simplified attribute lookup.
- let cls = obj.type_pyref();
+ let cls = obj.class();
match objtype::class_get_attr(&cls, method_name) {
Some(func) => {
trace!(
@@ -583,7 +583,7 @@ impl VirtualMachine {
// get_method should be used for internal access to magic methods (by-passing
// the full getattribute look-up.
pub fn get_method(&self, obj: PyObjectRef, method_name: &str) -> PyResult {
- let cls = obj.type_pyref();
+ let cls = obj.class();
match objtype::class_get_attr(&cls, method_name) {
Some(method) => self.call_get_descriptor(method, obj.clone()),
None => Err(self.new_type_error(format!("{} has no method {:?}", obj, method_name))),
From 6474a4a6ef895c8b57e4482ec6d26b0474ffbd2c Mon Sep 17 00:00:00 2001
From: Joey Hain
Date: Mon, 25 Mar 2019 19:18:07 -0700
Subject: [PATCH 032/658] Remove objtype::get_type_name()
---
vm/src/builtins.rs | 7 ++-----
vm/src/exceptions.rs | 3 +--
vm/src/frame.rs | 14 ++++++--------
vm/src/obj/objfloat.rs | 3 +--
vm/src/obj/objint.rs | 15 +++------------
vm/src/obj/objobject.rs | 11 +++++------
vm/src/obj/objsuper.rs | 3 +--
vm/src/obj/objtype.rs | 4 ----
vm/src/pyobject.rs | 6 +++---
vm/src/vm.rs | 6 +++---
10 files changed, 25 insertions(+), 47 deletions(-)
diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs
index fbd2d5356..27ce8aadd 100644
--- a/vm/src/builtins.rs
+++ b/vm/src/builtins.rs
@@ -368,7 +368,7 @@ fn builtin_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
Err(..) => Err(vm.new_type_error(format!(
"object of type '{}' has no method {:?}",
- objtype::get_type_name(&obj.class()),
+ obj.class(),
len_method_name
))),
}
@@ -605,10 +605,7 @@ fn builtin_reversed(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
match vm.get_method(obj.clone(), "__reversed__") {
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
// TODO: fallback to using __len__ and __getitem__, if object supports sequence protocol
- Err(..) => Err(vm.new_type_error(format!(
- "'{}' object is not reversible",
- objtype::get_type_name(&obj.class()),
- ))),
+ Err(..) => Err(vm.new_type_error(format!("'{}' object is not reversible", obj.class()))),
}
}
// builtin_reversed
diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs
index 7177527da..f850d7697 100644
--- a/vm/src/exceptions.rs
+++ b/vm/src/exceptions.rs
@@ -68,7 +68,6 @@ fn exception_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
args,
required = [(exc, Some(vm.ctx.exceptions.exception_type.clone()))]
);
- let type_name = objtype::get_type_name(&exc.class());
let msg = if let Ok(m) = vm.get_attribute(exc.clone(), "msg") {
match vm.to_pystr(&m) {
Ok(msg) => msg,
@@ -77,7 +76,7 @@ fn exception_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
} else {
panic!("Error message must be set");
};
- let s = format!("{}: {}", type_name, msg);
+ let s = format!("{}: {}", exc.class(), msg);
Ok(vm.new_str(s))
}
diff --git a/vm/src/frame.rs b/vm/src/frame.rs
index 53479f8fc..6f8815cbe 100644
--- a/vm/src/frame.rs
+++ b/vm/src/frame.rs
@@ -1091,20 +1091,18 @@ impl Frame {
fn _in(&self, vm: &VirtualMachine, needle: PyObjectRef, haystack: PyObjectRef) -> PyResult {
match self._membership(vm, needle, &haystack) {
Ok(found) => Ok(found),
- Err(_) => Err(vm.new_type_error(format!(
- "{} has no __contains__ method",
- objtype::get_type_name(&haystack.class())
- ))),
+ Err(_) => {
+ Err(vm.new_type_error(format!("{} has no __contains__ method", haystack.class())))
+ }
}
}
fn _not_in(&self, vm: &VirtualMachine, needle: PyObjectRef, haystack: PyObjectRef) -> PyResult {
match self._membership(vm, needle, &haystack) {
Ok(found) => Ok(vm.ctx.new_bool(!objbool::get_value(&found))),
- Err(_) => Err(vm.new_type_error(format!(
- "{} has no __contains__ method",
- objtype::get_type_name(&haystack.class())
- ))),
+ Err(_) => {
+ Err(vm.new_type_error(format!("{} has no __contains__ method", haystack.class())))
+ }
}
}
diff --git a/vm/src/obj/objfloat.rs b/vm/src/obj/objfloat.rs
index 5e68f5960..e261a689e 100644
--- a/vm/src/obj/objfloat.rs
+++ b/vm/src/obj/objfloat.rs
@@ -190,8 +190,7 @@ impl PyFloatRef {
}
}
} else {
- let type_name = objtype::get_type_name(&arg.class());
- return Err(vm.new_type_error(format!("can't convert {} to float", type_name)));
+ return Err(vm.new_type_error(format!("can't convert {} to float", arg.class())));
};
PyFloat { value }.into_ref_with_type(vm, cls)
}
diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs
index f31997ead..e2203469a 100644
--- a/vm/src/obj/objint.rs
+++ b/vm/src/obj/objint.rs
@@ -211,11 +211,7 @@ impl PyIntRef {
fn lshift(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if !objtype::isinstance(&other, &vm.ctx.int_type()) {
- return Err(vm.new_type_error(format!(
- "unsupported operand type(s) for << '{}' and '{}'",
- objtype::get_type_name(&self.as_object().class()),
- objtype::get_type_name(&other.class())
- )));
+ return Ok(vm.ctx.not_implemented());
}
if let Some(n_bits) = get_value(&other).to_usize() {
@@ -234,11 +230,7 @@ impl PyIntRef {
fn rshift(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if !objtype::isinstance(&other, &vm.ctx.int_type()) {
- return Err(vm.new_type_error(format!(
- "unsupported operand type(s) for >> '{}' and '{}'",
- objtype::get_type_name(&self.as_object().class()),
- objtype::get_type_name(&other.class())
- )));
+ return Ok(vm.ctx.not_implemented());
}
if let Some(n_bits) = get_value(&other).to_usize() {
@@ -420,10 +412,9 @@ pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, base: u32) -> PyResult PyResult {
fn object_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(obj, Some(vm.ctx.object()))]);
- let type_name = objtype::get_type_name(&obj.class());
let address = obj.get_id();
- Ok(vm.new_str(format!("<{} object at 0x{:x}>", type_name, address)))
+ Ok(vm.new_str(format!("<{} object at 0x{:x}>", obj.class(), address)))
}
pub fn object_dir(obj: PyObjectRef, vm: &VirtualMachine) -> PyList {
diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs
index fad365e24..0061b41e9 100644
--- a/vm/src/obj/objsuper.rs
+++ b/vm/src/obj/objsuper.rs
@@ -112,10 +112,9 @@ fn super_new(
// Check type argument:
if !objtype::isinstance(py_type.as_object(), &vm.get_type()) {
- let type_name = objtype::get_type_name(&py_type.as_object().class());
return Err(vm.new_type_error(format!(
"super() argument 1 must be type, not {}",
- type_name
+ py_type.class()
)));
}
diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs
index 857ec402f..14958300b 100644
--- a/vm/src/obj/objtype.rs
+++ b/vm/src/obj/objtype.rs
@@ -223,10 +223,6 @@ pub fn issubclass(subclass: &PyClassRef, cls: &PyClassRef) -> bool {
subclass.is(cls) || mro.iter().any(|c| c.is(cls.as_object()))
}
-pub fn get_type_name(typ: &PyClassRef) -> String {
- typ.name.clone()
-}
-
pub fn type_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
debug!("type.__new__ {:?}", args);
if args.args.len() == 2 {
diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs
index 739012c5e..f15c5e09b 100644
--- a/vm/src/pyobject.rs
+++ b/vm/src/pyobject.rs
@@ -88,7 +88,7 @@ impl fmt::Display for PyObject {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::TypeProtocol;
if let Some(PyClass { ref name, .. }) = self.payload::() {
- let type_name = objtype::get_type_name(&self.class());
+ let type_name = self.class().name.clone();
// We don't have access to a vm, so just assume that if its parent's name
// is type, it's a type
if type_name == "type" {
@@ -101,7 +101,7 @@ impl fmt::Display for PyObject {
if let Some(PyModule { ref name, .. }) = self.payload::() {
return write!(f, "module '{}'", name);
}
- write!(f, "'{}' object", objtype::get_type_name(&self.class()))
+ write!(f, "'{}' object", self.class())
}
}
@@ -956,7 +956,7 @@ pub trait BufferProtocol {
impl BufferProtocol for PyObjectRef {
fn readonly(&self) -> bool {
- match objtype::get_type_name(&self.class()).as_ref() {
+ match self.class().name.as_str() {
"bytes" => false,
"bytearray" | "memoryview" => true,
_ => panic!("Bytes-Like type expected not {:?}", self),
diff --git a/vm/src/vm.rs b/vm/src/vm.rs
index 92c264bcd..df092bdc8 100644
--- a/vm/src/vm.rs
+++ b/vm/src/vm.rs
@@ -174,11 +174,11 @@ impl VirtualMachine {
b: PyObjectRef,
op: &str,
) -> PyObjectRef {
- let a_type_name = objtype::get_type_name(&a.class());
- let b_type_name = objtype::get_type_name(&b.class());
self.new_type_error(format!(
"Unsupported operand types for '{}': '{}' and '{}'",
- op, a_type_name, b_type_name
+ op,
+ a.class(),
+ b.class()
))
}
From 8bdc766bedf04063a5a0027f73db6d469202570a Mon Sep 17 00:00:00 2001
From: Joey Hain
Date: Mon, 25 Mar 2019 19:32:58 -0700
Subject: [PATCH 033/658] Use name field directly
---
vm/src/builtins.rs | 6 ++++--
vm/src/exceptions.rs | 2 +-
vm/src/frame.rs | 14 ++++++++------
vm/src/obj/objfloat.rs | 2 +-
vm/src/obj/objint.rs | 2 +-
vm/src/obj/objobject.rs | 6 +++---
vm/src/obj/objsuper.rs | 2 +-
vm/src/pyobject.rs | 2 +-
vm/src/vm.rs | 4 ++--
9 files changed, 22 insertions(+), 18 deletions(-)
diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs
index 27ce8aadd..8a4a6adc3 100644
--- a/vm/src/builtins.rs
+++ b/vm/src/builtins.rs
@@ -368,7 +368,7 @@ fn builtin_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
Err(..) => Err(vm.new_type_error(format!(
"object of type '{}' has no method {:?}",
- obj.class(),
+ obj.class().name,
len_method_name
))),
}
@@ -605,7 +605,9 @@ fn builtin_reversed(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
match vm.get_method(obj.clone(), "__reversed__") {
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
// TODO: fallback to using __len__ and __getitem__, if object supports sequence protocol
- Err(..) => Err(vm.new_type_error(format!("'{}' object is not reversible", obj.class()))),
+ Err(..) => {
+ Err(vm.new_type_error(format!("'{}' object is not reversible", obj.class().name)))
+ }
}
}
// builtin_reversed
diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs
index f850d7697..fb757cd0f 100644
--- a/vm/src/exceptions.rs
+++ b/vm/src/exceptions.rs
@@ -76,7 +76,7 @@ fn exception_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
} else {
panic!("Error message must be set");
};
- let s = format!("{}: {}", exc.class(), msg);
+ let s = format!("{}: {}", exc.class().name, msg);
Ok(vm.new_str(s))
}
diff --git a/vm/src/frame.rs b/vm/src/frame.rs
index 6f8815cbe..6fd5cfea8 100644
--- a/vm/src/frame.rs
+++ b/vm/src/frame.rs
@@ -1091,18 +1091,20 @@ impl Frame {
fn _in(&self, vm: &VirtualMachine, needle: PyObjectRef, haystack: PyObjectRef) -> PyResult {
match self._membership(vm, needle, &haystack) {
Ok(found) => Ok(found),
- Err(_) => {
- Err(vm.new_type_error(format!("{} has no __contains__ method", haystack.class())))
- }
+ Err(_) => Err(vm.new_type_error(format!(
+ "{} has no __contains__ method",
+ haystack.class().name
+ ))),
}
}
fn _not_in(&self, vm: &VirtualMachine, needle: PyObjectRef, haystack: PyObjectRef) -> PyResult {
match self._membership(vm, needle, &haystack) {
Ok(found) => Ok(vm.ctx.new_bool(!objbool::get_value(&found))),
- Err(_) => {
- Err(vm.new_type_error(format!("{} has no __contains__ method", haystack.class())))
- }
+ Err(_) => Err(vm.new_type_error(format!(
+ "{} has no __contains__ method",
+ haystack.class().name
+ ))),
}
}
diff --git a/vm/src/obj/objfloat.rs b/vm/src/obj/objfloat.rs
index e261a689e..ca6bad9d2 100644
--- a/vm/src/obj/objfloat.rs
+++ b/vm/src/obj/objfloat.rs
@@ -190,7 +190,7 @@ impl PyFloatRef {
}
}
} else {
- return Err(vm.new_type_error(format!("can't convert {} to float", arg.class())));
+ return Err(vm.new_type_error(format!("can't convert {} to float", arg.class().name)));
};
PyFloat { value }.into_ref_with_type(vm, cls)
}
diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs
index e2203469a..c7f0ff5af 100644
--- a/vm/src/obj/objint.rs
+++ b/vm/src/obj/objint.rs
@@ -414,7 +414,7 @@ pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, base: u32) -> PyResult PyResult {
fn object_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(obj, Some(vm.ctx.object()))]);
let address = obj.get_id();
- Ok(vm.new_str(format!("<{} object at 0x{:x}>", obj.class(), address)))
+ Ok(vm.new_str(format!("<{} object at 0x{:x}>", obj.class().name, address)))
}
pub fn object_dir(obj: PyObjectRef, vm: &VirtualMachine) -> PyList {
diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs
index 0061b41e9..24424d265 100644
--- a/vm/src/obj/objsuper.rs
+++ b/vm/src/obj/objsuper.rs
@@ -114,7 +114,7 @@ fn super_new(
if !objtype::isinstance(py_type.as_object(), &vm.get_type()) {
return Err(vm.new_type_error(format!(
"super() argument 1 must be type, not {}",
- py_type.class()
+ py_type.class().name
)));
}
diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs
index f15c5e09b..afee7060e 100644
--- a/vm/src/pyobject.rs
+++ b/vm/src/pyobject.rs
@@ -101,7 +101,7 @@ impl fmt::Display for PyObject {
if let Some(PyModule { ref name, .. }) = self.payload::() {
return write!(f, "module '{}'", name);
}
- write!(f, "'{}' object", self.class())
+ write!(f, "'{}' object", self.class().name)
}
}
diff --git a/vm/src/vm.rs b/vm/src/vm.rs
index df092bdc8..41321c266 100644
--- a/vm/src/vm.rs
+++ b/vm/src/vm.rs
@@ -177,8 +177,8 @@ impl VirtualMachine {
self.new_type_error(format!(
"Unsupported operand types for '{}': '{}' and '{}'",
op,
- a.class(),
- b.class()
+ a.class().name,
+ b.class().name
))
}
From 625d2357bd493175a7379eaf876fc33711fdb1c1 Mon Sep 17 00:00:00 2001
From: Joey Hain
Date: Mon, 25 Mar 2019 19:34:24 -0700
Subject: [PATCH 034/658] Fix wasm
---
wasm/lib/src/wasm_builtins.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/wasm/lib/src/wasm_builtins.rs b/wasm/lib/src/wasm_builtins.rs
index d5bc830df..ada0c83f5 100644
--- a/wasm/lib/src/wasm_builtins.rs
+++ b/wasm/lib/src/wasm_builtins.rs
@@ -25,7 +25,7 @@ pub fn format_print_args(vm: &VirtualMachine, args: PyFuncArgs) -> Result Result
Date: Tue, 26 Mar 2019 15:16:30 +0000
Subject: [PATCH 035/658] Change types inside Scope to PyDictRef.
---
vm/src/builtins.rs | 28 +++++++++--------------
vm/src/frame.rs | 29 +++++++++++------------
vm/src/import.rs | 2 +-
vm/src/obj/objframe.rs | 52 ++++++++++++++++++------------------------
vm/src/pyobject.rs | 10 +++++---
vm/src/vm.rs | 9 ++++----
6 files changed, 59 insertions(+), 71 deletions(-)
diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs
index 8a4a6adc3..1de24b86a 100644
--- a/vm/src/builtins.rs
+++ b/vm/src/builtins.rs
@@ -11,6 +11,7 @@ use num_traits::{Signed, ToPrimitive};
use crate::compile;
use crate::import::import_module;
use crate::obj::objbool;
+use crate::obj::objdict::PyDictRef;
use crate::obj::objint;
use crate::obj::objiter;
use crate::obj::objstr::{self, PyStringRef};
@@ -27,14 +28,6 @@ use crate::obj::objcode::PyCodeRef;
#[cfg(not(target_arch = "wasm32"))]
use crate::stdlib::io::io_open;
-fn get_locals(vm: &VirtualMachine) -> PyObjectRef {
- vm.get_locals()
-}
-
-fn dir_locals(vm: &VirtualMachine) -> PyObjectRef {
- get_locals(vm)
-}
-
fn builtin_abs(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(x, None)]);
match vm.get_method(x.clone(), "__abs__") {
@@ -146,7 +139,7 @@ fn builtin_delattr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
fn builtin_dir(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
if args.args.is_empty() {
- Ok(dir_locals(vm))
+ Ok(vm.get_locals().into_object())
} else {
let obj = args.args.into_iter().next().unwrap();
let seq = vm.call_method(&obj, "__dir__", vec![])?;
@@ -254,11 +247,11 @@ fn make_scope(
let current_scope = vm.current_scope();
let globals = match globals {
- Some(dict) => dict.clone(),
+ Some(dict) => dict.clone().downcast().unwrap(),
None => current_scope.globals.clone(),
};
let locals = match locals {
- Some(dict) => Some(dict.clone()),
+ Some(dict) => dict.clone().downcast().ok(),
None => current_scope.get_only_locals(),
};
@@ -300,7 +293,7 @@ fn builtin_getattr(
}
}
-fn builtin_globals(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
+fn builtin_globals(vm: &VirtualMachine) -> PyResult {
Ok(vm.current_scope().globals.clone())
}
@@ -374,9 +367,8 @@ fn builtin_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}
-fn builtin_locals(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(vm, args);
- Ok(vm.get_locals())
+fn builtin_locals(vm: &VirtualMachine) -> PyDictRef {
+ vm.get_locals()
}
fn builtin_max(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -814,13 +806,15 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
let prepare = vm.get_attribute(metaclass.clone().into_object(), "__prepare__")?;
let namespace = vm.invoke(prepare, vec![name_arg.clone(), bases.clone()])?;
+ let namespace: PyDictRef = TryFromObject::try_from_object(vm, namespace)?;
+
let cells = vm.ctx.new_dict();
- vm.invoke_with_locals(function, cells.clone().into_object(), namespace.clone())?;
+ vm.invoke_with_locals(function, cells.clone(), namespace.clone())?;
let class = vm.call_method(
metaclass.as_object(),
"__call__",
- vec![name_arg, bases, namespace],
+ vec![name_arg, bases, namespace.into_object()],
)?;
cells.set_item(&vm.ctx, "__class__", class.clone());
Ok(class)
diff --git a/vm/src/frame.rs b/vm/src/frame.rs
index 6fd5cfea8..88a619eb3 100644
--- a/vm/src/frame.rs
+++ b/vm/src/frame.rs
@@ -12,8 +12,7 @@ use crate::function::PyFuncArgs;
use crate::obj::objbool;
use crate::obj::objbuiltinfunc::PyBuiltinFunction;
use crate::obj::objcode::PyCodeRef;
-use crate::obj::objdict;
-use crate::obj::objdict::PyDict;
+use crate::obj::objdict::{self, PyDictRef};
use crate::obj::objint::PyInt;
use crate::obj::objiter;
use crate::obj::objlist;
@@ -80,8 +79,8 @@ impl<'a, T> Iterator for Iter<'a, T> {
#[derive(Clone)]
pub struct Scope {
- locals: RcList,
- pub globals: PyObjectRef,
+ locals: RcList,
+ pub globals: PyDictRef,
}
impl fmt::Debug for Scope {
@@ -92,7 +91,7 @@ impl fmt::Debug for Scope {
}
impl Scope {
- pub fn new(locals: Option, globals: PyObjectRef) -> Scope {
+ pub fn new(locals: Option, globals: PyDictRef) -> Scope {
let locals = match locals {
Some(dict) => RcList::new().insert(dict),
None => RcList::new(),
@@ -100,18 +99,18 @@ impl Scope {
Scope { locals, globals }
}
- pub fn get_locals(&self) -> PyObjectRef {
+ pub fn get_locals(&self) -> PyDictRef {
match self.locals.iter().next() {
Some(dict) => dict.clone(),
None => self.globals.clone(),
}
}
- pub fn get_only_locals(&self) -> Option {
+ pub fn get_only_locals(&self) -> Option {
self.locals.iter().next().cloned()
}
- pub fn child_scope_with_locals(&self, locals: PyObjectRef) -> Scope {
+ pub fn child_scope_with_locals(&self, locals: PyDictRef) -> Scope {
Scope {
locals: self.locals.clone().insert(locals),
globals: self.globals.clone(),
@@ -119,7 +118,7 @@ impl Scope {
}
pub fn child_scope(&self, ctx: &PyContext) -> Scope {
- self.child_scope_with_locals(ctx.new_dict().into_object())
+ self.child_scope_with_locals(ctx.new_dict())
}
}
@@ -1232,13 +1231,11 @@ impl fmt::Debug for Frame {
.iter()
.map(|elem| format!("\n > {:?}", elem))
.collect::();
- let local_str = match self.scope.get_locals().payload::() {
- Some(dict) => objdict::get_key_value_pairs_from_content(&dict.entries.borrow())
- .iter()
- .map(|elem| format!("\n {:?} = {:?}", elem.0, elem.1))
- .collect::(),
- None => panic!("locals unexpectedly not wrapping a dict!",),
- };
+ let dict = self.scope.get_locals();
+ let local_str = objdict::get_key_value_pairs_from_content(&dict.entries.borrow())
+ .iter()
+ .map(|elem| format!("\n {:?} = {:?}", elem.0, elem.1))
+ .collect::();
write!(
f,
"Frame Object {{ \n Stack:{}\n Blocks:{}\n Locals:{}\n}}",
diff --git a/vm/src/import.rs b/vm/src/import.rs
index 987555915..936b89680 100644
--- a/vm/src/import.rs
+++ b/vm/src/import.rs
@@ -40,7 +40,7 @@ fn import_uncached_module(vm: &VirtualMachine, current_path: PathBuf, module: &s
let attrs = vm.ctx.new_dict();
attrs.set_item(&vm.ctx, "__name__", vm.new_str(module.to_string()));
- vm.run_code_obj(code_obj, Scope::new(None, attrs.clone().into_object()))?;
+ vm.run_code_obj(code_obj, Scope::new(None, attrs.clone()))?;
Ok(vm.ctx.new_module(module, attrs))
}
diff --git a/vm/src/obj/objframe.rs b/vm/src/obj/objframe.rs
index 8657dc280..b4ed15f74 100644
--- a/vm/src/obj/objframe.rs
+++ b/vm/src/obj/objframe.rs
@@ -2,43 +2,35 @@
*/
-use crate::frame::Frame;
-use crate::function::PyFuncArgs;
-use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
+use super::objcode::PyCodeRef;
+use super::objdict::PyDictRef;
+use crate::frame::FrameRef;
+use crate::pyobject::{PyContext, PyResult};
use crate::vm::VirtualMachine;
pub fn init(context: &PyContext) {
- let frame_type = &context.frame_type;
- extend_class!(context, frame_type, {
- "__new__" => context.new_rustfunc(frame_new),
- "__repr__" => context.new_rustfunc(frame_repr),
- "f_locals" => context.new_property(frame_flocals),
- "f_code" => context.new_property(frame_fcode)
+ extend_class!(context, &context.frame_type, {
+ "__new__" => context.new_rustfunc(FrameRef::new),
+ "__repr__" => context.new_rustfunc(FrameRef::repr),
+ "f_locals" => context.new_property(FrameRef::flocals),
+ "f_code" => context.new_property(FrameRef::fcode),
});
}
-fn frame_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(vm, args, required = [(_cls, None)]);
- Err(vm.new_type_error("Cannot directly create frame object".to_string()))
-}
+impl FrameRef {
+ fn new(_class: FrameRef, vm: &VirtualMachine) -> PyResult {
+ Err(vm.new_type_error("Cannot directly create frame object".to_string()))
+ }
-fn frame_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(vm, args, required = [(_frame, Some(vm.ctx.frame_type()))]);
- let repr = "".to_string();
- Ok(vm.new_str(repr))
-}
+ fn repr(self, _vm: &VirtualMachine) -> String {
+ "".to_string()
+ }
-fn frame_flocals(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(vm, args, required = [(frame, Some(vm.ctx.frame_type()))]);
- let frame = get_value(frame);
- Ok(frame.scope.get_locals().clone())
-}
+ fn flocals(self, _vm: &VirtualMachine) -> PyDictRef {
+ self.scope.get_locals()
+ }
-fn frame_fcode(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
- arg_check!(vm, args, required = [(frame, Some(vm.ctx.frame_type()))]);
- Ok(vm.ctx.new_code_object(get_value(frame).code.clone()))
-}
-
-pub fn get_value(obj: &PyObjectRef) -> &Frame {
- &obj.payload::().unwrap()
+ fn fcode(self, vm: &VirtualMachine) -> PyCodeRef {
+ vm.ctx.new_code_object(self.code.clone())
+ }
}
diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs
index afee7060e..aa3348be5 100644
--- a/vm/src/pyobject.rs
+++ b/vm/src/pyobject.rs
@@ -582,7 +582,7 @@ impl PyContext {
}
pub fn new_scope(&self) -> Scope {
- Scope::new(None, self.new_dict().into_object())
+ Scope::new(None, self.new_dict())
}
pub fn new_module(&self, name: &str, dict: PyDictRef) -> PyObjectRef {
@@ -613,8 +613,10 @@ impl PyContext {
PropertyBuilder::new(self).add_getter(f).create()
}
- pub fn new_code_object(&self, code: bytecode::CodeObject) -> PyObjectRef {
+ pub fn new_code_object(&self, code: bytecode::CodeObject) -> PyCodeRef {
PyObject::new(objcode::PyCode::new(code), self.code_type(), None)
+ .downcast()
+ .unwrap()
}
pub fn new_function(
@@ -683,7 +685,9 @@ impl PyContext {
bytecode::Constant::String { ref value } => self.new_str(value.clone()),
bytecode::Constant::Bytes { ref value } => self.new_bytes(value.clone()),
bytecode::Constant::Boolean { ref value } => self.new_bool(value.clone()),
- bytecode::Constant::Code { ref code } => self.new_code_object(*code.clone()),
+ bytecode::Constant::Code { ref code } => {
+ self.new_code_object(*code.clone()).into_object()
+ }
bytecode::Constant::Tuple { ref elements } => {
let elements = elements
.iter()
diff --git a/vm/src/vm.rs b/vm/src/vm.rs
index 41321c266..321d659b8 100644
--- a/vm/src/vm.rs
+++ b/vm/src/vm.rs
@@ -19,6 +19,7 @@ use crate::function::PyFuncArgs;
use crate::obj::objbool;
use crate::obj::objbuiltinfunc::PyBuiltinFunction;
use crate::obj::objcode::PyCodeRef;
+use crate::obj::objdict::PyDictRef;
use crate::obj::objfunction::{PyFunction, PyMethod};
use crate::obj::objgenerator::PyGeneratorRef;
use crate::obj::objiter;
@@ -231,7 +232,7 @@ impl VirtualMachine {
self.ctx.object()
}
- pub fn get_locals(&self) -> PyObjectRef {
+ pub fn get_locals(&self) -> PyDictRef {
self.current_scope().get_locals().clone()
}
@@ -371,8 +372,8 @@ impl VirtualMachine {
pub fn invoke_with_locals(
&self,
function: PyObjectRef,
- cells: PyObjectRef,
- locals: PyObjectRef,
+ cells: PyDictRef,
+ locals: PyDictRef,
) -> PyResult {
if let Some(PyFunction {
code,
@@ -395,7 +396,7 @@ impl VirtualMachine {
fn fill_locals_from_args(
&self,
code_object: &bytecode::CodeObject,
- locals: &PyObjectRef,
+ locals: &PyDictRef,
args: PyFuncArgs,
defaults: &PyObjectRef,
) -> PyResult<()> {
From c5203a4934621292fb87d7e23d91b4068fd9ae51 Mon Sep 17 00:00:00 2001
From: Adrian Wielgosik
Date: Tue, 26 Mar 2019 19:00:06 +0100
Subject: [PATCH 036/658] Remove .gcno files before a coverage run
---
tests/.travis-runner.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/.travis-runner.sh b/tests/.travis-runner.sh
index 36b9f43ac..f55526589 100755
--- a/tests/.travis-runner.sh
+++ b/tests/.travis-runner.sh
@@ -13,6 +13,7 @@ pip install pipenv
if [ $CODE_COVERAGE = "true" ]
then
find . -name '*.gcda' -delete
+ find . -name '*.gcno' -delete
export CARGO_INCREMENTAL=0
export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads"
From 4cb7f026dee431e611863d7378815a98401c5b48 Mon Sep 17 00:00:00 2001
From: Adam Kelly
Date: Tue, 26 Mar 2019 15:38:19 +0000
Subject: [PATCH 037/658] Remove unnecessary cast to pyobject in kwarg
construction.
---
vm/src/vm.rs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/vm/src/vm.rs b/vm/src/vm.rs
index 321d659b8..4148184f4 100644
--- a/vm/src/vm.rs
+++ b/vm/src/vm.rs
@@ -451,11 +451,11 @@ impl VirtualMachine {
// Do we support `**kwargs` ?
let kwargs = match code_object.varkeywords {
bytecode::Varargs::Named(ref kwargs_name) => {
- let d = self.ctx.new_dict().into_object();
- locals.set_item(&self.ctx, kwargs_name, d.clone());
+ let d = self.ctx.new_dict();
+ locals.set_item(&self.ctx, kwargs_name, d.as_object().clone());
Some(d)
}
- bytecode::Varargs::Unnamed => Some(self.ctx.new_dict().into_object()),
+ bytecode::Varargs::Unnamed => Some(self.ctx.new_dict()),
bytecode::Varargs::None => None,
};
From c64417654700084d508458ecb4cb7d9fe4d1dbfe Mon Sep 17 00:00:00 2001
From: Adam Kelly
Date: Tue, 26 Mar 2019 15:38:40 +0000
Subject: [PATCH 038/658] Modules have attributes, not items.
---
vm/src/stdlib/json.rs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/vm/src/stdlib/json.rs b/vm/src/stdlib/json.rs
index b881b7a72..fbe7ea6b1 100644
--- a/vm/src/stdlib/json.rs
+++ b/vm/src/stdlib/json.rs
@@ -199,8 +199,7 @@ pub fn de_pyobject(vm: &VirtualMachine, s: &str) -> PyResult {
de.deserialize(&mut serde_json::Deserializer::from_str(s))
.map_err(|err| {
let json_decode_error = vm
- .sys_module
- .get_item("modules")
+ .get_attribute(vm.sys_module.clone(), "modules")
.unwrap()
.get_item("json")
.unwrap()
From 3ca387b509dca33d09dba944d3573b8bd0cc5f21 Mon Sep 17 00:00:00 2001
From: ben
Date: Thu, 28 Mar 2019 05:55:15 +1300
Subject: [PATCH 039/658] Enhance FromArgs derive proc macro to allow
positional, and positional or keyword arguments.
---
derive/src/lib.rs | 55 ++++++++++++++++++++++------
tests/snippets/ints.py | 18 +++++++++-
vm/src/builtins.rs | 23 ++++++++----
vm/src/function.rs | 82 +++++++++++++++++++++++++++++++++++++++---
vm/src/obj/objint.rs | 50 ++++++++++++++++----------
5 files changed, 187 insertions(+), 41 deletions(-)
diff --git a/derive/src/lib.rs b/derive/src/lib.rs
index ad743e72f..558bf3dda 100644
--- a/derive/src/lib.rs
+++ b/derive/src/lib.rs
@@ -3,9 +3,9 @@ extern crate proc_macro;
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
-use syn::{Data, DeriveInput, Fields};
+use syn::{Data, DeriveInput, Field, Fields};
-#[proc_macro_derive(FromArgs)]
+#[proc_macro_derive(FromArgs, attributes(positional, keyword))]
pub fn derive_from_args(input: TokenStream) -> TokenStream {
let ast: DeriveInput = syn::parse(input).unwrap();
@@ -13,21 +13,54 @@ pub fn derive_from_args(input: TokenStream) -> TokenStream {
gen.to_string().parse().unwrap()
}
+enum ArgType {
+ Positional,
+ PositionalKeyword,
+ Keyword,
+}
+
+fn generate_field(field: &Field) -> TokenStream2 {
+ let arg_type = if let Some(attr) = field.attrs.first() {
+ if attr.path.is_ident("positional") {
+ ArgType::Positional
+ } else if attr.path.is_ident("keyword") {
+ ArgType::Keyword
+ } else {
+ panic!("Unrecognised attribute")
+ }
+ } else {
+ ArgType::PositionalKeyword
+ };
+
+ let name = &field.ident;
+ match arg_type {
+ ArgType::Positional => {
+ quote! {
+ #name: args.take_positional(vm)?,
+ }
+ }
+ ArgType::PositionalKeyword => {
+ quote! {
+ #name: args.take_positional_keyword(vm, stringify!(#name))?,
+ }
+ }
+ ArgType::Keyword => {
+ quote! {
+ #name: args.take_keyword(vm, stringify!(#name))?,
+ }
+ }
+ }
+}
+
fn impl_from_args(input: &DeriveInput) -> TokenStream2 {
// FIXME: This references types using `crate` instead of `rustpython_vm`
// so that it can be used in the latter. How can we support both?
+ // Can use extern crate self as rustpython_vm; once in stable.
+ // https://github.com/rust-lang/rust/issues/56409
let fields = match input.data {
Data::Struct(ref data) => {
match data.fields {
- Fields::Named(ref fields) => fields.named.iter().map(|field| {
- let name = &field.ident;
- quote! {
- #name: crate::pyobject::TryFromObject::try_from_object(
- vm,
- args.take_keyword(stringify!(#name)).unwrap_or_else(|| vm.ctx.none())
- )?,
- }
- }),
+ Fields::Named(ref fields) => fields.named.iter().map(generate_field),
Fields::Unnamed(_) | Fields::Unit => unimplemented!(), // TODO: better error message
}
}
diff --git a/tests/snippets/ints.py b/tests/snippets/ints.py
index 2d36afcb6..1fbbc2bef 100644
--- a/tests/snippets/ints.py
+++ b/tests/snippets/ints.py
@@ -1,4 +1,4 @@
-from testutils import assert_raises
+from testutils import assert_raises, assertRaises
# int to int comparisons
@@ -58,3 +58,19 @@ assert (2).__mul__(1.0) == NotImplemented
assert (2).__rmul__(1.0) == NotImplemented
assert (2).__truediv__(1.0) == NotImplemented
assert (2).__rtruediv__(1.0) == NotImplemented
+
+
+assert int() == 0
+assert int("101", 2) == 5
+assert int("101", base=2) == 5
+assert int(1) == 1
+
+with assertRaises(TypeError):
+ int(base=2)
+
+with assertRaises(TypeError):
+ int(1, base=2)
+
+with assertRaises(TypeError):
+ # check that first parameter is truly positional only
+ int(val_options=1)
diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs
index 4d9fb7989..cf0c0a3f6 100644
--- a/vm/src/builtins.rs
+++ b/vm/src/builtins.rs
@@ -559,11 +559,22 @@ fn builtin_pow(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}
+// Idea: Should we have a 'default' attribute, so we don't have to use OptionalArg's in this case
+//#[derive(Debug, FromArgs)]
+//pub struct PrintOptions {
+// #[keyword] #[default(None)] sep: Option,
+// #[keyword] #[default(None)] end: Option,
+// #[keyword] #[default(flush)] flush: bool,
+//}
+
#[derive(Debug, FromArgs)]
pub struct PrintOptions {
- sep: Option,
- end: Option,
- flush: bool,
+ #[keyword]
+ sep: OptionalArg]