@@ -12,7 +12,7 @@ use rustpython_vm::pyobject::{
1212use rustpython_vm:: VirtualMachine ;
1313use rustpython_vm:: { exceptions, py_serde} ;
1414
15- use crate :: browser_module ;
15+ use crate :: js_module ;
1616use crate :: vm_class:: { stored_vm_from_wasm, WASMVirtualMachine } ;
1717
1818#[ wasm_bindgen( inline_js = r"
@@ -35,10 +35,25 @@ extern "C" {
3535}
3636
3737pub fn py_err_to_js_err ( vm : & VirtualMachine , py_err : & PyBaseExceptionRef ) -> JsValue {
38- let res = serde_wasm_bindgen:: to_value ( & exceptions:: SerializeException :: new ( vm, py_err) ) ;
39- match res {
40- Ok ( err_info) => PyError :: new ( err_info) . into ( ) ,
41- Err ( e) => e. into ( ) ,
38+ let jserr = vm. try_class ( "_js" , "JSError" ) . ok ( ) ;
39+ let js_arg = if jserr. map_or ( false , |jserr| py_err. isinstance ( & jserr) ) {
40+ py_err. get_arg ( 0 )
41+ } else {
42+ None
43+ } ;
44+ let js_arg = js_arg
45+ . as_ref ( )
46+ . and_then ( |x| x. payload :: < js_module:: PyJsValue > ( ) ) ;
47+ match js_arg {
48+ Some ( val) => val. value . clone ( ) ,
49+ None => {
50+ let res =
51+ serde_wasm_bindgen:: to_value ( & exceptions:: SerializeException :: new ( vm, py_err) ) ;
52+ match res {
53+ Ok ( err_info) => PyError :: new ( err_info) . into ( ) ,
54+ Err ( e) => e. into ( ) ,
55+ }
56+ }
4257 }
4358}
4459
@@ -74,37 +89,42 @@ pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue {
7489 } ;
7590 let weak_py_obj = wasm_vm. push_held_rc ( py_obj) . unwrap ( ) ;
7691
77- let closure =
78- move |args : Option < Array > , kwargs : Option < Object > | -> Result < JsValue , JsValue > {
79- let py_obj = match wasm_vm. assert_valid ( ) {
80- Ok ( _) => weak_py_obj
81- . upgrade ( )
82- . expect ( "weak_py_obj to be valid if VM is valid" ) ,
83- Err ( err) => {
84- return Err ( err) ;
85- }
92+ let closure = move |args : Option < Box < [ JsValue ] > > ,
93+ kwargs : Option < Object > |
94+ -> Result < JsValue , JsValue > {
95+ let py_obj = match wasm_vm. assert_valid ( ) {
96+ Ok ( _) => weak_py_obj
97+ . upgrade ( )
98+ . expect ( "weak_py_obj to be valid if VM is valid" ) ,
99+ Err ( err) => {
100+ return Err ( err) ;
101+ }
102+ } ;
103+ stored_vm_from_wasm ( & wasm_vm) . interp . enter ( move |vm| {
104+ let args = match args {
105+ Some ( args) => Vec :: from ( args)
106+ . into_iter ( )
107+ . map ( |arg| js_to_py ( vm, arg) )
108+ . collect :: < Vec < _ > > ( ) ,
109+ None => Vec :: new ( ) ,
86110 } ;
87- stored_vm_from_wasm ( & wasm_vm) . interp . enter ( move |vm| {
88- let mut py_func_args = FuncArgs :: default ( ) ;
89- if let Some ( ref args) = args {
90- for arg in args. values ( ) {
91- py_func_args. args . push ( js_to_py ( vm, arg?) ) ;
92- }
111+ let mut py_func_args = FuncArgs :: from ( args) ;
112+ if let Some ( ref kwargs) = kwargs {
113+ for pair in object_entries ( kwargs) {
114+ let ( key, val) = pair?;
115+ py_func_args
116+ . kwargs
117+ . insert ( js_sys:: JsString :: from ( key) . into ( ) , js_to_py ( vm, val) ) ;
93118 }
94- if let Some ( ref kwargs) = kwargs {
95- for pair in object_entries ( kwargs) {
96- let ( key, val) = pair?;
97- py_func_args
98- . kwargs
99- . insert ( js_sys:: JsString :: from ( key) . into ( ) , js_to_py ( vm, val) ) ;
100- }
101- }
102- let result = vm. invoke ( & py_obj, py_func_args) ;
103- pyresult_to_jsresult ( vm, result)
104- } )
105- } ;
119+ }
120+ let result = vm. invoke ( & py_obj, py_func_args) ;
121+ pyresult_to_jsresult ( vm, result)
122+ } )
123+ } ;
106124 let closure = Closure :: wrap ( Box :: new ( closure)
107- as Box < dyn FnMut ( Option < Array > , Option < Object > ) -> Result < JsValue , JsValue > > ) ;
125+ as Box <
126+ dyn FnMut ( Option < Box < [ JsValue ] > > , Option < Object > ) -> Result < JsValue , JsValue > ,
127+ > ) ;
108128 let func = closure. as_ref ( ) . clone ( ) ;
109129
110130 // stores pretty much nothing, it's fine to leak this because if it gets dropped
@@ -115,8 +135,8 @@ pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue {
115135 }
116136 }
117137 // the browser module might not be injected
118- if vm. try_class ( "browser " , "Promise" ) . is_ok ( ) {
119- if let Some ( py_prom) = py_obj. payload :: < browser_module :: PyPromise > ( ) {
138+ if vm. try_class ( "_js " , "Promise" ) . is_ok ( ) {
139+ if let Some ( py_prom) = py_obj. payload :: < js_module :: PyPromise > ( ) {
120140 return py_prom. value ( ) . into ( ) ;
121141 }
122142 }
@@ -157,7 +177,7 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
157177 if let Some ( promise) = js_val. dyn_ref :: < Promise > ( ) {
158178 // the browser module might not be injected
159179 if vm. try_class ( "browser" , "Promise" ) . is_ok ( ) {
160- return browser_module :: PyPromise :: new ( promise. clone ( ) )
180+ return js_module :: PyPromise :: new ( promise. clone ( ) )
161181 . into_ref ( vm)
162182 . into_object ( ) ;
163183 }
@@ -205,10 +225,11 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
205225 Reflect :: set ( & this, & k. into ( ) , & py_to_js ( vm, v) )
206226 . expect ( "property to be settable" ) ;
207227 }
208- let js_args = Array :: new ( ) ;
209- for v in args. args {
210- js_args. push ( & py_to_js ( vm, v) ) ;
211- }
228+ let js_args = args
229+ . args
230+ . into_iter ( )
231+ . map ( |v| py_to_js ( vm, v) )
232+ . collect :: < Array > ( ) ;
212233 func. apply ( & this, & js_args)
213234 . map ( |val| js_to_py ( vm, val) )
214235 . map_err ( |err| js_err_to_py_err ( vm, & err) )
0 commit comments