@@ -7,106 +7,130 @@ pub mod wasm_builtins;
7
7
#[ macro_use]
8
8
extern crate rustpython_vm;
9
9
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 } ;
12
13
use std:: panic;
13
14
use wasm_bindgen:: prelude:: * ;
14
15
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;
19
17
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 ) {
21
20
// 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) ;
26
35
} ;
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) ;
36
38
}
37
39
40
+ #[ doc( hidden) ]
38
41
#[ wasm_bindgen( start) ]
39
- pub fn setup_console_error ( ) {
42
+ pub fn _setup_console_error ( ) {
40
43
std:: panic:: set_hook ( Box :: new ( panic_hook) ) ;
41
44
}
42
45
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 ( ) ) ?;
54
72
}
55
- } ;
73
+ vm. run ( source, mode, None )
74
+ }
56
75
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
+ }
58
96
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)
61
109
}
62
- vm. run ( source, mode, None )
63
- }
64
110
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
+ }
84
124
}
85
125
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 } ;
98
133
}
99
134
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