mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Merge pull request #914 from palaviv/wasm-import
Add browser.load_module
This commit is contained in:
2 files changed
+71
-19
No files matched your search
+27
-17
@@ -31,29 +31,39 @@ pub fn import_module(vm: &VirtualMachine, current_path: PathBuf, module_name: &s
|
||||
.map_err(|e| vm.new_exception(notfound_error.clone(), e))?;
|
||||
let source = util::read_file(file_path.as_path())
|
||||
.map_err(|e| vm.new_exception(import_error.clone(), e.to_string()))?;
|
||||
let code_obj = compile::compile(
|
||||
|
||||
import_file(
|
||||
vm,
|
||||
&source,
|
||||
&compile::Mode::Exec,
|
||||
module_name,
|
||||
file_path.to_str().unwrap().to_string(),
|
||||
source,
|
||||
)
|
||||
.map_err(|err| vm.new_syntax_error(&err))?;
|
||||
// trace!("Code object: {:?}", code_obj);
|
||||
|
||||
let attrs = vm.ctx.new_dict();
|
||||
attrs.set_item("__name__", vm.new_str(module_name.to_string()), vm)?;
|
||||
let module = vm.ctx.new_module(module_name, attrs.clone());
|
||||
|
||||
// Store module in cache to prevent infinite loop with mutual importing libs:
|
||||
sys_modules.set_item(module_name, module.clone(), vm)?;
|
||||
|
||||
// Execute main code in module:
|
||||
vm.run_code_obj(code_obj, Scope::new(None, attrs))?;
|
||||
|
||||
Ok(module)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn import_file(
|
||||
vm: &VirtualMachine,
|
||||
module_name: &str,
|
||||
file_path: String,
|
||||
content: String,
|
||||
) -> PyResult {
|
||||
let sys_modules = vm.get_attribute(vm.sys_module.clone(), "modules").unwrap();
|
||||
let code_obj = compile::compile(vm, &content, &compile::Mode::Exec, file_path)
|
||||
.map_err(|err| vm.new_syntax_error(&err))?;
|
||||
// trace!("Code object: {:?}", code_obj);
|
||||
|
||||
let attrs = vm.ctx.new_dict();
|
||||
attrs.set_item("__name__", vm.new_str(module_name.to_string()), vm)?;
|
||||
let module = vm.ctx.new_module(module_name, attrs.clone());
|
||||
|
||||
// Store module in cache to prevent infinite loop with mutual importing libs:
|
||||
sys_modules.set_item(module_name, module.clone(), vm)?;
|
||||
|
||||
// Execute main code in module:
|
||||
vm.run_code_obj(code_obj, Scope::new(None, attrs))?;
|
||||
Ok(module)
|
||||
}
|
||||
|
||||
fn find_source(vm: &VirtualMachine, current_path: PathBuf, name: &str) -> Result<PathBuf, String> {
|
||||
let sys_path = vm.get_attribute(vm.sys_module.clone(), "path").unwrap();
|
||||
let mut paths: Vec<PathBuf> = objsequence::get_elements(&sys_path)
|
||||
|
||||
@@ -6,6 +6,7 @@ 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,
|
||||
};
|
||||
@@ -206,8 +207,12 @@ impl PyPromise {
|
||||
let vm = &stored_vm.vm;
|
||||
let ret = match res {
|
||||
Ok(val) => {
|
||||
let val = convert::js_to_py(vm, val);
|
||||
vm.invoke(on_fulfill.into_object(), PyFuncArgs::new(vec![val], vec![]))
|
||||
let args = if val.is_null() {
|
||||
vec![]
|
||||
} else {
|
||||
vec![convert::js_to_py(vm, val)]
|
||||
};
|
||||
vm.invoke(on_fulfill.into_object(), PyFuncArgs::new(args, vec![]))
|
||||
}
|
||||
Err(err) => {
|
||||
if let OptionalArg::Present(on_reject) = on_reject {
|
||||
@@ -342,6 +347,42 @@ fn browser_prompt(
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn browser_load_module(module: PyStringRef, path: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
let weak_vm = weak_vm(vm);
|
||||
|
||||
let mut opts = web_sys::RequestInit::new();
|
||||
opts.method("GET");
|
||||
|
||||
let request = web_sys::Request::new_with_str_and_init(path.as_str(), &opts)
|
||||
.map_err(|err| convert::js_py_typeerror(vm, err))?;
|
||||
|
||||
let window = window();
|
||||
let request_prom = window.fetch_with_request(&request);
|
||||
|
||||
let future = JsFuture::from(request_prom)
|
||||
.and_then(move |val| {
|
||||
let response = val
|
||||
.dyn_into::<web_sys::Response>()
|
||||
.expect("val to be of type Response");
|
||||
response.text()
|
||||
})
|
||||
.and_then(JsFuture::from)
|
||||
.and_then(move |text| {
|
||||
let stored_vm = &weak_vm
|
||||
.upgrade()
|
||||
.expect("that the vm is valid when the promise resolves");
|
||||
let vm = &stored_vm.vm;
|
||||
let resp_text = text.as_string().unwrap();
|
||||
let res = import_file(vm, module.as_str(), "WEB".to_string(), resp_text);
|
||||
match res {
|
||||
Ok(_) => Ok(JsValue::null()),
|
||||
Err(err) => Err(convert::py_err_to_js_err(vm, &err)),
|
||||
}
|
||||
});
|
||||
|
||||
Ok(PyPromise::from_future(future).into_ref(vm).into_object())
|
||||
}
|
||||
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
@@ -370,6 +411,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
"alert" => ctx.new_rustfunc(browser_alert),
|
||||
"confirm" => ctx.new_rustfunc(browser_confirm),
|
||||
"prompt" => ctx.new_rustfunc(browser_prompt),
|
||||
"load_module" => ctx.new_rustfunc(browser_load_module),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user