Skip to content

Commit 9de7285

Browse files
Merge remote-tracking branch 'origin/master' into joey/pyobject-function-split
Conflicts: vm/src/frame.rs vm/src/obj/objbytearray.rs vm/src/obj/objbytes.rs vm/src/obj/objcomplex.rs
2 parents 7bfd2e6 + 94e3cb8 commit 9de7285

21 files changed

+341
-192
lines changed

.travis.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,26 @@ matrix:
115115
- TRAVIS_RUST_VERSION=nightly
116116
- REGULAR_TEST=false
117117
- CODE_COVERAGE=true
118+
- name: test WASM
119+
language: python
120+
python: 3.6
121+
cache:
122+
pip: true
123+
# Because we're using the Python Travis environment, we can't use
124+
# the built-in cargo cacher
125+
directories:
126+
- /home/travis/.cargo
127+
- target
128+
addons:
129+
firefox: latest
130+
install:
131+
- nvm install node
132+
- pip install pipenv
133+
script:
134+
- wasm/tests/.travis-runner.sh
135+
env:
136+
- REGULAR_TEST=true
137+
- TRAVIS_RUST_VERSION=stable
118138
allow_failures:
119139
- rust: nightly
120140
env: REGULAR_TEST=true

tests/snippets/builtin_any.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
assert any([1]);
2+
assert not any([]);
3+
assert not any([0,0,0,0]);
4+
assert any([0,0,1,0,0]);
5+
def anything(a):
6+
return a
7+
8+
class Test:
9+
def __iter__(self):
10+
while True:
11+
yield True
12+
13+
assert any(map(anything, Test()))

vm/src/builtins.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,19 @@ fn builtin_all(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
6565

6666
fn builtin_any(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
6767
arg_check!(vm, args, required = [(iterable, None)]);
68-
let items = vm.extract_elements(iterable)?;
69-
for item in items {
68+
let iterator = objiter::get_iter(vm, iterable)?;
69+
70+
loop {
71+
let item = match objiter::get_next_object(vm, &iterator)? {
72+
Some(obj) => obj,
73+
None => break,
74+
};
7075
let result = objbool::boolval(vm, item)?;
7176
if result {
7277
return Ok(vm.new_bool(true));
7378
}
7479
}
80+
7581
Ok(vm.new_bool(false))
7682
}
7783

vm/src/frame.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ use crate::obj::objslice::PySlice;
2121
use crate::obj::objstr;
2222
use crate::obj::objtype;
2323
use crate::pyobject::{
24-
AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyObject, PyObjectRef, PyResult,
25-
PyValue, TryFromObject, TypeProtocol,
24+
AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyObjectRef, PyResult, PyValue,
25+
TryFromObject, TypeProtocol,
2626
};
2727
use crate::vm::VirtualMachine;
2828

@@ -410,8 +410,8 @@ impl Frame {
410410
let stop = out[1].take();
411411
let step = if out.len() == 3 { out[2].take() } else { None };
412412

413-
let obj = PyObject::new(PySlice { start, stop, step }, vm.ctx.slice_type());
414-
self.push_value(obj);
413+
let obj = PySlice { start, stop, step }.into_ref(vm);
414+
self.push_value(obj.into_object());
415415
Ok(None)
416416
}
417417
bytecode::Instruction::ListAppend { i } => {
@@ -692,22 +692,17 @@ impl Frame {
692692
let expr = self.pop_value();
693693
if !expr.is(&vm.get_none()) {
694694
let repr = vm.to_repr(&expr)?;
695-
builtins::builtin_print(
696-
vm,
697-
PyFuncArgs {
698-
args: vec![repr],
699-
kwargs: vec![],
700-
},
701-
)?;
695+
// TODO: implement sys.displayhook
696+
if let Some(print) = vm.ctx.get_attr(&vm.builtins, "print") {
697+
vm.invoke(print, vec![repr])?;
698+
}
702699
}
703700
Ok(None)
704701
}
705702
bytecode::Instruction::LoadBuildClass => {
706-
let rustfunc = PyObject::new(
707-
PyBuiltinFunction::new(Box::new(builtins::builtin_build_class_)),
708-
vm.ctx.type_type(),
709-
);
710-
self.push_value(rustfunc);
703+
let rustfunc =
704+
PyBuiltinFunction::new(Box::new(builtins::builtin_build_class_)).into_ref(vm);
705+
self.push_value(rustfunc.into_object());
711706
Ok(None)
712707
}
713708
bytecode::Instruction::UnpackSequence { size } => {

vm/src/obj/objbytearray.rs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@ use std::ops::{Deref, DerefMut};
66

77
use num_traits::ToPrimitive;
88

9-
use crate::function::PyFuncArgs;
10-
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
9+
use crate::function::{OptionalArg, PyFuncArgs};
10+
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
1111
use crate::vm::VirtualMachine;
1212

1313
use super::objint;
14-
use super::objtype;
14+
use super::objtype::{self, PyClassRef};
1515

1616
#[derive(Debug)]
1717
pub struct PyByteArray {
1818
// TODO: shouldn't be public
1919
pub value: RefCell<Vec<u8>>,
2020
}
21+
type PyByteArrayRef = PyRef<PyByteArray>;
2122

2223
impl PyByteArray {
2324
pub fn new(data: Vec<u8>) -> Self {
@@ -143,20 +144,14 @@ pub fn init(context: &PyContext) {
143144
);
144145
}
145146

146-
fn bytearray_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
147-
arg_check!(
148-
vm,
149-
args,
150-
required = [(cls, None)],
151-
optional = [(val_option, None)]
152-
);
153-
if !objtype::issubclass(cls, &vm.ctx.bytearray_type()) {
154-
return Err(vm.new_type_error(format!("{:?} is not a subtype of bytearray", cls)));
155-
}
156-
147+
fn bytearray_new(
148+
cls: PyClassRef,
149+
val_option: OptionalArg<PyObjectRef>,
150+
vm: &mut VirtualMachine,
151+
) -> PyResult<PyByteArrayRef> {
157152
// Create bytes data:
158-
let value = if let Some(ival) = val_option {
159-
let elements = vm.extract_elements(ival)?;
153+
let value = if let OptionalArg::Present(ival) = val_option {
154+
let elements = vm.extract_elements(&ival)?;
160155
let mut data_bytes = vec![];
161156
for elem in elements.iter() {
162157
let v = objint::to_int(vm, elem, 10)?;
@@ -171,7 +166,7 @@ fn bytearray_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
171166
} else {
172167
vec![]
173168
};
174-
Ok(PyObject::new(PyByteArray::new(value), cls.clone()))
169+
PyByteArray::new(value).into_ref_with_type(vm, cls.clone())
175170
}
176171

177172
fn bytesarray_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {

vm/src/obj/objbytes.rs

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,20 @@ use std::ops::Deref;
44

55
use num_traits::ToPrimitive;
66

7-
use crate::function::PyFuncArgs;
7+
use crate::function::{OptionalArg, PyFuncArgs};
88
use crate::pyobject::{
9-
PyContext, PyIteratorValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
9+
PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
1010
};
1111
use crate::vm::VirtualMachine;
1212

1313
use super::objint;
14-
use super::objtype;
14+
use super::objtype::{self, PyClassRef};
1515

1616
#[derive(Debug)]
1717
pub struct PyBytes {
1818
value: Vec<u8>,
1919
}
20+
type PyBytesRef = PyRef<PyBytes>;
2021

2122
impl PyBytes {
2223
pub fn new(data: Vec<u8>) -> Self {
@@ -72,20 +73,14 @@ pub fn init(context: &PyContext) {
7273
);
7374
}
7475

75-
fn bytes_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
76-
arg_check!(
77-
vm,
78-
args,
79-
required = [(cls, None)],
80-
optional = [(val_option, None)]
81-
);
82-
if !objtype::issubclass(cls, &vm.ctx.bytes_type()) {
83-
return Err(vm.new_type_error(format!("{:?} is not a subtype of bytes", cls)));
84-
}
85-
76+
fn bytes_new(
77+
cls: PyClassRef,
78+
val_option: OptionalArg<PyObjectRef>,
79+
vm: &mut VirtualMachine,
80+
) -> PyResult<PyBytesRef> {
8681
// Create bytes data:
87-
let value = if let Some(ival) = val_option {
88-
let elements = vm.extract_elements(ival)?;
82+
let value = if let OptionalArg::Present(ival) = val_option {
83+
let elements = vm.extract_elements(&ival)?;
8984
let mut data_bytes = vec![];
9085
for elem in elements.iter() {
9186
let v = objint::to_int(vm, elem, 10)?;
@@ -97,7 +92,7 @@ fn bytes_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
9792
vec![]
9893
};
9994

100-
Ok(PyObject::new(PyBytes::new(value), cls.clone()))
95+
PyBytes::new(value).into_ref_with_type(vm, cls)
10196
}
10297

10398
fn bytes_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -202,16 +197,9 @@ fn bytes_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
202197
Ok(vm.new_str(format!("b'{}'", data)))
203198
}
204199

205-
fn bytes_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
206-
arg_check!(vm, args, required = [(obj, Some(vm.ctx.bytes_type()))]);
207-
208-
let iter_obj = PyObject::new(
209-
PyIteratorValue {
210-
position: Cell::new(0),
211-
iterated_obj: obj.clone(),
212-
},
213-
vm.ctx.iter_type(),
214-
);
215-
216-
Ok(iter_obj)
200+
fn bytes_iter(obj: PyBytesRef, _vm: &mut VirtualMachine) -> PyIteratorValue {
201+
PyIteratorValue {
202+
position: Cell::new(0),
203+
iterated_obj: obj.into_object(),
204+
}
217205
}

vm/src/obj/objcomplex.rs

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
use num_complex::Complex64;
22
use num_traits::ToPrimitive;
33

4-
use crate::function::PyFuncArgs;
5-
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
4+
use crate::function::{OptionalArg, PyFuncArgs};
5+
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
66
use crate::vm::VirtualMachine;
77

88
use super::objfloat;
99
use super::objint;
10-
use super::objtype;
10+
use super::objtype::{self, PyClassRef};
1111

1212
#[derive(Debug, Copy, Clone, PartialEq)]
1313
pub struct PyComplex {
1414
value: Complex64,
1515
}
16+
type PyComplexRef = PyRef<PyComplex>;
1617

1718
impl PyValue for PyComplex {
1819
fn class(vm: &mut VirtualMachine) -> PyObjectRef {
@@ -66,31 +67,24 @@ pub fn get_value(obj: &PyObjectRef) -> Complex64 {
6667
obj.payload::<PyComplex>().unwrap().value
6768
}
6869

69-
fn complex_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
70-
arg_check!(
71-
vm,
72-
args,
73-
required = [(cls, None)],
74-
optional = [(real, None), (imag, None)]
75-
);
76-
77-
if !objtype::issubclass(cls, &vm.ctx.complex_type()) {
78-
return Err(vm.new_type_error(format!("{:?} is not a subtype of complex", cls)));
79-
}
80-
70+
fn complex_new(
71+
cls: PyClassRef,
72+
real: OptionalArg<PyObjectRef>,
73+
imag: OptionalArg<PyObjectRef>,
74+
vm: &mut VirtualMachine,
75+
) -> PyResult<PyComplexRef> {
8176
let real = match real {
82-
None => 0.0,
83-
Some(value) => objfloat::make_float(vm, value)?,
77+
OptionalArg::Missing => 0.0,
78+
OptionalArg::Present(ref value) => objfloat::make_float(vm, value)?,
8479
};
8580

8681
let imag = match imag {
87-
None => 0.0,
88-
Some(value) => objfloat::make_float(vm, value)?,
82+
OptionalArg::Missing => 0.0,
83+
OptionalArg::Present(ref value) => objfloat::make_float(vm, value)?,
8984
};
9085

9186
let value = Complex64::new(real, imag);
92-
93-
Ok(PyObject::new(PyComplex { value }, cls.clone()))
87+
PyComplex { value }.into_ref_with_type(vm, cls)
9488
}
9589

9690
fn complex_real(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {

0 commit comments

Comments
 (0)