pub mod browser_module;
pub mod convert;
pub mod js_module;
pub mod vm_class;
pub mod wasm_builtins;
#[macro_use]
extern crate rustpython_vm;
use js_sys::{Reflect, WebAssembly::RuntimeError};
use std::panic;
pub use vm_class::add_init_func;
pub(crate) use vm_class::weak_vm;
use wasm_bindgen::prelude::*;
pub fn panic_hook(info: &panic::PanicInfo) {
let try_set_info = || {
let msg = &info.to_string();
let window = match web_sys::window() {
Some(win) => win,
None => return,
};
let _ = Reflect::set(&window, &"__RUSTPYTHON_ERROR_MSG".into(), &msg.into());
let error = RuntimeError::new(msg);
let _ = Reflect::set(&window, &"__RUSTPYTHON_ERROR".into(), &error);
let stack = match Reflect::get(&error, &"stack".into()) {
Ok(stack) => stack,
Err(_) => return,
};
let _ = Reflect::set(&window, &"__RUSTPYTHON_ERROR_STACK".into(), &stack);
};
try_set_info();
console_error_panic_hook::hook(info);
}
#[doc(hidden)]
#[cfg(not(feature = "no-start-func"))]
#[wasm_bindgen(start)]
pub fn _setup_console_error() {
std::panic::set_hook(Box::new(panic_hook));
}
pub mod eval {
use crate::vm_class::VMStore;
use js_sys::{Object, Reflect, TypeError};
use rustpython_vm::compiler::Mode;
use wasm_bindgen::prelude::*;
const PY_EVAL_VM_ID: &str = "__py_eval_vm";
fn run_py(source: &str, options: Option<Object>, mode: Mode) -> Result<JsValue, JsValue> {
let vm = VMStore::init(PY_EVAL_VM_ID.into(), Some(true));
let options = options.unwrap_or_default();
let js_vars = {
let prop = Reflect::get(&options, &"vars".into())?;
if prop.is_undefined() {
None
} else if prop.is_object() {
Some(Object::from(prop))
} else {
return Err(TypeError::new("vars must be an object").into());
}
};
vm.set_stdout(Reflect::get(&options, &"stdout".into())?)?;
if let Some(js_vars) = js_vars {
vm.add_to_scope("js_vars".into(), js_vars.into())?;
}
vm.run(source, mode, None)
}
#[wasm_bindgen(js_name = pyEval)]
pub fn eval_py(source: &str, options: Option<Object>) -> Result<JsValue, JsValue> {
run_py(source, options, Mode::Eval)
}
#[wasm_bindgen(js_name = pyExec)]
pub fn exec_py(source: &str, options: Option<Object>) -> Result<(), JsValue> {
run_py(source, options, Mode::Exec).map(drop)
}
#[wasm_bindgen(js_name = pyExecSingle)]
pub fn exec_single_py(source: &str, options: Option<Object>) -> Result<JsValue, JsValue> {
run_py(source, options, Mode::Single)
}
}
pub mod exports {
pub use crate::convert::PyError;
pub use crate::eval::{eval_py, exec_py, exec_single_py};
pub use crate::vm_class::{VMStore, WASMVirtualMachine};
}
#[doc(hidden)]
pub use exports::*;