Skip to content

Commit b621a13

Browse files
committed
Merge branch 'master' into coolreader18/update-deps
2 parents e819ca6 + e048037 commit b621a13

28 files changed

+276
-394
lines changed

Cargo.lock

Lines changed: 71 additions & 103 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

parser/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ build = "build.rs"
66
edition = "2018"
77

88
[build-dependencies]
9-
lalrpop="0.15.1"
9+
lalrpop="0.16.3"
1010

1111
[dependencies]
12-
lalrpop-util="0.15.1"
12+
lalrpop-util="0.16.3"
1313
log="0.4.1"
1414
regex="0.2.2"
1515
num-bigint = "0.2"

parser/build.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use lalrpop;
22

33
fn main() {
4-
lalrpop::process_root().unwrap();
4+
lalrpop::Configuration::new()
5+
.generate_in_source_tree()
6+
.process()
7+
.unwrap();
58
}

parser/src/token.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use num_bigint::BigInt;
44

55
/// Python source code can be tokenized in a sequence of these tokens.
6-
#[derive(Debug, PartialEq)]
6+
#[derive(Clone, Debug, PartialEq)]
77
pub enum Tok {
88
Name { name: String },
99
Int { value: BigInt },

tests/.travis-runner.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pip install pipenv
1313
if [ $CODE_COVERAGE = "true" ]
1414
then
1515
find . -name '*.gcda' -delete
16+
find . -name '*.gcno' -delete
1617

1718
export CARGO_INCREMENTAL=0
1819
export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads"

vm/src/builtins.rs

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use num_traits::{Signed, ToPrimitive};
1111
use crate::compile;
1212
use crate::import::import_module;
1313
use crate::obj::objbool;
14+
use crate::obj::objdict::PyDictRef;
1415
use crate::obj::objint;
1516
use crate::obj::objiter;
1617
use crate::obj::objstr::{self, PyStringRef};
@@ -27,14 +28,6 @@ use crate::obj::objcode::PyCodeRef;
2728
#[cfg(not(target_arch = "wasm32"))]
2829
use crate::stdlib::io::io_open;
2930

30-
fn get_locals(vm: &VirtualMachine) -> PyObjectRef {
31-
vm.get_locals()
32-
}
33-
34-
fn dir_locals(vm: &VirtualMachine) -> PyObjectRef {
35-
get_locals(vm)
36-
}
37-
3831
fn builtin_abs(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
3932
arg_check!(vm, args, required = [(x, None)]);
4033
match vm.get_method(x.clone(), "__abs__") {
@@ -88,7 +81,7 @@ fn builtin_bin(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
8881

8982
fn builtin_callable(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
9083
arg_check!(vm, args, required = [(obj, None)]);
91-
let is_callable = objtype::class_has_attr(&obj.type_pyref(), "__call__");
84+
let is_callable = objtype::class_has_attr(&obj.class(), "__call__");
9285
Ok(vm.new_bool(is_callable))
9386
}
9487

@@ -146,7 +139,7 @@ fn builtin_delattr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
146139

147140
fn builtin_dir(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
148141
if args.args.is_empty() {
149-
Ok(dir_locals(vm))
142+
Ok(vm.get_locals().into_object())
150143
} else {
151144
let obj = args.args.into_iter().next().unwrap();
152145
let seq = vm.call_method(&obj, "__dir__", vec![])?;
@@ -240,7 +233,7 @@ fn make_scope(
240233
} else if vm.isinstance(arg, &dict_type)? {
241234
Some(arg)
242235
} else {
243-
let arg_typ = arg.typ();
236+
let arg_typ = arg.class();
244237
let actual_type = vm.to_pystr(&arg_typ)?;
245238
let expected_type_name = vm.to_pystr(&dict_type)?;
246239
return Err(vm.new_type_error(format!(
@@ -254,11 +247,11 @@ fn make_scope(
254247

255248
let current_scope = vm.current_scope();
256249
let globals = match globals {
257-
Some(dict) => dict.clone(),
250+
Some(dict) => dict.clone().downcast().unwrap(),
258251
None => current_scope.globals.clone(),
259252
};
260253
let locals = match locals {
261-
Some(dict) => Some(dict.clone()),
254+
Some(dict) => dict.clone().downcast().ok(),
262255
None => current_scope.get_only_locals(),
263256
};
264257

@@ -300,7 +293,7 @@ fn builtin_getattr(
300293
}
301294
}
302295

303-
fn builtin_globals(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
296+
fn builtin_globals(vm: &VirtualMachine) -> PyResult<PyDictRef> {
304297
Ok(vm.current_scope().globals.clone())
305298
}
306299

@@ -368,15 +361,14 @@ fn builtin_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
368361
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
369362
Err(..) => Err(vm.new_type_error(format!(
370363
"object of type '{}' has no method {:?}",
371-
objtype::get_type_name(&obj.typ()),
364+
obj.class().name,
372365
len_method_name
373366
))),
374367
}
375368
}
376369

377-
fn builtin_locals(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
378-
arg_check!(vm, args);
379-
Ok(vm.get_locals())
370+
fn builtin_locals(vm: &VirtualMachine) -> PyDictRef {
371+
vm.get_locals()
380372
}
381373

382374
fn builtin_max(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -605,10 +597,9 @@ fn builtin_reversed(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
605597
match vm.get_method(obj.clone(), "__reversed__") {
606598
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
607599
// TODO: fallback to using __len__ and __getitem__, if object supports sequence protocol
608-
Err(..) => Err(vm.new_type_error(format!(
609-
"'{}' object is not reversible",
610-
objtype::get_type_name(&obj.typ()),
611-
))),
600+
Err(..) => {
601+
Err(vm.new_type_error(format!("'{}' object is not reversible", obj.class().name)))
602+
}
612603
}
613604
}
614605
// builtin_reversed
@@ -802,9 +793,9 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
802793
};
803794

804795
for base in bases.clone() {
805-
if objtype::issubclass(&base.type_pyref(), &metaclass) {
806-
metaclass = base.type_pyref();
807-
} else if !objtype::issubclass(&metaclass, &base.type_pyref()) {
796+
if objtype::issubclass(&base.class(), &metaclass) {
797+
metaclass = base.class();
798+
} else if !objtype::issubclass(&metaclass, &base.class()) {
808799
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()));
809800
}
810801
}
@@ -815,13 +806,15 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
815806
let prepare = vm.get_attribute(metaclass.clone().into_object(), "__prepare__")?;
816807
let namespace = vm.invoke(prepare, vec![name_arg.clone(), bases.clone()])?;
817808

809+
let namespace: PyDictRef = TryFromObject::try_from_object(vm, namespace)?;
810+
818811
let cells = vm.ctx.new_dict();
819812

820-
vm.invoke_with_locals(function, cells.clone().into_object(), namespace.clone())?;
813+
vm.invoke_with_locals(function, cells.clone(), namespace.clone())?;
821814
let class = vm.call_method(
822815
metaclass.as_object(),
823816
"__call__",
824-
vec![name_arg, bases, namespace],
817+
vec![name_arg, bases, namespace.into_object()],
825818
)?;
826819
cells.set_item(&vm.ctx, "__class__", class.clone());
827820
Ok(class)

vm/src/exceptions.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ fn exception_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
6868
args,
6969
required = [(exc, Some(vm.ctx.exceptions.exception_type.clone()))]
7070
);
71-
let type_name = objtype::get_type_name(&exc.typ());
7271
let msg = if let Ok(m) = vm.get_attribute(exc.clone(), "msg") {
7372
match vm.to_pystr(&m) {
7473
Ok(msg) => msg,
@@ -77,7 +76,7 @@ fn exception_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
7776
} else {
7877
panic!("Error message must be set");
7978
};
80-
let s = format!("{}: {}", type_name, msg);
79+
let s = format!("{}: {}", exc.class().name, msg);
8180
Ok(vm.new_str(s))
8281
}
8382

vm/src/frame.rs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ use crate::function::PyFuncArgs;
1212
use crate::obj::objbool;
1313
use crate::obj::objbuiltinfunc::PyBuiltinFunction;
1414
use crate::obj::objcode::PyCodeRef;
15-
use crate::obj::objdict;
16-
use crate::obj::objdict::PyDict;
15+
use crate::obj::objdict::{self, PyDictRef};
1716
use crate::obj::objint::PyInt;
1817
use crate::obj::objiter;
1918
use crate::obj::objlist;
@@ -80,8 +79,8 @@ impl<'a, T> Iterator for Iter<'a, T> {
8079

8180
#[derive(Clone)]
8281
pub struct Scope {
83-
locals: RcList<PyObjectRef>,
84-
pub globals: PyObjectRef,
82+
locals: RcList<PyDictRef>,
83+
pub globals: PyDictRef,
8584
}
8685

8786
impl fmt::Debug for Scope {
@@ -92,34 +91,34 @@ impl fmt::Debug for Scope {
9291
}
9392

9493
impl Scope {
95-
pub fn new(locals: Option<PyObjectRef>, globals: PyObjectRef) -> Scope {
94+
pub fn new(locals: Option<PyDictRef>, globals: PyDictRef) -> Scope {
9695
let locals = match locals {
9796
Some(dict) => RcList::new().insert(dict),
9897
None => RcList::new(),
9998
};
10099
Scope { locals, globals }
101100
}
102101

103-
pub fn get_locals(&self) -> PyObjectRef {
102+
pub fn get_locals(&self) -> PyDictRef {
104103
match self.locals.iter().next() {
105104
Some(dict) => dict.clone(),
106105
None => self.globals.clone(),
107106
}
108107
}
109108

110-
pub fn get_only_locals(&self) -> Option<PyObjectRef> {
109+
pub fn get_only_locals(&self) -> Option<PyDictRef> {
111110
self.locals.iter().next().cloned()
112111
}
113112

114-
pub fn child_scope_with_locals(&self, locals: PyObjectRef) -> Scope {
113+
pub fn child_scope_with_locals(&self, locals: PyDictRef) -> Scope {
115114
Scope {
116115
locals: self.locals.clone().insert(locals),
117116
globals: self.globals.clone(),
118117
}
119118
}
120119

121120
pub fn child_scope(&self, ctx: &PyContext) -> Scope {
122-
self.child_scope_with_locals(ctx.new_dict().into_object())
121+
self.child_scope_with_locals(ctx.new_dict())
123122
}
124123
}
125124

@@ -949,7 +948,7 @@ impl Frame {
949948
// let args = PyFuncArgs::default();
950949
// TODO: what happens when we got an error during handling exception?
951950
let args = if let Some(exc) = exc {
952-
let exc_type = exc.typ();
951+
let exc_type = exc.class().into_object();
953952
let exc_val = exc.clone();
954953
let exc_tb = vm.ctx.none(); // TODO: retrieve traceback?
955954
vec![exc_type, exc_val, exc_tb]
@@ -1093,7 +1092,7 @@ impl Frame {
10931092
Ok(found) => Ok(found),
10941093
Err(_) => Err(vm.new_type_error(format!(
10951094
"{} has no __contains__ method",
1096-
objtype::get_type_name(&haystack.typ())
1095+
haystack.class().name
10971096
))),
10981097
}
10991098
}
@@ -1103,7 +1102,7 @@ impl Frame {
11031102
Ok(found) => Ok(vm.ctx.new_bool(!objbool::get_value(&found))),
11041103
Err(_) => Err(vm.new_type_error(format!(
11051104
"{} has no __contains__ method",
1106-
objtype::get_type_name(&haystack.typ())
1105+
haystack.class().name
11071106
))),
11081107
}
11091108
}
@@ -1232,13 +1231,11 @@ impl fmt::Debug for Frame {
12321231
.iter()
12331232
.map(|elem| format!("\n > {:?}", elem))
12341233
.collect::<String>();
1235-
let local_str = match self.scope.get_locals().payload::<PyDict>() {
1236-
Some(dict) => objdict::get_key_value_pairs_from_content(&dict.entries.borrow())
1237-
.iter()
1238-
.map(|elem| format!("\n {:?} = {:?}", elem.0, elem.1))
1239-
.collect::<String>(),
1240-
None => panic!("locals unexpectedly not wrapping a dict!",),
1241-
};
1234+
let dict = self.scope.get_locals();
1235+
let local_str = objdict::get_key_value_pairs_from_content(&dict.entries.borrow())
1236+
.iter()
1237+
.map(|elem| format!("\n {:?} = {:?}", elem.0, elem.1))
1238+
.collect::<String>();
12421239
write!(
12431240
f,
12441241
"Frame Object {{ \n Stack:{}\n Blocks:{}\n Locals:{}\n}}",

vm/src/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl PyFuncArgs {
9999
Ok(Some(kwarg))
100100
} else {
101101
let expected_ty_name = vm.to_pystr(&ty)?;
102-
let actual_ty_name = vm.to_pystr(&kwarg.typ())?;
102+
let actual_ty_name = vm.to_pystr(&kwarg.class())?;
103103
Err(vm.new_type_error(format!(
104104
"argument of type {} is required for named parameter `{}` (got: {})",
105105
expected_ty_name, key, actual_ty_name

vm/src/import.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ fn import_uncached_module(vm: &VirtualMachine, current_path: PathBuf, module: &s
4040

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

vm/src/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ macro_rules! type_check {
2020
let arg = &$args.args[$arg_count];
2121

2222
if !$crate::obj::objtype::isinstance(arg, &expected_type) {
23-
let arg_typ = arg.typ();
23+
let arg_typ = arg.class();
2424
let expected_type_name = $vm.to_pystr(&expected_type)?;
2525
let actual_type = $vm.to_pystr(&arg_typ)?;
2626
return Err($vm.new_type_error(format!(

vm/src/obj/objfloat.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,7 @@ impl PyFloatRef {
190190
}
191191
}
192192
} else {
193-
let type_name = objtype::get_type_name(&arg.typ());
194-
return Err(vm.new_type_error(format!("can't convert {} to float", type_name)));
193+
return Err(vm.new_type_error(format!("can't convert {} to float", arg.class().name)));
195194
};
196195
PyFloat { value }.into_ref_with_type(vm, cls)
197196
}

0 commit comments

Comments
 (0)