mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge remote-tracking branch 'origin/master' into joey/range-getitem-either
This commit is contained in:
22
src/main.rs
22
src/main.rs
@@ -65,16 +65,11 @@ fn main() {
|
||||
}
|
||||
|
||||
fn _run_string(vm: &VirtualMachine, source: &str, source_path: String) -> PyResult {
|
||||
let code_obj = compile::compile(
|
||||
source,
|
||||
&compile::Mode::Exec,
|
||||
source_path,
|
||||
vm.ctx.code_type(),
|
||||
)
|
||||
.map_err(|err| {
|
||||
let syntax_error = vm.context().exceptions.syntax_error.clone();
|
||||
vm.new_exception(syntax_error, err.to_string())
|
||||
})?;
|
||||
let code_obj =
|
||||
compile::compile(vm, source, &compile::Mode::Exec, source_path).map_err(|err| {
|
||||
let syntax_error = vm.context().exceptions.syntax_error.clone();
|
||||
vm.new_exception(syntax_error, err.to_string())
|
||||
})?;
|
||||
// trace!("Code object: {:?}", code_obj.borrow());
|
||||
let vars = vm.ctx.new_scope(); // Keep track of local variables
|
||||
vm.run_code_obj(code_obj, vars)
|
||||
@@ -115,12 +110,7 @@ fn run_script(vm: &VirtualMachine, script_file: &str) -> PyResult {
|
||||
}
|
||||
|
||||
fn shell_exec(vm: &VirtualMachine, source: &str, scope: Scope) -> Result<(), CompileError> {
|
||||
match compile::compile(
|
||||
source,
|
||||
&compile::Mode::Single,
|
||||
"<stdin>".to_string(),
|
||||
vm.ctx.code_type(),
|
||||
) {
|
||||
match compile::compile(vm, source, &compile::Mode::Single, "<stdin>".to_string()) {
|
||||
Ok(code) => {
|
||||
if let Err(err) = vm.run_code_obj(code, scope) {
|
||||
print_exception(vm, &err);
|
||||
|
||||
@@ -24,6 +24,7 @@ use crate::pyobject::{
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use crate::obj::objcode::PyCodeRef;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::stdlib::io::io_open;
|
||||
|
||||
@@ -112,22 +113,17 @@ fn builtin_chr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(vm.new_str(txt))
|
||||
}
|
||||
|
||||
fn builtin_compile(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [
|
||||
(source, None),
|
||||
(filename, Some(vm.ctx.str_type())),
|
||||
(mode, Some(vm.ctx.str_type()))
|
||||
]
|
||||
);
|
||||
let source = objstr::get_value(source);
|
||||
fn builtin_compile(
|
||||
source: PyStringRef,
|
||||
filename: PyStringRef,
|
||||
mode: PyStringRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyCodeRef> {
|
||||
// TODO: fix this newline bug:
|
||||
let source = format!("{}\n", source);
|
||||
let source = format!("{}\n", &source.value);
|
||||
|
||||
let mode = {
|
||||
let mode = objstr::get_value(mode);
|
||||
let mode = &mode.value;
|
||||
if mode == "exec" {
|
||||
compile::Mode::Exec
|
||||
} else if mode == "eval" {
|
||||
@@ -141,9 +137,7 @@ fn builtin_compile(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
};
|
||||
|
||||
let filename = objstr::get_value(filename);
|
||||
|
||||
compile::compile(&source, &mode, filename, vm.ctx.code_type()).map_err(|err| {
|
||||
compile::compile(vm, &source, &mode, filename.value.to_string()).map_err(|err| {
|
||||
let syntax_error = vm.context().exceptions.syntax_error.clone();
|
||||
vm.new_exception(syntax_error, err.to_string())
|
||||
})
|
||||
@@ -190,25 +184,23 @@ fn builtin_eval(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let scope = make_scope(vm, globals, locals)?;
|
||||
|
||||
// Determine code object:
|
||||
let code_obj = if objtype::isinstance(source, &vm.ctx.code_type()) {
|
||||
source.clone()
|
||||
let code_obj = if let Ok(code_obj) = PyCodeRef::try_from_object(vm, source.clone()) {
|
||||
code_obj
|
||||
} else if objtype::isinstance(source, &vm.ctx.str_type()) {
|
||||
let mode = compile::Mode::Eval;
|
||||
let source = objstr::get_value(source);
|
||||
// TODO: fix this newline bug:
|
||||
let source = format!("{}\n", source);
|
||||
compile::compile(&source, &mode, "<string>".to_string(), vm.ctx.code_type()).map_err(
|
||||
|err| {
|
||||
let syntax_error = vm.context().exceptions.syntax_error.clone();
|
||||
vm.new_exception(syntax_error, err.to_string())
|
||||
},
|
||||
)?
|
||||
compile::compile(vm, &source, &mode, "<string>".to_string()).map_err(|err| {
|
||||
let syntax_error = vm.context().exceptions.syntax_error.clone();
|
||||
vm.new_exception(syntax_error, err.to_string())
|
||||
})?
|
||||
} else {
|
||||
return Err(vm.new_type_error("code argument must be str or code object".to_string()));
|
||||
};
|
||||
|
||||
// Run the source:
|
||||
vm.run_code_obj(code_obj.clone(), scope)
|
||||
vm.run_code_obj(code_obj, scope)
|
||||
}
|
||||
|
||||
/// Implements `exec`
|
||||
@@ -229,14 +221,12 @@ fn builtin_exec(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let source = objstr::get_value(source);
|
||||
// TODO: fix this newline bug:
|
||||
let source = format!("{}\n", source);
|
||||
compile::compile(&source, &mode, "<string>".to_string(), vm.ctx.code_type()).map_err(
|
||||
|err| {
|
||||
let syntax_error = vm.context().exceptions.syntax_error.clone();
|
||||
vm.new_exception(syntax_error, err.to_string())
|
||||
},
|
||||
)?
|
||||
} else if objtype::isinstance(source, &vm.ctx.code_type()) {
|
||||
source.clone()
|
||||
compile::compile(vm, &source, &mode, "<string>".to_string()).map_err(|err| {
|
||||
let syntax_error = vm.context().exceptions.syntax_error.clone();
|
||||
vm.new_exception(syntax_error, err.to_string())
|
||||
})?
|
||||
} else if let Ok(code_obj) = PyCodeRef::try_from_object(vm, source.clone()) {
|
||||
code_obj
|
||||
} else {
|
||||
return Err(vm.new_type_error("source argument must be str or code object".to_string()));
|
||||
};
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
use crate::bytecode::{self, CallType, CodeObject, Instruction, Varargs};
|
||||
use crate::error::CompileError;
|
||||
use crate::obj::objcode;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{PyObject, PyObjectRef};
|
||||
use crate::obj::objcode::PyCodeRef;
|
||||
use crate::pyobject::PyValue;
|
||||
use crate::VirtualMachine;
|
||||
use num_complex::Complex64;
|
||||
use rustpython_parser::{ast, parser};
|
||||
|
||||
@@ -24,11 +25,11 @@ struct Compiler {
|
||||
|
||||
/// Compile a given sourcecode into a bytecode object.
|
||||
pub fn compile(
|
||||
vm: &VirtualMachine,
|
||||
source: &str,
|
||||
mode: &Mode,
|
||||
source_path: String,
|
||||
code_type: PyClassRef,
|
||||
) -> Result<PyObjectRef, CompileError> {
|
||||
) -> Result<PyCodeRef, CompileError> {
|
||||
let mut compiler = Compiler::new();
|
||||
compiler.source_path = Some(source_path);
|
||||
compiler.push_new_code_object("<module>".to_string());
|
||||
@@ -50,10 +51,7 @@ pub fn compile(
|
||||
|
||||
let code = compiler.pop_code_object();
|
||||
trace!("Compilation completed: {:?}", code);
|
||||
Ok(PyObject::new(
|
||||
objcode::PyCode::new(code),
|
||||
code_type.into_object(),
|
||||
))
|
||||
Ok(objcode::PyCode::new(code).into_ref(vm))
|
||||
}
|
||||
|
||||
pub enum Mode {
|
||||
|
||||
@@ -8,12 +8,7 @@ use crate::pyobject::PyResult;
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub fn eval(vm: &VirtualMachine, source: &str, scope: Scope, source_path: &str) -> PyResult {
|
||||
match compile::compile(
|
||||
source,
|
||||
&compile::Mode::Eval,
|
||||
source_path.to_string(),
|
||||
vm.ctx.code_type(),
|
||||
) {
|
||||
match compile::compile(vm, source, &compile::Mode::Eval, source_path.to_string()) {
|
||||
Ok(bytecode) => {
|
||||
debug!("Code object: {:?}", bytecode);
|
||||
vm.run_code_obj(bytecode, scope)
|
||||
|
||||
@@ -305,6 +305,13 @@ pub enum OptionalArg<T> {
|
||||
}
|
||||
|
||||
impl<T> OptionalArg<T> {
|
||||
pub fn is_present(&self) -> bool {
|
||||
match self {
|
||||
Present(_) => true,
|
||||
Missing => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_option(self) -> Option<T> {
|
||||
match self {
|
||||
Present(value) => Some(value),
|
||||
|
||||
@@ -27,10 +27,10 @@ fn import_uncached_module(vm: &VirtualMachine, current_path: PathBuf, module: &s
|
||||
let source = util::read_file(file_path.as_path())
|
||||
.map_err(|e| vm.new_exception(import_error.clone(), e.description().to_string()))?;
|
||||
let code_obj = compile::compile(
|
||||
vm,
|
||||
&source,
|
||||
&compile::Mode::Exec,
|
||||
file_path.to_str().unwrap().to_string(),
|
||||
vm.ctx.code_type(),
|
||||
)
|
||||
.map_err(|err| {
|
||||
let syntax_error = vm.context().exceptions.syntax_error.clone();
|
||||
|
||||
@@ -7,9 +7,11 @@ use std::fmt;
|
||||
use crate::bytecode;
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{IdProtocol, PyContext, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::pyobject::{IdProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub type PyCodeRef = PyRef<PyCode>;
|
||||
|
||||
pub struct PyCode {
|
||||
code: bytecode::CodeObject,
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::pyobject::{IdProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine; // Required for arg_check! to use isinstance
|
||||
|
||||
use super::objbool;
|
||||
use super::objiter;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
|
||||
pub type PyFilterRef = PyRef<PyFilter>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyFilter {
|
||||
predicate: PyObjectRef,
|
||||
@@ -20,20 +20,19 @@ impl PyValue for PyFilter {
|
||||
}
|
||||
}
|
||||
|
||||
fn filter_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(cls, None), (function, None), (iterable, None)]
|
||||
);
|
||||
let iterator = objiter::get_iter(vm, iterable)?;
|
||||
Ok(PyObject::new(
|
||||
PyFilter {
|
||||
predicate: function.clone(),
|
||||
iterator,
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
fn filter_new(
|
||||
cls: PyClassRef,
|
||||
function: PyObjectRef,
|
||||
iterable: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyFilterRef> {
|
||||
let iterator = objiter::get_iter(vm, &iterable)?;
|
||||
|
||||
PyFilter {
|
||||
predicate: function.clone(),
|
||||
iterator,
|
||||
}
|
||||
.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
fn filter_next(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -4,7 +4,7 @@ use super::objstr;
|
||||
use super::objtype;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{
|
||||
IntoPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
IntoPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_bigint::ToBigInt;
|
||||
@@ -155,7 +155,7 @@ impl PyFloatRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn new_float(cls: PyObjectRef, arg: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
fn new_float(cls: PyClassRef, arg: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyFloatRef> {
|
||||
let value = if objtype::isinstance(&arg, &vm.ctx.float_type()) {
|
||||
get_value(&arg)
|
||||
} else if objtype::isinstance(&arg, &vm.ctx.int_type()) {
|
||||
@@ -193,7 +193,7 @@ impl PyFloatRef {
|
||||
let type_name = objtype::get_type_name(&arg.typ());
|
||||
return Err(vm.new_type_error(format!("can't convert {} to float", type_name)));
|
||||
};
|
||||
Ok(PyObject::new(PyFloat { value }, cls.clone()))
|
||||
PyFloat { value }.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
fn mod_(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub type PyMemoryViewRef = PyRef<PyMemoryView>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyMemoryView {
|
||||
obj: PyObjectRef,
|
||||
@@ -14,15 +15,13 @@ impl PyValue for PyMemoryView {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_memory_view(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(cls, None), (bytes_object, None)]);
|
||||
vm.ctx.set_attr(cls, "obj", bytes_object.clone());
|
||||
Ok(PyObject::new(
|
||||
PyMemoryView {
|
||||
obj: bytes_object.clone(),
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
pub fn new_memory_view(
|
||||
cls: PyClassRef,
|
||||
bytes_object: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyMemoryViewRef> {
|
||||
vm.ctx.set_attr(&cls, "obj", bytes_object.clone());
|
||||
PyMemoryView { obj: bytes_object }.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
pub fn init(ctx: &PyContext) {
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::obj::objproperty::PropertyBuilder;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{
|
||||
DictProtocol, IdProtocol, PyAttributes, PyContext, PyObject, PyObjectRef, PyResult, PyValue,
|
||||
TypeProtocol,
|
||||
TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -22,7 +22,7 @@ impl PyValue for PyInstance {
|
||||
|
||||
pub fn new_instance(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResult {
|
||||
// more or less __new__ operator
|
||||
let cls = args.shift();
|
||||
let cls = PyClassRef::try_from_object(vm, args.shift())?;
|
||||
Ok(if cls.is(&vm.ctx.object) {
|
||||
PyObject::new_without_dict(PyInstance, cls)
|
||||
} else {
|
||||
|
||||
@@ -200,7 +200,7 @@ impl<'a> PropertyBuilder<'a> {
|
||||
deleter: None,
|
||||
};
|
||||
|
||||
PyObject::new(payload, self.ctx.property_type().into_object())
|
||||
PyObject::new(payload, self.ctx.property_type())
|
||||
} else {
|
||||
let payload = PyReadOnlyProperty {
|
||||
getter: self.getter.expect(
|
||||
@@ -208,7 +208,7 @@ impl<'a> PropertyBuilder<'a> {
|
||||
),
|
||||
};
|
||||
|
||||
PyObject::new(payload, self.ctx.readonly_property_type().into_object())
|
||||
PyObject::new(payload, self.ctx.readonly_property_type())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,12 +163,12 @@ pub fn get_item(
|
||||
if sequence.payload::<PyList>().is_some() {
|
||||
Ok(PyObject::new(
|
||||
PyList::from(elements.to_vec().get_slice_items(vm, &subscript)?),
|
||||
sequence.typ(),
|
||||
sequence.type_pyref(),
|
||||
))
|
||||
} else if sequence.payload::<PyTuple>().is_some() {
|
||||
Ok(PyObject::new(
|
||||
PyTuple::from(elements.to_vec().get_slice_items(vm, &subscript)?),
|
||||
sequence.typ(),
|
||||
sequence.type_pyref(),
|
||||
))
|
||||
} else {
|
||||
panic!("sequence get_item called for non-sequence")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objint;
|
||||
@@ -57,14 +57,13 @@ fn slice_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok((cls, Some(start), Some(stop), step))
|
||||
}
|
||||
}?;
|
||||
Ok(PyObject::new(
|
||||
PySlice {
|
||||
start: start.map(|x| objint::get_value(x).clone()),
|
||||
stop: stop.map(|x| objint::get_value(x).clone()),
|
||||
step: step.map(|x| objint::get_value(x).clone()),
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
PySlice {
|
||||
start: start.map(|x| objint::get_value(x).clone()),
|
||||
stop: stop.map(|x| objint::get_value(x).clone()),
|
||||
step: step.map(|x| objint::get_value(x).clone()),
|
||||
}
|
||||
.into_ref_with_type(vm, cls.clone().downcast().unwrap())
|
||||
.map(|x| x.into_object())
|
||||
}
|
||||
|
||||
fn get_property_value(vm: &VirtualMachine, value: &Option<BigInt>) -> PyResult {
|
||||
|
||||
@@ -241,11 +241,12 @@ pub fn type_new_class(
|
||||
bases.push(vm.ctx.object());
|
||||
let name = objstr::get_value(name);
|
||||
new(
|
||||
typ.clone(),
|
||||
typ.clone().downcast().unwrap(),
|
||||
&name,
|
||||
bases,
|
||||
objdict::py_dict_to_attributes(dict),
|
||||
)
|
||||
.map(|x| x.into_object())
|
||||
}
|
||||
|
||||
pub fn type_call(class: PyClassRef, args: Args, kwargs: KwArgs, vm: &VirtualMachine) -> PyResult {
|
||||
@@ -365,14 +366,14 @@ fn linearise_mro(mut bases: Vec<Vec<PyClassRef>>) -> Option<Vec<PyClassRef>> {
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
typ: PyObjectRef,
|
||||
typ: PyClassRef,
|
||||
name: &str,
|
||||
bases: Vec<PyClassRef>,
|
||||
dict: HashMap<String, PyObjectRef>,
|
||||
) -> PyResult {
|
||||
) -> PyResult<PyClassRef> {
|
||||
let mros = bases.into_iter().map(|x| _mro(&x)).collect();
|
||||
let mro = linearise_mro(mros).unwrap();
|
||||
Ok(PyObject {
|
||||
let new_type = PyObject {
|
||||
payload: PyClass {
|
||||
name: String::from(name),
|
||||
mro,
|
||||
@@ -380,7 +381,8 @@ pub fn new(
|
||||
dict: Some(RefCell::new(dict)),
|
||||
typ,
|
||||
}
|
||||
.into_ref())
|
||||
.into_ref();
|
||||
Ok(new_type.downcast().unwrap())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -401,23 +403,8 @@ mod tests {
|
||||
let object: PyClassRef = context.object.clone();
|
||||
let type_type = &context.type_type;
|
||||
|
||||
let a = new(
|
||||
type_type.clone().into_object(),
|
||||
"A",
|
||||
vec![object.clone()],
|
||||
HashMap::new(),
|
||||
)
|
||||
.unwrap();
|
||||
let b = new(
|
||||
type_type.clone().into_object(),
|
||||
"B",
|
||||
vec![object.clone()],
|
||||
HashMap::new(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let a: PyClassRef = a.downcast().unwrap();
|
||||
let b: PyClassRef = b.downcast().unwrap();
|
||||
let a = new(type_type.clone(), "A", vec![object.clone()], HashMap::new()).unwrap();
|
||||
let b = new(type_type.clone(), "B", vec![object.clone()], HashMap::new()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
map_ids(linearise_mro(vec![
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::function::{Args, PyFuncArgs};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objiter;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
|
||||
pub type PyZipRef = PyRef<PyZip>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyZip {
|
||||
iterators: Vec<PyObjectRef>,
|
||||
@@ -16,15 +18,12 @@ impl PyValue for PyZip {
|
||||
}
|
||||
}
|
||||
|
||||
fn zip_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
no_kwargs!(vm, args);
|
||||
let cls = &args.args[0];
|
||||
let iterables = &args.args[1..];
|
||||
fn zip_new(cls: PyClassRef, iterables: Args, vm: &VirtualMachine) -> PyResult<PyZipRef> {
|
||||
let iterators = iterables
|
||||
.iter()
|
||||
.map(|iterable| objiter::get_iter(vm, iterable))
|
||||
.into_iter()
|
||||
.map(|iterable| objiter::get_iter(vm, &iterable))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(PyObject::new(PyZip { iterators }, cls.clone()))
|
||||
PyZip { iterators }.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
fn zip_next(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -152,14 +152,7 @@ pub struct PyContext {
|
||||
|
||||
pub fn create_type(name: &str, type_type: &PyClassRef, base: &PyClassRef) -> PyClassRef {
|
||||
let dict = PyAttributes::new();
|
||||
let new_type = objtype::new(
|
||||
type_type.clone().into_object(),
|
||||
name,
|
||||
vec![base.clone()],
|
||||
dict,
|
||||
)
|
||||
.unwrap();
|
||||
new_type.downcast().unwrap()
|
||||
objtype::new(type_type.clone(), name, vec![base.clone()], dict).unwrap()
|
||||
}
|
||||
|
||||
pub type PyNotImplementedRef = PyRef<PyNotImplemented>;
|
||||
@@ -212,13 +205,14 @@ fn init_type_hierarchy() -> (PyClassRef, PyClassRef) {
|
||||
|
||||
let object_type_ptr = PyObjectRef::into_raw(object_type.clone()) as *mut PyObject<PyClass>;
|
||||
let type_type_ptr = PyObjectRef::into_raw(type_type.clone()) as *mut PyObject<PyClass>;
|
||||
|
||||
let type_type: PyClassRef = type_type.downcast().unwrap();
|
||||
let object_type: PyClassRef = object_type.downcast().unwrap();
|
||||
|
||||
ptr::write(&mut (*object_type_ptr).typ, type_type.clone());
|
||||
ptr::write(&mut (*type_type_ptr).typ, type_type.clone());
|
||||
|
||||
(
|
||||
type_type.downcast().unwrap(),
|
||||
object_type.downcast().unwrap(),
|
||||
)
|
||||
(type_type, object_type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,7 +259,7 @@ impl PyContext {
|
||||
|
||||
fn create_object<T: PyObjectPayload>(payload: T, cls: &PyClassRef) -> PyRef<T> {
|
||||
PyRef {
|
||||
obj: PyObject::new(payload, cls.clone().into_object()),
|
||||
obj: PyObject::new(payload, cls.clone()),
|
||||
_payload: PhantomData,
|
||||
}
|
||||
}
|
||||
@@ -520,33 +514,27 @@ impl PyContext {
|
||||
}
|
||||
|
||||
pub fn new_int<T: Into<BigInt>>(&self, i: T) -> PyObjectRef {
|
||||
PyObject::new(PyInt::new(i), self.int_type().into_object())
|
||||
PyObject::new(PyInt::new(i), self.int_type())
|
||||
}
|
||||
|
||||
pub fn new_float(&self, value: f64) -> PyObjectRef {
|
||||
PyObject::new(PyFloat::from(value), self.float_type().into_object())
|
||||
PyObject::new(PyFloat::from(value), self.float_type())
|
||||
}
|
||||
|
||||
pub fn new_complex(&self, value: Complex64) -> PyObjectRef {
|
||||
PyObject::new(PyComplex::from(value), self.complex_type().into_object())
|
||||
PyObject::new(PyComplex::from(value), self.complex_type())
|
||||
}
|
||||
|
||||
pub fn new_str(&self, s: String) -> PyObjectRef {
|
||||
PyObject::new(objstr::PyString { value: s }, self.str_type().into_object())
|
||||
PyObject::new(objstr::PyString { value: s }, self.str_type())
|
||||
}
|
||||
|
||||
pub fn new_bytes(&self, data: Vec<u8>) -> PyObjectRef {
|
||||
PyObject::new(
|
||||
objbytes::PyBytes::new(data),
|
||||
self.bytes_type().into_object(),
|
||||
)
|
||||
PyObject::new(objbytes::PyBytes::new(data), self.bytes_type())
|
||||
}
|
||||
|
||||
pub fn new_bytearray(&self, data: Vec<u8>) -> PyObjectRef {
|
||||
PyObject::new(
|
||||
objbytearray::PyByteArray::new(data),
|
||||
self.bytearray_type().into_object(),
|
||||
)
|
||||
PyObject::new(objbytearray::PyByteArray::new(data), self.bytearray_type())
|
||||
}
|
||||
|
||||
pub fn new_bool(&self, b: bool) -> PyObjectRef {
|
||||
@@ -558,32 +546,25 @@ impl PyContext {
|
||||
}
|
||||
|
||||
pub fn new_tuple(&self, elements: Vec<PyObjectRef>) -> PyObjectRef {
|
||||
PyObject::new(PyTuple::from(elements), self.tuple_type().into_object())
|
||||
PyObject::new(PyTuple::from(elements), self.tuple_type())
|
||||
}
|
||||
|
||||
pub fn new_list(&self, elements: Vec<PyObjectRef>) -> PyObjectRef {
|
||||
PyObject::new(PyList::from(elements), self.list_type().into_object())
|
||||
PyObject::new(PyList::from(elements), self.list_type())
|
||||
}
|
||||
|
||||
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().into_object())
|
||||
PyObject::new(PySet::default(), self.set_type())
|
||||
}
|
||||
|
||||
pub fn new_dict(&self) -> PyObjectRef {
|
||||
PyObject::new(PyDict::default(), self.dict_type().into_object())
|
||||
PyObject::new(PyDict::default(), self.dict_type())
|
||||
}
|
||||
|
||||
pub fn new_class(&self, name: &str, base: PyClassRef) -> PyClassRef {
|
||||
let typ = objtype::new(
|
||||
self.type_type().into_object(),
|
||||
name,
|
||||
vec![base],
|
||||
PyAttributes::new(),
|
||||
)
|
||||
.unwrap();
|
||||
typ.downcast().unwrap()
|
||||
objtype::new(self.type_type(), name, vec![base], PyAttributes::new()).unwrap()
|
||||
}
|
||||
|
||||
pub fn new_scope(&self) -> Scope {
|
||||
@@ -596,7 +577,7 @@ impl PyContext {
|
||||
name: name.to_string(),
|
||||
dict,
|
||||
},
|
||||
self.module_type.clone().into_object(),
|
||||
self.module_type.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -606,12 +587,12 @@ impl PyContext {
|
||||
{
|
||||
PyObject::new(
|
||||
PyBuiltinFunction::new(f.into_func()),
|
||||
self.builtin_function_or_method_type().into_object(),
|
||||
self.builtin_function_or_method_type(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_frame(&self, code: PyObjectRef, scope: Scope) -> PyObjectRef {
|
||||
PyObject::new(Frame::new(code, scope), self.frame_type().into_object())
|
||||
PyObject::new(Frame::new(code, scope), self.frame_type())
|
||||
}
|
||||
|
||||
pub fn new_property<F, I, V>(&self, f: F) -> PyObjectRef
|
||||
@@ -622,7 +603,7 @@ impl PyContext {
|
||||
}
|
||||
|
||||
pub fn new_code_object(&self, code: bytecode::CodeObject) -> PyObjectRef {
|
||||
PyObject::new(objcode::PyCode::new(code), self.code_type().into_object())
|
||||
PyObject::new(objcode::PyCode::new(code), self.code_type())
|
||||
}
|
||||
|
||||
pub fn new_function(
|
||||
@@ -633,21 +614,18 @@ impl PyContext {
|
||||
) -> PyObjectRef {
|
||||
PyObject::new(
|
||||
PyFunction::new(code_obj, scope, defaults),
|
||||
self.function_type().into_object(),
|
||||
self.function_type(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_bound_method(&self, function: PyObjectRef, object: PyObjectRef) -> PyObjectRef {
|
||||
PyObject::new(
|
||||
PyMethod::new(object, function),
|
||||
self.bound_method_type().into_object(),
|
||||
)
|
||||
PyObject::new(PyMethod::new(object, function), self.bound_method_type())
|
||||
}
|
||||
|
||||
pub fn new_instance(&self, class: PyClassRef, dict: Option<PyAttributes>) -> PyObjectRef {
|
||||
let dict = dict.unwrap_or_default();
|
||||
PyObject {
|
||||
typ: class.into_object(),
|
||||
typ: class,
|
||||
dict: Some(RefCell::new(dict)),
|
||||
payload: objobject::PyInstance,
|
||||
}
|
||||
@@ -716,7 +694,7 @@ pub struct PyObject<T>
|
||||
where
|
||||
T: ?Sized + PyObjectPayload,
|
||||
{
|
||||
pub typ: PyObjectRef,
|
||||
pub typ: PyClassRef,
|
||||
pub dict: Option<RefCell<PyAttributes>>, // __dict__ member
|
||||
pub payload: T,
|
||||
}
|
||||
@@ -896,7 +874,7 @@ where
|
||||
T: ?Sized + PyObjectPayload,
|
||||
{
|
||||
fn type_ref(&self) -> &PyObjectRef {
|
||||
&self.typ
|
||||
self.typ.as_object()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1124,7 +1102,7 @@ where
|
||||
T: PyValue + Sized,
|
||||
{
|
||||
fn into_pyobject(self, vm: &VirtualMachine) -> PyResult {
|
||||
Ok(PyObject::new(self, T::class(vm).into_object()))
|
||||
Ok(PyObject::new(self, T::class(vm)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1146,7 +1124,7 @@ impl<T> PyObject<T>
|
||||
where
|
||||
T: Sized + PyObjectPayload,
|
||||
{
|
||||
pub fn new(payload: T, typ: PyObjectRef) -> PyObjectRef {
|
||||
pub fn new(payload: T, typ: PyClassRef) -> PyObjectRef {
|
||||
PyObject {
|
||||
typ,
|
||||
dict: Some(RefCell::new(PyAttributes::new())),
|
||||
@@ -1155,7 +1133,7 @@ where
|
||||
.into_ref()
|
||||
}
|
||||
|
||||
pub fn new_without_dict(payload: T, typ: PyObjectRef) -> PyObjectRef {
|
||||
pub fn new_without_dict(payload: T, typ: PyClassRef) -> PyObjectRef {
|
||||
PyObject {
|
||||
typ,
|
||||
dict: None,
|
||||
@@ -1187,7 +1165,7 @@ pub trait PyValue: fmt::Debug + Sized + 'static {
|
||||
|
||||
fn into_ref(self, vm: &VirtualMachine) -> PyRef<Self> {
|
||||
PyRef {
|
||||
obj: PyObject::new(self, Self::class(vm).into_object()),
|
||||
obj: PyObject::new(self, Self::class(vm)),
|
||||
_payload: PhantomData,
|
||||
}
|
||||
}
|
||||
@@ -1196,7 +1174,7 @@ pub trait PyValue: fmt::Debug + Sized + 'static {
|
||||
let class = Self::class(vm);
|
||||
if objtype::issubclass(&cls, &class) {
|
||||
Ok(PyRef {
|
||||
obj: PyObject::new(self, cls.obj),
|
||||
obj: PyObject::new(self, cls),
|
||||
_payload: PhantomData,
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -4,16 +4,13 @@
|
||||
* This module fits the python re interface onto the rust regular expression
|
||||
* system.
|
||||
*/
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use regex::{Match, Regex};
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::import;
|
||||
use crate::obj::objstr;
|
||||
use crate::obj::objstr::PyStringRef;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
impl PyValue for Regex {
|
||||
@@ -55,7 +52,8 @@ fn re_match(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
(string, Some(vm.ctx.str_type()))
|
||||
]
|
||||
);
|
||||
let regex = make_regex(vm, pattern)?;
|
||||
let pattern_str = objstr::get_value(&pattern);
|
||||
let regex = make_regex(vm, &pattern_str)?;
|
||||
let search_text = objstr::get_value(string);
|
||||
|
||||
do_match(vm, ®ex, search_text)
|
||||
@@ -74,8 +72,8 @@ fn re_search(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
]
|
||||
);
|
||||
|
||||
// let pattern_str = objstr::get_value(&pattern);
|
||||
let regex = make_regex(vm, pattern)?;
|
||||
let pattern_str = objstr::get_value(&pattern);
|
||||
let regex = make_regex(vm, &pattern_str)?;
|
||||
let search_text = objstr::get_value(string);
|
||||
|
||||
do_search(vm, ®ex, search_text)
|
||||
@@ -93,10 +91,8 @@ fn do_search(vm: &VirtualMachine, regex: &Regex, search_text: String) -> PyResul
|
||||
}
|
||||
}
|
||||
|
||||
fn make_regex(vm: &VirtualMachine, pattern: &PyObjectRef) -> PyResult<Regex> {
|
||||
let pattern_str = objstr::get_value(pattern);
|
||||
|
||||
match Regex::new(&pattern_str) {
|
||||
fn make_regex(vm: &VirtualMachine, pattern: &str) -> PyResult<Regex> {
|
||||
match Regex::new(pattern) {
|
||||
Ok(regex) => Ok(regex),
|
||||
Err(err) => Err(vm.new_value_error(format!("Error in regex: {:?}", err))),
|
||||
}
|
||||
@@ -117,39 +113,24 @@ impl PyValue for PyMatch {
|
||||
|
||||
/// Take a found regular expression and convert it to proper match object.
|
||||
fn create_match(vm: &VirtualMachine, match_value: &Match) -> PyResult {
|
||||
// Return match object:
|
||||
// TODO: implement match object
|
||||
// TODO: how to refer to match object defined in this
|
||||
let module = import::import_module(vm, PathBuf::default(), "re").unwrap();
|
||||
let match_class = vm.get_attribute(module, "Match").unwrap();
|
||||
|
||||
// let mo = vm.invoke(match_class, PyFuncArgs::default())?;
|
||||
// let txt = vm.ctx.new_str(result.as_str().to_string());
|
||||
// vm.ctx.set_attr(&mo, "str", txt);
|
||||
let match_value = PyMatch {
|
||||
Ok(PyMatch {
|
||||
start: match_value.start(),
|
||||
end: match_value.end(),
|
||||
};
|
||||
|
||||
Ok(PyObject::new(match_value, match_class.clone()))
|
||||
}
|
||||
.into_ref(vm)
|
||||
.into_object())
|
||||
}
|
||||
|
||||
/// Compile a regular expression into a Pattern object.
|
||||
/// See also:
|
||||
/// https://docs.python.org/3/library/re.html#re.compile
|
||||
fn re_compile(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(pattern, Some(vm.ctx.str_type()))] // TODO: flags=0
|
||||
);
|
||||
fn re_compile(pattern: PyStringRef, vm: &VirtualMachine) -> PyResult<PyRef<Regex>> {
|
||||
let regex = make_regex(vm, &pattern.value)?;
|
||||
|
||||
let regex = make_regex(vm, pattern)?;
|
||||
// TODO: retrieval of this module is akward:
|
||||
let module = import::import_module(vm, PathBuf::default(), "re").unwrap();
|
||||
let pattern_class = vm.get_attribute(module, "Pattern").unwrap();
|
||||
|
||||
Ok(PyObject::new(regex, pattern_class.clone()))
|
||||
Ok(regex.into_ref(vm))
|
||||
}
|
||||
|
||||
fn pattern_match(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -19,6 +19,7 @@ use crate::function::PyFuncArgs;
|
||||
use crate::obj::objbool;
|
||||
use crate::obj::objbuiltinfunc::PyBuiltinFunction;
|
||||
use crate::obj::objcode;
|
||||
use crate::obj::objcode::PyCodeRef;
|
||||
use crate::obj::objframe;
|
||||
use crate::obj::objfunction::{PyFunction, PyMethod};
|
||||
use crate::obj::objgenerator;
|
||||
@@ -72,8 +73,8 @@ impl VirtualMachine {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_code_obj(&self, code: PyObjectRef, scope: Scope) -> PyResult {
|
||||
let frame = self.ctx.new_frame(code, scope);
|
||||
pub fn run_code_obj(&self, code: PyCodeRef, scope: Scope) -> PyResult {
|
||||
let frame = self.ctx.new_frame(code.into_object(), scope);
|
||||
self.run_frame_full(frame)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@ use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::{future_to_promise, JsFuture};
|
||||
|
||||
use rustpython_vm::function::PyFuncArgs;
|
||||
use rustpython_vm::function::{OptionalArg, PyFuncArgs};
|
||||
use rustpython_vm::import::import_module;
|
||||
use rustpython_vm::obj::objtype::PyClassRef;
|
||||
use rustpython_vm::obj::{objint, objstr};
|
||||
use rustpython_vm::pyobject::{
|
||||
PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
};
|
||||
use rustpython_vm::VirtualMachine;
|
||||
|
||||
@@ -45,8 +45,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 = import_promise_type(vm)?;
|
||||
|
||||
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 +100,7 @@ fn browser_fetch(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
})
|
||||
.and_then(JsFuture::from);
|
||||
|
||||
Ok(PyPromise::new_obj(promise_type, future_to_promise(future)))
|
||||
Ok(PyPromise::from_future(future).into_ref(vm).into_object())
|
||||
}
|
||||
|
||||
fn browser_request_animation_frame(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -159,6 +157,8 @@ fn browser_cancel_animation_frame(vm: &VirtualMachine, args: PyFuncArgs) -> PyRe
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
pub type PyPromiseRef = PyRef<PyPromise>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyPromise {
|
||||
value: Promise,
|
||||
@@ -171,8 +171,15 @@ 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(promise: Promise) -> PyPromise {
|
||||
PyPromise { value: promise }
|
||||
}
|
||||
|
||||
pub fn from_future<F>(future: F) -> PyPromise
|
||||
where
|
||||
F: Future<Item = JsValue, Error = JsValue> + 'static,
|
||||
{
|
||||
PyPromise::new(future_to_promise(future))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,26 +200,17 @@ pub fn import_promise_type(vm: &VirtualMachine) -> PyResult<PyClassRef> {
|
||||
}
|
||||
}
|
||||
|
||||
fn promise_then(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let promise_type = import_promise_type(vm)?;
|
||||
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()))]
|
||||
);
|
||||
|
||||
let on_fulfill = on_fulfill.clone();
|
||||
let on_reject = on_reject.cloned();
|
||||
fn promise_then(
|
||||
zelf: PyPromiseRef,
|
||||
on_fulfill: PyObjectRef,
|
||||
on_reject: OptionalArg<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyPromise {
|
||||
let on_reject = on_reject.into_option();
|
||||
|
||||
let acc_vm = AccessibleVM::from(vm);
|
||||
|
||||
let promise = get_promise_value(zelf);
|
||||
|
||||
let ret_future = JsFuture::from(promise).then(move |res| {
|
||||
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");
|
||||
@@ -234,29 +232,13 @@ fn promise_then(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
convert::pyresult_to_jsresult(vm, ret)
|
||||
});
|
||||
|
||||
let ret_promise = future_to_promise(ret_future);
|
||||
|
||||
Ok(PyPromise::new_obj(promise_type, ret_promise))
|
||||
PyPromise::from_future(ret_future)
|
||||
}
|
||||
|
||||
fn promise_catch(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let promise_type = import_promise_type(vm)?;
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [
|
||||
(zelf, Some(promise_type.clone())),
|
||||
(on_reject, Some(vm.ctx.function_type()))
|
||||
]
|
||||
);
|
||||
|
||||
let on_reject = on_reject.clone();
|
||||
|
||||
fn promise_catch(zelf: PyPromiseRef, on_reject: PyObjectRef, vm: &VirtualMachine) -> PyPromise {
|
||||
let acc_vm = AccessibleVM::from(vm);
|
||||
|
||||
let promise = get_promise_value(zelf);
|
||||
|
||||
let ret_future = JsFuture::from(promise).then(move |res| match res {
|
||||
let ret_future = JsFuture::from(zelf.value.clone()).then(move |res| match res {
|
||||
Ok(val) => Ok(val),
|
||||
Err(err) => {
|
||||
let stored_vm = acc_vm
|
||||
@@ -269,9 +251,7 @@ fn promise_catch(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
});
|
||||
|
||||
let ret_promise = future_to_promise(ret_future);
|
||||
|
||||
Ok(PyPromise::new_obj(promise_type, ret_promise))
|
||||
PyPromise::from_future(ret_future)
|
||||
}
|
||||
|
||||
fn browser_alert(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -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;
|
||||
@@ -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::<Promise>() {
|
||||
// the browser module might not be injected
|
||||
if let Ok(promise_type) = browser_module::import_promise_type(vm) {
|
||||
return browser_module::PyPromise::new_obj(promise_type, promise.clone());
|
||||
if let Ok(_) = browser_module::import_promise_type(vm) {
|
||||
return browser_module::PyPromise::new(promise.clone())
|
||||
.into_ref(vm)
|
||||
.into_object();
|
||||
}
|
||||
}
|
||||
if Array::is_array(&js_val) {
|
||||
|
||||
@@ -285,8 +285,7 @@ impl WASMVirtualMachine {
|
||||
ref vm, ref scope, ..
|
||||
}| {
|
||||
source.push('\n');
|
||||
let code =
|
||||
compile::compile(&source, &mode, "<wasm>".to_string(), vm.ctx.code_type());
|
||||
let code = compile::compile(vm, &source, &mode, "<wasm>".to_string());
|
||||
let code = code.map_err(|err| {
|
||||
let js_err = SyntaxError::new(&format!("Error parsing Python code: {}", err));
|
||||
if let rustpython_vm::error::CompileError::Parse(ref parse_error) = err {
|
||||
|
||||
Reference in New Issue
Block a user