-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Improve wasm demo website #230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 3 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b428f2e
Improve demo site
coolreader18 f8cce25
Formatting; move the `+ '\n'` hack to eval().
coolreader18 2ae1df5
Rename run_code() to run_from_textbox()
coolreader18 921efd4
Switch to using json.dumps for py_to_js()
coolreader18 3be6fee
Clarify names of wasm builtins
coolreader18 e78a251
Remove dependency on num_bigint
coolreader18 a796b13
Allow injecting JS variables into python with eval_py()
coolreader18 e77f223
Add documentation for eval_py() and update error message handling
coolreader18 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,3 +6,4 @@ __pycache__ | |
| **/*.pytest_cache | ||
| .*sw* | ||
| .repl_history.txt | ||
| wasm-pack.log | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| bin/ | ||
| pkg/ |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| dist/ | ||
| node_modules/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "singleQuote": true, | ||
| "tabWidth": 4 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| // A dependency graph that contains any wasm must all be imported | ||
| // asynchronously. This `bootstrap.js` file does the single async import, so | ||
| // that no one else needs to worry about it again. | ||
| import("./index.js") | ||
| .catch(e => console.error("Error importing `index.js`:", e)); | ||
| import('./index.js').catch(e => | ||
| console.error('Error importing `index.js`:', e) | ||
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,26 +1,25 @@ | ||
| import * as rp from "rustpython_wasm"; | ||
| import * as rp from 'rustpython_wasm'; | ||
|
|
||
| // so people can play around with it | ||
| window.rp = rp; | ||
|
coolreader18 marked this conversation as resolved.
|
||
|
|
||
| function runCodeFromTextarea(_) { | ||
| const consoleElement = document.getElementById('console'); | ||
| // Clean the console | ||
| consoleElement.value = ''; | ||
| const consoleElement = document.getElementById('console'); | ||
| const errorElement = document.getElementById('error'); | ||
| // Clean the console | ||
| consoleElement.value = ''; | ||
|
|
||
| const code = document.getElementById('code').value; | ||
| try { | ||
| if (!code.endsWith('\n')) { // HACK: if the code doesn't end with newline it crashes. | ||
| rp.run_code(code + '\n'); | ||
| return; | ||
| const code = document.getElementById('code').value; | ||
| try { | ||
| rp.run_from_textbox(code); | ||
| } catch (e) { | ||
| errorElement.textContent = e; | ||
| console.error(e); | ||
| } | ||
|
|
||
| rp.run_code(code); | ||
|
|
||
| } catch(e) { | ||
| consoleElement.value = 'Execution failed. Please check if your Python code has any syntax error.'; | ||
| console.error(e); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| document.getElementById('run-btn').addEventListener('click', runCodeFromTextarea); | ||
| document | ||
| .getElementById('run-btn') | ||
| .addEventListener('click', runCodeFromTextarea); | ||
|
|
||
| runCodeFromTextarea(); // Run once for demo | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,33 +1,133 @@ | ||
| mod wasm_builtins; | ||
|
|
||
| extern crate js_sys; | ||
| extern crate num_bigint; | ||
| extern crate rustpython_vm; | ||
| extern crate wasm_bindgen; | ||
| extern crate web_sys; | ||
|
|
||
| use rustpython_vm::VirtualMachine; | ||
| use num_bigint::BigInt; | ||
| use rustpython_vm::compile; | ||
| use rustpython_vm::pyobject::AttributeProtocol; | ||
| use rustpython_vm::pyobject::{self, IdProtocol, PyObjectRef, PyResult}; | ||
| use rustpython_vm::VirtualMachine; | ||
| use wasm_bindgen::prelude::*; | ||
| use web_sys::console; | ||
|
|
||
| fn py_str_err(vm: &mut VirtualMachine, py_err: &PyObjectRef) -> String { | ||
| vm.to_pystr(&py_err) | ||
| .unwrap_or_else(|_| "Error, and error getting error message".into()) | ||
| } | ||
|
|
||
| fn py_to_js(vm: &mut VirtualMachine, py_obj: &PyObjectRef) -> JsValue { | ||
|
coolreader18 marked this conversation as resolved.
Outdated
|
||
| use pyobject::PyObjectKind; | ||
| let py_obj = py_obj.borrow(); | ||
| match py_obj.kind { | ||
|
coolreader18 marked this conversation as resolved.
Outdated
|
||
| PyObjectKind::String { ref value } => value.into(), | ||
| PyObjectKind::Integer { ref value } => { | ||
| if let Some(ref typ) = py_obj.typ { | ||
| if typ.is(&vm.ctx.bool_type()) { | ||
| let out_bool = value == &BigInt::new(num_bigint::Sign::Plus, vec![1]); | ||
| return out_bool.into(); | ||
| } | ||
| } | ||
| let int = vm.ctx.new_int(value.clone()); | ||
| rustpython_vm::obj::objfloat::make_float(vm, &int) | ||
| .unwrap() | ||
| .into() | ||
| } | ||
| PyObjectKind::Float { ref value } => JsValue::from_f64(*value), | ||
| PyObjectKind::Bytes { ref value } => { | ||
| let arr = js_sys::Uint8Array::new(&JsValue::from(value.len() as u32)); | ||
| for (i, byte) in value.iter().enumerate() { | ||
| console::log_1(&JsValue::from(i as u32)); | ||
| js_sys::Reflect::set(&arr, &JsValue::from(i as u32), &JsValue::from(*byte)) | ||
| .unwrap(); | ||
| } | ||
| arr.into() | ||
| } | ||
| PyObjectKind::Sequence { ref elements } => { | ||
| let arr = js_sys::Array::new(); | ||
| for val in elements { | ||
| arr.push(&py_to_js(vm, val)); | ||
| } | ||
| arr.into() | ||
| } | ||
| PyObjectKind::Dict { ref elements } => { | ||
| let obj = js_sys::Object::new(); | ||
| for (key, (_, val)) in elements { | ||
| js_sys::Reflect::set(&obj, &key.into(), &py_to_js(vm, val)) | ||
| .expect("couldn't set property of object"); | ||
| } | ||
| obj.into() | ||
| } | ||
| PyObjectKind::None => JsValue::UNDEFINED, | ||
| _ => JsValue::UNDEFINED, | ||
| } | ||
| } | ||
|
|
||
| fn eval(vm: &mut VirtualMachine, source: &str) -> PyResult { | ||
| // HACK: if the code doesn't end with newline it crashes. | ||
| let mut source = source.to_string(); | ||
| if !source.ends_with('\n') { | ||
| source.push('\n'); | ||
| } | ||
|
|
||
| let code_obj = compile::compile(vm, &source, compile::Mode::Exec, None)?; | ||
|
|
||
| let builtins = vm.get_builtin_scope(); | ||
| let vars = vm.context().new_scope(Some(builtins)); | ||
|
|
||
| vm.run_code_obj(code_obj, vars) | ||
| } | ||
|
|
||
| #[wasm_bindgen] | ||
| pub fn eval_py(source: &str) -> Result<JsValue, JsValue> { | ||
| let mut vm = VirtualMachine::new(); | ||
|
|
||
| vm.ctx.set_attr( | ||
| &vm.builtins, | ||
| "print", | ||
| vm.context().new_rustfunc(wasm_builtins::builtin_log), | ||
| ); | ||
|
|
||
| eval(&mut vm, source) | ||
| .map(|value| py_to_js(&mut vm, &value)) | ||
| .map_err(|err| py_str_err(&mut vm, &err).into()) | ||
| } | ||
|
|
||
| #[wasm_bindgen] | ||
| pub fn run_code(source: &str) -> () { | ||
| pub fn run_from_textbox(source: &str) -> Result<JsValue, JsValue> { | ||
| //add hash in here | ||
| console::log_1(&"Running RustPython".into()); | ||
| console::log_1(&"Running code:".into()); | ||
| console::log_1(&source.to_string().into()); | ||
|
|
||
| let mut vm = VirtualMachine::new(); | ||
| // We are monkey-patching the builtin print to use console.log | ||
| // TODO: moneky-patch sys.stdout instead, after print actually uses sys.stdout | ||
| vm.builtins.set_attr("print", vm.context().new_rustfunc(wasm_builtins::builtin_print)); | ||
|
|
||
| let code_obj = compile::compile(&mut vm, &source.to_string(), compile::Mode::Exec, None); | ||
| // We are monkey-patching the builtin print to use console.log | ||
| // TODO: monkey-patch sys.stdout instead, after print actually uses sys.stdout | ||
| vm.ctx.set_attr( | ||
|
coolreader18 marked this conversation as resolved.
|
||
| &vm.builtins, | ||
| "print", | ||
| vm.context().new_rustfunc(wasm_builtins::builtin_print), | ||
| ); | ||
|
|
||
| let builtins = vm.get_builtin_scope(); | ||
| let vars = vm.context().new_scope(Some(builtins)); | ||
| match vm.run_code_obj(code_obj.unwrap(), vars) { | ||
| Ok(_value) => console::log_1(&"Execution successful".into()), | ||
| Err(_) => console::log_1(&"Execution failed".into()), | ||
| match eval(&mut vm, source) { | ||
| Ok(value) => { | ||
| console::log_1(&"Execution successful".into()); | ||
| match value.borrow().kind { | ||
| pyobject::PyObjectKind::None => {} | ||
| _ => { | ||
| if let Ok(text) = vm.to_pystr(&value) { | ||
| wasm_builtins::print_to_html(&text); | ||
| } | ||
| } | ||
| } | ||
| Ok(JsValue::UNDEFINED) | ||
| } | ||
| Err(err) => { | ||
| console::log_1(&"Execution failed".into()); | ||
| Err(py_str_err(&mut vm, &err).into()) | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.