@@ -7,106 +7,130 @@ pub mod wasm_builtins;
77#[ macro_use]
88extern crate rustpython_vm;
99
10- use js_sys:: { Object , Reflect , TypeError } ;
11- use rustpython_vm:: compile:: Mode ;
10+ pub ( crate ) use vm_class:: weak_vm;
11+
12+ use js_sys:: { Reflect , WebAssembly :: RuntimeError } ;
1213use std:: panic;
1314use wasm_bindgen:: prelude:: * ;
1415
15- pub use crate :: convert:: PyError ;
16- pub use crate :: vm_class:: * ;
17-
18- const PY_EVAL_VM_ID : & str = "__py_eval_vm" ;
16+ pub use vm_class:: add_init_func;
1917
20- fn panic_hook ( info : & panic:: PanicInfo ) {
18+ /// Sets error info on the window object, and prints the backtrace to console
19+ pub fn panic_hook ( info : & panic:: PanicInfo ) {
2120 // If something errors, just ignore it; we don't want to panic in the panic hook
22- use js_sys:: WebAssembly :: RuntimeError ;
23- let window = match web_sys:: window ( ) {
24- Some ( win) => win,
25- None => return ,
21+ let try_set_info = || {
22+ let msg = & info. to_string ( ) ;
23+ let window = match web_sys:: window ( ) {
24+ Some ( win) => win,
25+ None => return ,
26+ } ;
27+ let _ = Reflect :: set ( & window, & "__RUSTPYTHON_ERROR_MSG" . into ( ) , & msg. into ( ) ) ;
28+ let error = RuntimeError :: new ( & msg) ;
29+ let _ = Reflect :: set ( & window, & "__RUSTPYTHON_ERROR" . into ( ) , & error) ;
30+ let stack = match Reflect :: get ( & error, & "stack" . into ( ) ) {
31+ Ok ( stack) => stack,
32+ Err ( _) => return ,
33+ } ;
34+ let _ = Reflect :: set ( & window, & "__RUSTPYTHON_ERROR_STACK" . into ( ) , & stack) ;
2635 } ;
27- let msg = & info. to_string ( ) ;
28- let _ = Reflect :: set ( & window, & "__RUSTPYTHON_ERROR_MSG" . into ( ) , & msg. into ( ) ) ;
29- let error = RuntimeError :: new ( & msg) ;
30- let _ = Reflect :: set ( & window, & "__RUSTPYTHON_ERROR" . into ( ) , & error) ;
31- let stack = match Reflect :: get ( & error, & "stack" . into ( ) ) {
32- Ok ( stack) => stack,
33- Err ( _) => return ,
34- } ;
35- let _ = Reflect :: set ( & window, & "__RUSTPYTHON_ERROR_STACK" . into ( ) , & stack) ;
36+ try_set_info ( ) ;
37+ console_error_panic_hook:: hook ( info) ;
3638}
3739
40+ #[ doc( hidden) ]
3841#[ wasm_bindgen( start) ]
39- pub fn setup_console_error ( ) {
42+ pub fn _setup_console_error ( ) {
4043 std:: panic:: set_hook ( Box :: new ( panic_hook) ) ;
4144}
4245
43- fn run_py ( source : & str , options : Option < Object > , mode : Mode ) -> Result < JsValue , JsValue > {
44- let vm = VMStore :: init ( PY_EVAL_VM_ID . into ( ) , Some ( true ) ) ;
45- let options = options. unwrap_or_else ( Object :: new) ;
46- let js_vars = {
47- let prop = Reflect :: get ( & options, & "vars" . into ( ) ) ?;
48- if prop. is_undefined ( ) {
49- None
50- } else if prop. is_object ( ) {
51- Some ( Object :: from ( prop) )
52- } else {
53- return Err ( TypeError :: new ( "vars must be an object" ) . into ( ) ) ;
46+ pub mod eval {
47+ use crate :: vm_class:: VMStore ;
48+ use js_sys:: { Object , Reflect , TypeError } ;
49+ use rustpython_vm:: compile:: Mode ;
50+ use wasm_bindgen:: prelude:: * ;
51+
52+ const PY_EVAL_VM_ID : & str = "__py_eval_vm" ;
53+
54+ fn run_py ( source : & str , options : Option < Object > , mode : Mode ) -> Result < JsValue , JsValue > {
55+ let vm = VMStore :: init ( PY_EVAL_VM_ID . into ( ) , Some ( true ) ) ;
56+ let options = options. unwrap_or_else ( Object :: new) ;
57+ let js_vars = {
58+ let prop = Reflect :: get ( & options, & "vars" . into ( ) ) ?;
59+ if prop. is_undefined ( ) {
60+ None
61+ } else if prop. is_object ( ) {
62+ Some ( Object :: from ( prop) )
63+ } else {
64+ return Err ( TypeError :: new ( "vars must be an object" ) . into ( ) ) ;
65+ }
66+ } ;
67+
68+ vm. set_stdout ( Reflect :: get ( & options, & "stdout" . into ( ) ) ?) ?;
69+
70+ if let Some ( js_vars) = js_vars {
71+ vm. add_to_scope ( "js_vars" . into ( ) , js_vars. into ( ) ) ?;
5472 }
55- } ;
73+ vm. run ( source, mode, None )
74+ }
5675
57- vm. set_stdout ( Reflect :: get ( & options, & "stdout" . into ( ) ) ?) ?;
76+ /// Evaluate Python code
77+ ///
78+ /// ```js
79+ /// var result = pyEval(code, options?);
80+ /// ```
81+ ///
82+ /// `code`: `string`: The Python code to run in eval mode
83+ ///
84+ /// `options`:
85+ ///
86+ /// - `vars?`: `{ [key: string]: any }`: Variables passed to the VM that can be
87+ /// accessed in Python with the variable `js_vars`. Functions do work, and
88+ /// receive the Python kwargs as the `this` argument.
89+ /// - `stdout?`: `"console" | ((out: string) => void) | null`: A function to replace the
90+ /// native print native print function, and it will be `console.log` when giving
91+ /// `undefined` or "console", and it will be a dumb function when giving null.
92+ #[ wasm_bindgen( js_name = pyEval) ]
93+ pub fn eval_py ( source : & str , options : Option < Object > ) -> Result < JsValue , JsValue > {
94+ run_py ( source, options, Mode :: Eval )
95+ }
5896
59- if let Some ( js_vars) = js_vars {
60- vm. add_to_scope ( "js_vars" . into ( ) , js_vars. into ( ) ) ?;
97+ /// Evaluate Python code
98+ ///
99+ /// ```js
100+ /// pyExec(code, options?);
101+ /// ```
102+ ///
103+ /// `code`: `string`: The Python code to run in exec mode
104+ ///
105+ /// `options`: The options are the same as eval mode
106+ #[ wasm_bindgen( js_name = pyExec) ]
107+ pub fn exec_py ( source : & str , options : Option < Object > ) -> Result < ( ) , JsValue > {
108+ run_py ( source, options, Mode :: Exec ) . map ( drop)
61109 }
62- vm. run ( source, mode, None )
63- }
64110
65- /// Evaluate Python code
66- ///
67- /// ```js
68- /// var result = pyEval(code, options?);
69- /// ```
70- ///
71- /// `code`: `string`: The Python code to run in eval mode
72- ///
73- /// `options`:
74- ///
75- /// - `vars?`: `{ [key: string]: any }`: Variables passed to the VM that can be
76- /// accessed in Python with the variable `js_vars`. Functions do work, and
77- /// receive the Python kwargs as the `this` argument.
78- /// - `stdout?`: `"console" | ((out: string) => void) | null`: A function to replace the
79- /// native print native print function, and it will be `console.log` when giving
80- /// `undefined` or "console", and it will be a dumb function when giving null.
81- #[ wasm_bindgen( js_name = pyEval) ]
82- pub fn eval_py ( source : & str , options : Option < Object > ) -> Result < JsValue , JsValue > {
83- run_py ( source, options, Mode :: Eval )
111+ /// Evaluate Python code
112+ ///
113+ /// ```js
114+ /// var result = pyExecSingle(code, options?);
115+ /// ```
116+ ///
117+ /// `code`: `string`: The Python code to run in exec single mode
118+ ///
119+ /// `options`: The options are the same as eval mode
120+ #[ wasm_bindgen( js_name = pyExecSingle) ]
121+ pub fn exec_single_py ( source : & str , options : Option < Object > ) -> Result < JsValue , JsValue > {
122+ run_py ( source, options, Mode :: Single )
123+ }
84124}
85125
86- /// Evaluate Python code
87- ///
88- /// ```js
89- /// pyExec(code, options?);
90- /// ```
91- ///
92- /// `code`: `string`: The Python code to run in exec mode
93- ///
94- /// `options`: The options are the same as eval mode
95- #[ wasm_bindgen( js_name = pyExec) ]
96- pub fn exec_py ( source : & str , options : Option < Object > ) -> Result < ( ) , JsValue > {
97- run_py ( source, options, Mode :: Exec ) . map ( drop)
126+ /// A module containing all the wasm-bindgen exports that rustpython_wasm has
127+ /// Re-export as `pub use rustpython_wasm::exports::*;` in the root of your crate if you want your
128+ /// wasm module to mimic rustpython_wasm's API
129+ pub mod exports {
130+ pub use crate :: convert:: PyError ;
131+ pub use crate :: eval:: { eval_py, exec_py, exec_single_py} ;
132+ pub use crate :: vm_class:: { VMStore , WASMVirtualMachine } ;
98133}
99134
100- /// Evaluate Python code
101- ///
102- /// ```js
103- /// var result = pyExecSingle(code, options?);
104- /// ```
105- ///
106- /// `code`: `string`: The Python code to run in exec single mode
107- ///
108- /// `options`: The options are the same as eval mode
109- #[ wasm_bindgen( js_name = pyExecSingle) ]
110- pub fn exec_single_py ( source : & str , options : Option < Object > ) -> Result < JsValue , JsValue > {
111- run_py ( source, options, Mode :: Single )
112- }
135+ #[ doc( hidden) ]
136+ pub use exports:: * ;
0 commit comments