@@ -7,106 +7,131 @@ 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) ]
41
+ #[ cfg( not( feature = "no-start-func" ) ) ]
38
42
#[ wasm_bindgen( start) ]
39
- pub fn setup_console_error ( ) {
43
+ pub fn _setup_console_error ( ) {
40
44
std:: panic:: set_hook ( Box :: new ( panic_hook) ) ;
41
45
}
42
46
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 ( ) ) ?;
54
73
}
55
- } ;
74
+ vm. run ( source, mode, None )
75
+ }
56
76
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
+ }
58
97
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)
61
110
}
62
- vm. run ( source, mode, None )
63
- }
64
111
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
+ }
84
125
}
85
126
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 } ;
98
134
}
99
135
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