11mod wasm_builtins;
22
3+ extern crate js_sys;
4+ extern crate num_bigint;
35extern crate rustpython_vm;
46extern crate wasm_bindgen;
57extern crate web_sys;
68
7- use rustpython_vm :: VirtualMachine ;
9+ use num_bigint :: BigInt ;
810use rustpython_vm:: compile;
9- use rustpython_vm:: pyobject:: AttributeProtocol ;
11+ use rustpython_vm:: pyobject:: { self , IdProtocol , PyObjectRef , PyResult } ;
12+ use rustpython_vm:: VirtualMachine ;
1013use wasm_bindgen:: prelude:: * ;
1114use web_sys:: console;
1215
16+ fn py_str_err ( vm : & mut VirtualMachine , py_err : & PyObjectRef ) -> String {
17+ vm. to_pystr ( & py_err)
18+ . unwrap_or_else ( |_| "Error, and error getting error message" . into ( ) )
19+ }
20+
21+ fn py_to_js ( vm : & mut VirtualMachine , py_obj : & PyObjectRef ) -> JsValue {
22+ use pyobject:: PyObjectKind ;
23+ let py_obj = py_obj. borrow ( ) ;
24+ match py_obj. kind {
25+ PyObjectKind :: String { ref value } => value. into ( ) ,
26+ PyObjectKind :: Integer { ref value } => {
27+ if let Some ( ref typ) = py_obj. typ {
28+ if typ. is ( & vm. ctx . bool_type ( ) ) {
29+ let out_bool = value == & BigInt :: new ( num_bigint:: Sign :: Plus , vec ! [ 1 ] ) ;
30+ return out_bool. into ( ) ;
31+ }
32+ }
33+ let int = vm. ctx . new_int ( value. clone ( ) ) ;
34+ rustpython_vm:: obj:: objfloat:: make_float ( vm, & int)
35+ . unwrap ( )
36+ . into ( )
37+ }
38+ PyObjectKind :: Float { ref value } => JsValue :: from_f64 ( * value) ,
39+ PyObjectKind :: Bytes { ref value } => {
40+ let arr = js_sys:: Uint8Array :: new ( & JsValue :: from ( value. len ( ) as u32 ) ) ;
41+ for ( i, byte) in value. iter ( ) . enumerate ( ) {
42+ console:: log_1 ( & JsValue :: from ( i as u32 ) ) ;
43+ js_sys:: Reflect :: set ( & arr, & JsValue :: from ( i as u32 ) , & JsValue :: from ( * byte) )
44+ . unwrap ( ) ;
45+ }
46+ arr. into ( )
47+ }
48+ PyObjectKind :: Sequence { ref elements } => {
49+ let arr = js_sys:: Array :: new ( ) ;
50+ for val in elements {
51+ arr. push ( & py_to_js ( vm, val) ) ;
52+ }
53+ arr. into ( )
54+ }
55+ PyObjectKind :: Dict { ref elements } => {
56+ let obj = js_sys:: Object :: new ( ) ;
57+ for ( key, ( _, val) ) in elements {
58+ js_sys:: Reflect :: set ( & obj, & key. into ( ) , & py_to_js ( vm, val) )
59+ . expect ( "couldn't set property of object" ) ;
60+ }
61+ obj. into ( )
62+ }
63+ PyObjectKind :: None => JsValue :: UNDEFINED ,
64+ _ => JsValue :: UNDEFINED ,
65+ }
66+ }
67+
68+ fn eval ( vm : & mut VirtualMachine , source : & str ) -> PyResult {
69+ let code_obj = compile:: compile ( vm, & source. to_string ( ) , compile:: Mode :: Exec , None ) ?;
70+
71+ let builtins = vm. get_builtin_scope ( ) ;
72+ let vars = vm. context ( ) . new_scope ( Some ( builtins) ) ;
73+ vm. run_code_obj ( code_obj, vars)
74+ }
75+
76+ #[ wasm_bindgen]
77+ pub fn eval_py ( source : & str ) -> Result < JsValue , JsValue > {
78+ let mut vm = VirtualMachine :: new ( ) ;
79+
80+ vm. ctx . set_attr (
81+ & vm. builtins ,
82+ "print" ,
83+ vm. context ( ) . new_rustfunc ( wasm_builtins:: builtin_log) ,
84+ ) ;
85+
86+ eval ( & mut vm, source)
87+ . map ( |value| py_to_js ( & mut vm, & value) )
88+ . map_err ( |err| py_str_err ( & mut vm, & err) . into ( ) )
89+ }
90+
1391#[ wasm_bindgen]
14- pub fn run_code ( source : & str ) -> ( ) {
92+ pub fn run_code ( source : & str ) -> Result < JsValue , JsValue > {
1593 //add hash in here
1694 console:: log_1 ( & "Running RustPython" . into ( ) ) ;
1795 console:: log_1 ( & "Running code:" . into ( ) ) ;
@@ -20,14 +98,28 @@ pub fn run_code(source: &str) -> () {
2098 let mut vm = VirtualMachine :: new ( ) ;
2199 // We are monkey-patching the builtin print to use console.log
22100 // TODO: moneky-patch sys.stdout instead, after print actually uses sys.stdout
23- vm. builtins . set_attr ( "print" , vm. context ( ) . new_rustfunc ( wasm_builtins:: builtin_print) ) ;
24-
25- let code_obj = compile:: compile ( & mut vm, & source. to_string ( ) , compile:: Mode :: Exec , None ) ;
101+ vm. ctx . set_attr (
102+ & vm. builtins ,
103+ "print" ,
104+ vm. context ( ) . new_rustfunc ( wasm_builtins:: builtin_print) ,
105+ ) ;
26106
27- let builtins = vm. get_builtin_scope ( ) ;
28- let vars = vm. context ( ) . new_scope ( Some ( builtins) ) ;
29- match vm. run_code_obj ( code_obj. unwrap ( ) , vars) {
30- Ok ( _value) => console:: log_1 ( & "Execution successful" . into ( ) ) ,
31- Err ( _) => console:: log_1 ( & "Execution failed" . into ( ) ) ,
107+ match eval ( & mut vm, source) {
108+ Ok ( value) => {
109+ console:: log_1 ( & "Execution successful" . into ( ) ) ;
110+ match value. borrow ( ) . kind {
111+ pyobject:: PyObjectKind :: None => { }
112+ _ => {
113+ if let Ok ( text) = vm. to_pystr ( & value) {
114+ wasm_builtins:: print_to_html ( & text) ;
115+ }
116+ }
117+ }
118+ Ok ( JsValue :: UNDEFINED )
119+ }
120+ Err ( err) => {
121+ console:: log_1 ( & "Execution failed" . into ( ) ) ;
122+ Err ( py_str_err ( & mut vm, & err) . into ( ) )
123+ }
32124 }
33125}
0 commit comments