Skip to content

Mapping Python print to JavaScript console.log #203

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 1 commit into from
Dec 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion vm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use super::sysmodule;
/// Top level container of a python virtual machine. In theory you could
/// create more instances of this struct and have them operate fully isolated.
pub struct VirtualMachine {
builtins: PyObjectRef,
pub builtins: PyObjectRef,
pub sys_module: PyObjectRef,
pub stdlib_inits: HashMap<String, stdlib::StdlibInitFunc>,
pub ctx: PyContext,
Expand Down
4 changes: 4 additions & 0 deletions wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ rustpython_vm = {path = "../vm"}
cfg-if = "0.1.2"
wasm-bindgen = "0.2"

[dependencies.web-sys]
version = "0.3"
features = [ "console" ]


[profile.release]
opt-level = "s"
32 changes: 19 additions & 13 deletions wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
mod wasm_builtins;

extern crate rustpython_vm;
extern crate wasm_bindgen;
use rustpython_vm::compile;
extern crate web_sys;

use rustpython_vm::VirtualMachine;
use rustpython_vm::compile;
use rustpython_vm::pyobject::AttributeProtocol;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
// Use `js_namespace` here to bind `console.log(..)` instead of just
// `log(..)`
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
use web_sys::console;

#[wasm_bindgen]
pub fn run_code(source: &str) -> () {
//add hash in here
log("Running RustPython");
log(&source.to_string());
console::log_1(&"Running RustPython".into());
console::log_1(&"Running code:".into());
console::log_1(&source.to_string().into());
console::log_1(&"----- console -----".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);

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) => log("Execution successful"),
Err(_) => log("Execution failed"),
Ok(_value) => console::log_1(&"Execution successful".into()),
Err(_) => console::log_1(&"Execution failed".into()),
}
}
28 changes: 28 additions & 0 deletions wasm/src/wasm_builtins.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! Builtin function specific to WASM build.
//!
//! This is required because some feature like I/O works differently in the browser comparing to
//! desktop.
//! Implements functions listed here: https://docs.python.org/3/library/builtins.html
//!
extern crate wasm_bindgen;
extern crate web_sys;

use rustpython_vm::obj::objstr;
use rustpython_vm::VirtualMachine;
use rustpython_vm::pyobject::{ PyFuncArgs, PyResult };
use web_sys::console;

pub fn builtin_print(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let mut first = true;
for a in args.args {
if first {
first = false;
} else {
console::log_1(&" ".into())
}
let v = vm.to_str(&a)?;
let s = objstr::get_value(&v);
console::log_1(&format!("{}", s).into())
}
Ok(vm.get_none())
}