@@ -3,9 +3,12 @@ extern crate eel_wasm;
3
3
use std:: { collections:: HashMap , io} ;
4
4
5
5
use eel_wasm:: compile;
6
+ use wasmi:: nan_preserving_float:: F64 ;
7
+ use wasmi:: RuntimeValue ;
6
8
use 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 ,
9
12
} ;
10
13
11
14
fn run ( body : & [ u8 ] ) -> Result < f64 , String > {
@@ -75,6 +78,66 @@ impl ModuleImportResolver for GlobalPool {
75
78
let global = GlobalInstance :: alloc ( RuntimeValue :: F64 ( F64 :: from_float ( 0.0 ) ) , true ) ;
76
79
Ok ( global)
77
80
}
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
+ }
78
141
}
79
142
80
143
#[ test]
@@ -108,6 +171,38 @@ fn with_global() {
108
171
. expect ( "Ran" ) ;
109
172
}
110
173
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
+
111
206
#[ test]
112
207
fn multiple_functions ( ) {
113
208
let wasm_binary = compile (
0 commit comments