@@ -3,15 +3,16 @@ use std::{
33 fmt:: { Debug , Formatter } ,
44} ;
55
6- use tinywasm:: { Error , Result } ;
6+ use eyre:: { eyre, Result } ;
7+ use log:: debug;
78use tinywasm_types:: TinyWasmModule ;
89use wast:: {
910 lexer:: Lexer ,
1011 parser:: { self , ParseBuffer } ,
1112 QuoteWat , Wast ,
1213} ;
1314
14- fn parse_module ( mut module : wast:: core:: Module ) -> Result < TinyWasmModule , Error > {
15+ fn parse_module ( mut module : wast:: core:: Module ) -> Result < TinyWasmModule > {
1516 let parser = tinywasm_parser:: Parser :: new ( ) ;
1617 Ok ( parser. parse_module_bytes ( module. encode ( ) . expect ( "failed to encode module" ) ) ?)
1718}
@@ -27,32 +28,34 @@ fn test_mvp() -> Result<()> {
2728 let wast = wasm_testsuite:: get_test_wast ( group) . expect ( "failed to get test wast" ) ;
2829 let wast = std:: str:: from_utf8 ( & wast) . expect ( "failed to convert wast to utf8" ) ;
2930
30- let mut lexer = Lexer :: new ( & wast) ;
31+ let mut lexer = Lexer :: new ( wast) ;
3132 // we need to allow confusing unicode characters since they are technically valid wasm
3233 lexer. allow_confusing_unicode ( true ) ;
3334
3435 let buf = ParseBuffer :: new_with_lexer ( lexer) . expect ( "failed to create parse buffer" ) ;
3536 let wast_data = parser:: parse :: < Wast > ( & buf) . expect ( "failed to parse wat" ) ;
3637
38+ let mut last_module: Option < TinyWasmModule > = None ;
3739 for ( i, directive) in wast_data. directives . into_iter ( ) . enumerate ( ) {
3840 let span = directive. span ( ) ;
39-
4041 use wast:: WastDirective :: * ;
4142 let name = format ! ( "{}-{}" , group, i) ;
43+
4244 match directive {
4345 // TODO: needs to support more binary sections
4446 Wat ( QuoteWat :: Wat ( wast:: Wat :: Module ( module) ) ) => {
45- let module = std:: panic:: catch_unwind ( || parse_module ( module) ) ;
46- test_group . add_result (
47- & format ! ( "{}-parse" , name ) ,
48- span ,
49- match module {
50- Ok ( Ok ( _ ) ) => Ok ( ( ) ) ,
51- Ok ( Err ( e ) ) => Err ( e ) ,
52- Err ( e ) => Err ( Error :: Other ( format ! ( "failed to parse module: {:?}" , e ) ) ) ,
53- } ,
54- ) ;
47+ let result = std:: panic:: catch_unwind ( || parse_module ( module) )
48+ . map_err ( |e| eyre ! ( "failed to parse module: {:?}" , e ) )
49+ . and_then ( |res| res ) ;
50+
51+ match & result {
52+ Err ( _ ) => last_module = None ,
53+ Ok ( m ) => last_module = Some ( m . clone ( ) ) ,
54+ }
55+
56+ test_group . add_result ( & format ! ( "{}-parse" , name ) , span , result . map ( |_| ( ) ) ) ;
5557 }
58+
5659 // these all pass already :)
5760 AssertMalformed {
5861 span,
@@ -64,11 +67,49 @@ fn test_mvp() -> Result<()> {
6467 & format ! ( "{}-malformed" , name) ,
6568 span,
6669 match res {
67- Ok ( Ok ( _) ) => Err ( Error :: Other ( "expected module to be malformed" . to_string ( ) ) ) ,
70+ Ok ( Ok ( _) ) => Err ( eyre ! ( "expected module to be malformed" ) ) ,
6871 Err ( _) | Ok ( Err ( _) ) => Ok ( ( ) ) ,
6972 } ,
7073 ) ;
7174 }
75+ AssertReturn { span, exec, results : _ } => {
76+ let Some ( module) = last_module. as_ref ( ) else {
77+ // println!("no module found for assert_return: {:?}", exec);
78+ continue ;
79+ } ;
80+
81+ let res: Result < Result < ( ) > , _ > = std:: panic:: catch_unwind ( || {
82+ let mut store = tinywasm:: Store :: new ( ) ;
83+ let module = tinywasm:: Module :: from ( module) ;
84+ let instance = module. instantiate ( & mut store) ?;
85+
86+ use wast:: WastExecute :: * ;
87+ match exec {
88+ Wat ( _) => return Result :: Ok ( ( ) ) , // not used by the testsuite
89+ Get { module : _, global : _ } => return Result :: Ok ( ( ) ) ,
90+ Invoke ( invoke) => {
91+ for arg in invoke. args {
92+ let arg = get_tinywasm_wasm_value ( arg) ?;
93+ let _res = instance. get_func ( & store, invoke. name ) ?. call ( & mut store, & [ arg] ) ?;
94+ // TODO: check the result
95+ }
96+ }
97+ }
98+
99+ Ok ( ( ) )
100+ } ) ;
101+
102+ let res = match res {
103+ Err ( e) => Err ( eyre ! ( "test panicked: {:?}" , e) ) ,
104+ Ok ( Err ( e) ) => Err ( e) ,
105+ Ok ( Ok ( ( ) ) ) => Ok ( ( ) ) ,
106+ } ;
107+
108+ test_group. add_result ( & format ! ( "{}-return" , name) , span, res) ;
109+ }
110+ Invoke ( m) => {
111+ debug ! ( "invoke: {:?}" , m) ;
112+ }
72113 // _ => test_group.add_result(
73114 // &format!("{}-unknown", name),
74115 // span,
@@ -82,13 +123,29 @@ fn test_mvp() -> Result<()> {
82123
83124 if test_suite. failed ( ) {
84125 eprintln ! ( "\n \n failed one or more tests:\n {:#?}" , test_suite) ;
85- Err ( Error :: Other ( "failed one or more tests" . to_string ( ) ) )
126+ Err ( eyre ! ( "failed one or more tests" ) )
86127 } else {
87128 println ! ( "\n \n passed all tests:\n {:#?}" , test_suite) ;
88129 Ok ( ( ) )
89130 }
90131}
91132
133+ fn get_tinywasm_wasm_value ( arg : wast:: WastArg ) -> Result < tinywasm_types:: WasmValue > {
134+ let wast:: WastArg :: Core ( arg) = arg else {
135+ return Err ( eyre ! ( "unsupported arg type" ) ) ;
136+ } ;
137+
138+ use tinywasm_types:: WasmValue ;
139+ use wast:: core:: WastArgCore :: * ;
140+ Ok ( match arg {
141+ F32 ( f) => WasmValue :: F32 ( f32:: from_bits ( f. bits ) ) ,
142+ F64 ( f) => WasmValue :: F64 ( f64:: from_bits ( f. bits ) ) ,
143+ I32 ( i) => WasmValue :: I32 ( i) ,
144+ I64 ( i) => WasmValue :: I64 ( i) ,
145+ _ => return Err ( eyre ! ( "unsupported arg type" ) ) ,
146+ } )
147+ }
148+
92149struct TestSuite ( BTreeMap < String , TestGroup > ) ;
93150
94151impl TestSuite {
0 commit comments