@@ -3,9 +3,12 @@ extern crate eel_wasm;
33use std:: { collections:: HashMap , io} ;
44
55use eel_wasm:: compile;
6+ use wasmi:: nan_preserving_float:: F64 ;
7+ use wasmi:: RuntimeValue ;
68use wasmi:: {
7- nan_preserving_float:: F64 , Error as WasmiError , GlobalDescriptor , GlobalInstance , GlobalRef ,
8- ImportsBuilder , ModuleImportResolver , ModuleInstance , NopExternals , RuntimeValue ,
9+ Error as WasmiError , Externals , FuncInstance , FuncRef , GlobalDescriptor , GlobalInstance ,
10+ GlobalRef , ImportsBuilder , ModuleImportResolver , ModuleInstance , NopExternals , RuntimeArgs ,
11+ Signature , Trap , ValueType ,
912} ;
1013
1114fn run ( body : & [ u8 ] ) -> Result < f64 , String > {
@@ -75,6 +78,66 @@ impl ModuleImportResolver for GlobalPool {
7578 let global = GlobalInstance :: alloc ( RuntimeValue :: F64 ( F64 :: from_float ( 0.0 ) ) , true ) ;
7679 Ok ( global)
7780 }
81+ fn resolve_func ( & self , field_name : & str , signature : & Signature ) -> Result < FuncRef , WasmiError > {
82+ println ! ( "Calling function: {}" , field_name) ;
83+ let index = match field_name {
84+ "sin" => SIN_FUNC_INDEX ,
85+ _ => {
86+ return Err ( WasmiError :: Instantiation ( format ! (
87+ "Export {} not found" ,
88+ field_name
89+ ) ) )
90+ }
91+ } ;
92+
93+ if !self . check_signature ( index, signature) {
94+ return Err ( WasmiError :: Instantiation ( format ! (
95+ "Export {} has a bad signature" ,
96+ field_name
97+ ) ) ) ;
98+ }
99+
100+ println ! ( "PAssed sig check: {}" , field_name) ;
101+
102+ Ok ( FuncInstance :: alloc_host (
103+ Signature :: new ( & [ ValueType :: F64 ] [ ..] , Some ( ValueType :: F64 ) ) ,
104+ index,
105+ ) )
106+ }
107+ }
108+
109+ const SIN_FUNC_INDEX : usize = 0 ;
110+
111+ impl Externals for GlobalPool {
112+ fn invoke_index (
113+ & mut self ,
114+ index : usize ,
115+ args : RuntimeArgs ,
116+ ) -> Result < Option < RuntimeValue > , Trap > {
117+ println ! ( "Calling index {}" , index) ;
118+ match index {
119+ SIN_FUNC_INDEX => {
120+ let a: F64 = args. nth_checked ( 0 ) ?;
121+ println ! ( "First arg was {:?}" , a) ;
122+
123+ let result = a * 2 ;
124+
125+ Ok ( Some ( RuntimeValue :: F64 ( F64 :: from ( result) ) ) )
126+ }
127+ _ => panic ! ( "Unimplemented function at {}" , index) ,
128+ }
129+ }
130+ }
131+
132+ impl GlobalPool {
133+ fn check_signature ( & self , index : usize , signature : & Signature ) -> bool {
134+ println ! ( "Checking sig of {}" , index) ;
135+ let ( params, ret_ty) : ( & [ ValueType ] , Option < ValueType > ) = match index {
136+ SIN_FUNC_INDEX => ( & [ ValueType :: F64 ] , Some ( ValueType :: F64 ) ) ,
137+ _ => return false ,
138+ } ;
139+ signature. params ( ) == params && signature. return_type ( ) == ret_ty
140+ }
78141}
79142
80143#[ test]
@@ -108,6 +171,38 @@ fn with_global() {
108171 . expect ( "Ran" ) ;
109172}
110173
174+ #[ test]
175+ #[ ignore]
176+ fn with_shims ( ) {
177+ let global_imports = GlobalPool {
178+ globals : HashMap :: default ( ) ,
179+ } ;
180+ let wasm_binary = compile (
181+ vec ! [ ( "test" . to_string( ) , "sin(10)" , "pool" . to_string( ) ) ] ,
182+ vec ! [ ] ,
183+ )
184+ . expect ( "Expect to compile" ) ;
185+ // TODO: This will fail becuase wasmi 0.8.0 depends upon wasmi-validaiton
186+ // 0.3.0 which does not include https://github.com/paritytech/wasmi/pull/228
187+ // which allows mutable globals.
188+ // 0.3.1 has the PR, but wasmi has not shipped a new version that includes it.
189+ // parity-wasm already depends upon 0.3.1 (I _think_)
190+ let module = wasmi:: Module :: from_buffer ( & wasm_binary) . expect ( "No validation errors" ) ;
191+ let mut imports = ImportsBuilder :: default ( ) ;
192+ imports. push_resolver ( "pool" , & global_imports) ;
193+ imports. push_resolver ( "shims" , & global_imports) ;
194+ let instance = ModuleInstance :: new ( & module, & imports)
195+ . expect ( "failed to instantiate wasm module" )
196+ . assert_no_start ( ) ;
197+
198+ // Finally, invoke the exported function "test" with no parameters
199+ // and empty external function executor.
200+ instance
201+ . invoke_export ( "test" , & [ ] , & mut NopExternals )
202+ . expect ( "failed to execute export" )
203+ . expect ( "Ran" ) ;
204+ }
205+
111206#[ test]
112207fn multiple_functions ( ) {
113208 let wasm_binary = compile (
0 commit comments