@@ -7,106 +7,131 @@ 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) ]
41+ #[ cfg( not( feature = "no-start-func" ) ) ]
3842#[ wasm_bindgen( start) ]
39- pub fn setup_console_error ( ) {
43+ pub fn _setup_console_error ( ) {
4044 std:: panic:: set_hook ( Box :: new ( panic_hook) ) ;
4145}
4246
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 ( ) ) ;
47+ pub mod eval {
48+ use crate :: vm_class:: VMStore ;
49+ use js_sys:: { Object , Reflect , TypeError } ;
50+ use rustpython_vm:: compile:: Mode ;
51+ use wasm_bindgen:: prelude:: * ;
52+
53+ const PY_EVAL_VM_ID : & str = "__py_eval_vm" ;
54+
55+ fn run_py ( source : & str , options : Option < Object > , mode : Mode ) -> Result < JsValue , JsValue > {
56+ let vm = VMStore :: init ( PY_EVAL_VM_ID . into ( ) , Some ( true ) ) ;
57+ let options = options. unwrap_or_else ( Object :: new) ;
58+ let js_vars = {
59+ let prop = Reflect :: get ( & options, & "vars" . into ( ) ) ?;
60+ if prop. is_undefined ( ) {
61+ None
62+ } else if prop. is_object ( ) {
63+ Some ( Object :: from ( prop) )
64+ } else {
65+ return Err ( TypeError :: new ( "vars must be an object" ) . into ( ) ) ;
66+ }
67+ } ;
68+
69+ vm. set_stdout ( Reflect :: get ( & options, & "stdout" . into ( ) ) ?) ?;
70+
71+ if let Some ( js_vars) = js_vars {
72+ vm. add_to_scope ( "js_vars" . into ( ) , js_vars. into ( ) ) ?;
5473 }
55- } ;
74+ vm. run ( source, mode, None )
75+ }
5676
57- vm. set_stdout ( Reflect :: get ( & options, & "stdout" . into ( ) ) ?) ?;
77+ /// Evaluate Python code
78+ ///
79+ /// ```js
80+ /// var result = pyEval(code, options?);
81+ /// ```
82+ ///
83+ /// `code`: `string`: The Python code to run in eval mode
84+ ///
85+ /// `options`:
86+ ///
87+ /// - `vars?`: `{ [key: string]: any }`: Variables passed to the VM that can be
88+ /// accessed in Python with the variable `js_vars`. Functions do work, and
89+ /// receive the Python kwargs as the `this` argument.
90+ /// - `stdout?`: `"console" | ((out: string) => void) | null`: A function to replace the
91+ /// native print native print function, and it will be `console.log` when giving
92+ /// `undefined` or "console", and it will be a dumb function when giving null.
93+ #[ wasm_bindgen( js_name = pyEval) ]
94+ pub fn eval_py ( source : & str , options : Option < Object > ) -> Result < JsValue , JsValue > {
95+ run_py ( source, options, Mode :: Eval )
96+ }
5897
59- if let Some ( js_vars) = js_vars {
60- vm. add_to_scope ( "js_vars" . into ( ) , js_vars. into ( ) ) ?;
98+ /// Evaluate Python code
99+ ///
100+ /// ```js
101+ /// pyExec(code, options?);
102+ /// ```
103+ ///
104+ /// `code`: `string`: The Python code to run in exec mode
105+ ///
106+ /// `options`: The options are the same as eval mode
107+ #[ wasm_bindgen( js_name = pyExec) ]
108+ pub fn exec_py ( source : & str , options : Option < Object > ) -> Result < ( ) , JsValue > {
109+ run_py ( source, options, Mode :: Exec ) . map ( drop)
61110 }
62- vm. run ( source, mode, None )
63- }
64111
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 )
112+ /// Evaluate Python code
113+ ///
114+ /// ```js
115+ /// var result = pyExecSingle(code, options?);
116+ /// ```
117+ ///
118+ /// `code`: `string`: The Python code to run in exec single mode
119+ ///
120+ /// `options`: The options are the same as eval mode
121+ #[ wasm_bindgen( js_name = pyExecSingle) ]
122+ pub fn exec_single_py ( source : & str , options : Option < Object > ) -> Result < JsValue , JsValue > {
123+ run_py ( source, options, Mode :: Single )
124+ }
84125}
85126
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)
127+ /// A module containing all the wasm-bindgen exports that rustpython_wasm has
128+ /// Re-export as `pub use rustpython_wasm::exports::*;` in the root of your crate if you want your
129+ /// wasm module to mimic rustpython_wasm's API
130+ pub mod exports {
131+ pub use crate :: convert:: PyError ;
132+ pub use crate :: eval:: { eval_py, exec_py, exec_single_py} ;
133+ pub use crate :: vm_class:: { VMStore , WASMVirtualMachine } ;
98134}
99135
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- }
136+ #[ doc( hidden) ]
137+ pub use exports:: * ;
0 commit comments