Convert to new PyResult in rustpython_wasm

This commit is contained in:
coolreader18
2019-12-17 22:05:23 -06:00
parent 420f5c3490
commit 1773025368
6 changed files with 41 additions and 54 deletions

2
Cargo.lock generated
View File

@@ -1368,8 +1368,6 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
"num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rustpython-compiler 0.1.1",
"rustpython-parser 0.1.1",
"rustpython-vm 0.1.1",

View File

@@ -25,8 +25,6 @@ serde-wasm-bindgen = "0.1"
serde = "1.0"
js-sys = "0.3"
futures = "0.1"
num-traits = "0.2"
num-bigint = { version = "0.2.3", features = ["serde"] }
[dependencies.web-sys]
version = "0.3"

View File

@@ -1,15 +1,12 @@
use futures::Future;
use js_sys::Promise;
use num_traits::cast::ToPrimitive;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::{future_to_promise, JsFuture};
use rustpython_vm::function::{OptionalArg, PyFuncArgs};
use rustpython_vm::import::import_file;
use rustpython_vm::obj::{
objdict::PyDictRef, objint::PyIntRef, objstr::PyStringRef, objtype::PyClassRef,
};
use rustpython_vm::obj::{objdict::PyDictRef, objstr::PyStringRef, objtype::PyClassRef};
use rustpython_vm::pyobject::{
PyCallable, PyClassImpl, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
};
@@ -148,14 +145,7 @@ fn browser_request_animation_frame(func: PyCallable, vm: &VirtualMachine) -> PyR
Ok(vm.ctx.new_int(id))
}
fn browser_cancel_animation_frame(id: PyIntRef, vm: &VirtualMachine) -> PyResult {
let id = id.as_bigint().to_i32().ok_or_else(|| {
vm.new_exception(
vm.ctx.exceptions.value_error.clone(),
"Integer too large to convert to i32 for animationFrame id".into(),
)
})?;
fn browser_cancel_animation_frame(id: i32, vm: &VirtualMachine) -> PyResult {
window()
.cancel_animation_frame(id)
.map_err(|err| convert::js_py_typeerror(vm, err))?;
@@ -308,7 +298,7 @@ impl Element {
fn set_attr(&self, attr: PyStringRef, value: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
self.elem
.set_attribute(attr.as_str(), value.as_str())
.map_err(|err| convert::js_to_py(vm, err))
.map_err(|err| convert::js_py_typeerror(vm, err))
}
}

View File

@@ -1,20 +1,18 @@
use js_sys::{Array, ArrayBuffer, Object, Promise, Reflect, Uint8Array};
use num_traits::cast::ToPrimitive;
use serde_wasm_bindgen;
use wasm_bindgen::{closure::Closure, prelude::*, JsCast};
use rustpython_vm::exceptions::PyBaseExceptionRef;
use rustpython_vm::function::PyFuncArgs;
use rustpython_vm::obj::{objbytes, objint, objsequence, objtype};
use rustpython_vm::obj::{objbytes, objtype};
use rustpython_vm::py_serde;
use rustpython_vm::pyobject::{ItemProtocol, PyObjectRef, PyResult, PyValue};
use rustpython_vm::VirtualMachine;
use num_bigint::BigInt;
use crate::browser_module;
use crate::vm_class::{stored_vm_from_wasm, WASMVirtualMachine};
pub fn py_err_to_js_err(vm: &VirtualMachine, py_err: &PyObjectRef) -> JsValue {
pub fn py_err_to_js_err(vm: &VirtualMachine, py_err: &PyBaseExceptionRef) -> JsValue {
macro_rules! map_exceptions {
($py_exc:ident, $msg:expr, { $($py_exc_ty:expr => $js_err_new:expr),*$(,)? }) => {
$(if objtype::isinstance($py_exc, $py_exc_ty) {
@@ -24,11 +22,11 @@ pub fn py_err_to_js_err(vm: &VirtualMachine, py_err: &PyObjectRef) -> JsValue {
}
};
}
let msg = match vm.to_pystr(py_err) {
let msg = match vm.to_str(py_err.as_object()) {
Ok(msg) => msg,
Err(_) => return js_sys::Error::new("error getting error").into(),
};
let js_err = map_exceptions!(py_err,& msg, {
let js_err = map_exceptions!(py_err, msg.as_str(), {
// TypeError is sort of a catch-all for "this value isn't what I thought it was like"
&vm.ctx.exceptions.type_error => js_sys::TypeError::new,
&vm.ctx.exceptions.value_error => js_sys::TypeError::new,
@@ -38,31 +36,36 @@ pub fn py_err_to_js_err(vm: &VirtualMachine, py_err: &PyObjectRef) -> JsValue {
&vm.ctx.exceptions.name_error => js_sys::ReferenceError::new,
&vm.ctx.exceptions.syntax_error => js_sys::SyntaxError::new,
});
if let Ok(tb) = vm.get_attribute(py_err.clone(), "__traceback__") {
if objtype::isinstance(&tb, &vm.ctx.list_type()) {
let elements = objsequence::get_elements_list(&tb).to_vec();
if let Some(top) = elements.get(0) {
if objtype::isinstance(&top, &vm.ctx.tuple_type()) {
let element = objsequence::get_elements_tuple(&top);
if let Some(lineno) = objint::to_int(vm, &element[1], &BigInt::from(10))
.ok()
.and_then(|lineno| lineno.to_u32())
{
let _ = Reflect::set(&js_err, &"row".into(), &lineno.into());
}
}
}
}
if let Some(tb) = py_err.traceback() {
let _ = Reflect::set(&js_err, &"row".into(), &(tb.lineno as u32).into());
}
js_err
}
pub fn js_py_typeerror(vm: &VirtualMachine, js_err: JsValue) -> PyObjectRef {
pub fn js_py_typeerror(vm: &VirtualMachine, js_err: JsValue) -> PyBaseExceptionRef {
let msg = js_err.unchecked_into::<js_sys::Error>().to_string();
vm.new_type_error(msg.into())
}
pub fn js_err_to_py_err(vm: &VirtualMachine, js_err: &JsValue) -> PyBaseExceptionRef {
match js_err.dyn_ref::<js_sys::Error>() {
Some(err) => {
let exc_type = match String::from(err.name()).as_str() {
"TypeError" => &vm.ctx.exceptions.type_error,
"ReferenceError" => &vm.ctx.exceptions.name_error,
"SyntaxError" => &vm.ctx.exceptions.syntax_error,
_ => &vm.ctx.exceptions.exception_type,
}
.clone();
vm.new_exception(exc_type, err.message().into())
}
None => vm.new_exception(
vm.ctx.exceptions.exception_type.clone(),
format!("{:?}", js_err),
),
}
}
pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue {
if let Some(ref wasm_id) = vm.wasm_id {
if objtype::isinstance(&py_obj, &vm.ctx.function_type()) {
@@ -207,17 +210,10 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
}
func.apply(&this, &js_args)
.map(|val| js_to_py(vm, val))
.map_err(|err| js_to_py(vm, err))
.map_err(|err| js_err_to_py_err(vm, &err))
})
} else if let Some(err) = js_val.dyn_ref::<js_sys::Error>() {
let exc_type = match String::from(err.name()).as_str() {
"TypeError" => &vm.ctx.exceptions.type_error,
"ReferenceError" => &vm.ctx.exceptions.name_error,
"SyntaxError" => &vm.ctx.exceptions.syntax_error,
_ => &vm.ctx.exceptions.exception_type,
}
.clone();
vm.new_exception(exc_type, err.message().into())
js_err_to_py_err(vm, err).into_object()
} else if js_val.is_undefined() {
// Because `JSON.stringify(undefined)` returns undefined
vm.get_none()

View File

@@ -1,4 +1,5 @@
use js_sys::{Array, Object, Reflect};
use rustpython_vm::exceptions::PyBaseExceptionRef;
use rustpython_vm::function::Args;
use rustpython_vm::obj::{objfloat::PyFloatRef, objstr::PyStringRef, objtype::PyClassRef};
use rustpython_vm::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject};
@@ -233,10 +234,14 @@ struct NewObjectOptions {
prototype: Option<PyJsValueRef>,
}
fn new_js_error(vm: &VirtualMachine, err: JsValue) -> PyObjectRef {
fn new_js_error(vm: &VirtualMachine, err: JsValue) -> PyBaseExceptionRef {
let exc = vm.new_exception(vm.class("_js", "JsError"), format!("{:?}", err));
vm.set_attr(&exc, "js_value", PyJsValue::new(err).into_ref(vm))
.unwrap();
vm.set_attr(
exc.as_object(),
"js_value",
PyJsValue::new(err).into_ref(vm),
)
.unwrap();
exc
}

View File

@@ -232,7 +232,7 @@ impl WASMVirtualMachine {
&JsValue::UNDEFINED,
&wasm_builtins::format_print_args(vm, args)?.into(),
)
.map_err(|err| convert::js_to_py(vm, err))?;
.map_err(|err| convert::js_py_typeerror(vm, err))?;
Ok(vm.get_none())
})
} else if stdout.is_null() {