Skip to content

Commit 5734fc2

Browse files
authored
Merge pull request RustPython#203 from RustPython/consolelog
Mapping Python print to JavaScript console.log
2 parents 8eacbcb + 2c55c47 commit 5734fc2

File tree

4 files changed

+52
-14
lines changed

4 files changed

+52
-14
lines changed

vm/src/vm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use super::sysmodule;
3131
/// Top level container of a python virtual machine. In theory you could
3232
/// create more instances of this struct and have them operate fully isolated.
3333
pub struct VirtualMachine {
34-
builtins: PyObjectRef,
34+
pub builtins: PyObjectRef,
3535
pub sys_module: PyObjectRef,
3636
pub stdlib_inits: HashMap<String, stdlib::StdlibInitFunc>,
3737
pub ctx: PyContext,

wasm/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ rustpython_vm = {path = "../vm"}
1515
cfg-if = "0.1.2"
1616
wasm-bindgen = "0.2"
1717

18+
[dependencies.web-sys]
19+
version = "0.3"
20+
features = [ "console" ]
21+
1822

1923
[profile.release]
2024
opt-level = "s"

wasm/src/lib.rs

+19-13
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
1+
mod wasm_builtins;
2+
13
extern crate rustpython_vm;
24
extern crate wasm_bindgen;
3-
use rustpython_vm::compile;
5+
extern crate web_sys;
6+
47
use rustpython_vm::VirtualMachine;
8+
use rustpython_vm::compile;
9+
use rustpython_vm::pyobject::AttributeProtocol;
510
use wasm_bindgen::prelude::*;
6-
7-
#[wasm_bindgen]
8-
extern "C" {
9-
// Use `js_namespace` here to bind `console.log(..)` instead of just
10-
// `log(..)`
11-
#[wasm_bindgen(js_namespace = console)]
12-
fn log(s: &str);
13-
}
11+
use web_sys::console;
1412

1513
#[wasm_bindgen]
1614
pub fn run_code(source: &str) -> () {
1715
//add hash in here
18-
log("Running RustPython");
19-
log(&source.to_string());
16+
console::log_1(&"Running RustPython".into());
17+
console::log_1(&"Running code:".into());
18+
console::log_1(&source.to_string().into());
19+
console::log_1(&"----- console -----".into());
20+
2021
let mut vm = VirtualMachine::new();
22+
// We are monkey-patching the builtin print to use console.log
23+
// TODO: moneky-patch sys.stdout instead, after print actually uses sys.stdout
24+
vm.builtins.set_attr("print", vm.context().new_rustfunc(wasm_builtins::builtin_print));
25+
2126
let code_obj = compile::compile(&mut vm, &source.to_string(), compile::Mode::Exec, None);
27+
2228
let builtins = vm.get_builtin_scope();
2329
let vars = vm.context().new_scope(Some(builtins));
2430
match vm.run_code_obj(code_obj.unwrap(), vars) {
25-
Ok(_value) => log("Execution successful"),
26-
Err(_) => log("Execution failed"),
31+
Ok(_value) => console::log_1(&"Execution successful".into()),
32+
Err(_) => console::log_1(&"Execution failed".into()),
2733
}
2834
}

wasm/src/wasm_builtins.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//! Builtin function specific to WASM build.
2+
//!
3+
//! This is required because some feature like I/O works differently in the browser comparing to
4+
//! desktop.
5+
//! Implements functions listed here: https://docs.python.org/3/library/builtins.html
6+
//!
7+
extern crate wasm_bindgen;
8+
extern crate web_sys;
9+
10+
use rustpython_vm::obj::objstr;
11+
use rustpython_vm::VirtualMachine;
12+
use rustpython_vm::pyobject::{ PyFuncArgs, PyResult };
13+
use web_sys::console;
14+
15+
pub fn builtin_print(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
16+
let mut first = true;
17+
for a in args.args {
18+
if first {
19+
first = false;
20+
} else {
21+
console::log_1(&" ".into())
22+
}
23+
let v = vm.to_str(&a)?;
24+
let s = objstr::get_value(&v);
25+
console::log_1(&format!("{}", s).into())
26+
}
27+
Ok(vm.get_none())
28+
}

0 commit comments

Comments
 (0)