@@ -15,32 +15,32 @@ use macros::*;
15
15
use traits:: * ;
16
16
17
17
impl DefaultRuntime {
18
- pub ( crate ) fn exec ( & self , store : & mut Store , stack : & mut Stack , module : ModuleInstance ) -> Result < ( ) > {
19
- log:: debug!( "func_addrs: {:?}" , module. func_addrs( ) ) ;
20
- log:: debug!( "func_ty_addrs: {:?}" , module. func_ty_addrs( ) . len( ) ) ;
21
- log:: debug!( "store funcs: {:?}" , store. data. funcs. len( ) ) ;
22
-
18
+ pub ( crate ) fn exec ( & self , store : & mut Store , stack : & mut Stack ) -> Result < ( ) > {
23
19
// The current call frame, gets updated inside of exec_one
24
20
let mut cf = stack. call_stack . pop ( ) ?;
25
21
26
- // The function to execute, gets updated from ExecResult::Call
27
- let mut func_inst = store. get_func ( cf. func_ptr ) ?. clone ( ) ;
22
+ let mut func_inst = cf. func_instance . clone ( ) ;
28
23
let mut wasm_func = func_inst. assert_wasm ( ) . expect ( "exec expected wasm function" ) ;
24
+
25
+ // The function to execute, gets updated from ExecResult::Call
29
26
let mut instrs = & wasm_func. instructions ;
30
27
31
- let mut current_module = module;
28
+ let mut current_module = store
29
+ . get_module_instance ( func_inst. owner )
30
+ . expect ( "exec expected module instance to exist for function" )
31
+ . clone ( ) ;
32
32
33
33
while let Some ( instr) = instrs. get ( cf. instr_ptr ) {
34
34
match exec_one ( & mut cf, instr, instrs, stack, store, & current_module) ? {
35
35
// Continue execution at the new top of the call stack
36
36
ExecResult :: Call => {
37
37
cf = stack. call_stack . pop ( ) ?;
38
- func_inst = store . get_func ( cf. func_ptr ) ? . clone ( ) ;
39
- wasm_func = func_inst. assert_wasm ( ) . expect ( "call expected wasm function" ) ;
38
+ func_inst = cf. func_instance . clone ( ) ;
39
+ wasm_func = func_inst. assert_wasm ( ) . expect ( "exec expected wasm function" ) ;
40
40
instrs = & wasm_func. instructions ;
41
41
42
- if cf. module != current_module. id ( ) {
43
- current_module. swap ( store. get_module_instance ( cf. module ) . unwrap ( ) . clone ( ) ) ;
42
+ if cf. func_instance . owner != current_module. id ( ) {
43
+ current_module. swap ( store. get_module_instance ( cf. func_instance . owner ) . unwrap ( ) . clone ( ) ) ;
44
44
}
45
45
46
46
continue ;
@@ -135,10 +135,10 @@ fn exec_one(
135
135
log:: info!( "start call" ) ;
136
136
// prepare the call frame
137
137
let func_idx = module. resolve_func_addr ( * v) ;
138
- let func_inst = store. get_func ( func_idx as usize ) ?;
138
+ let func_inst = store. get_func ( func_idx as usize ) ?. clone ( ) ;
139
139
140
- let func = match & func_inst. func {
141
- crate :: Function :: Wasm ( ref f) => f ,
140
+ let ( locals , ty ) = match & func_inst. func {
141
+ crate :: Function :: Wasm ( ref f) => ( f . locals . to_vec ( ) , f . ty . clone ( ) ) ,
142
142
crate :: Function :: Host ( host_func) => {
143
143
let func = host_func. func . clone ( ) ;
144
144
log:: info!( "Getting params: {:?}" , host_func. ty. params) ;
@@ -150,8 +150,11 @@ fn exec_one(
150
150
}
151
151
} ;
152
152
153
- let params = stack. values . pop_n_rev ( func. ty . params . len ( ) ) ?;
154
- let call_frame = CallFrame :: new_raw ( func_idx as usize , & params, func. locals . to_vec ( ) , func_inst. _owner ) ;
153
+ let params = stack. values . pop_n_rev ( ty. params . len ( ) ) ?;
154
+ log:: info!( "call: current fn owner: {:?}" , module. id( ) ) ;
155
+ log:: info!( "call: func owner: {:?}" , func_inst. owner) ;
156
+
157
+ let call_frame = CallFrame :: new_raw ( func_inst, & params, locals) ;
155
158
156
159
// push the call frame
157
160
cf. instr_ptr += 1 ; // skip the call instruction
@@ -163,29 +166,39 @@ fn exec_one(
163
166
}
164
167
165
168
CallIndirect ( type_addr, table_addr) => {
166
- let table_idx = module. resolve_table_addr ( * table_addr) ;
167
- let table = store. get_table ( table_idx as usize ) ?;
168
-
169
- // TODO: currently, the type resolution is subtlely broken for imported functions
170
-
171
- let call_ty = module. func_ty ( * type_addr) ;
172
-
173
- let func_idx = stack. values . pop_t :: < u32 > ( ) ?;
169
+ let table = store. get_table ( module. resolve_table_addr ( * table_addr) as usize ) ?;
170
+ let table_idx = stack. values . pop_t :: < u32 > ( ) ?;
174
171
175
172
// verify that the table is of the right type, this should be validated by the parser already
176
173
assert ! ( table. borrow( ) . kind. element_type == ValType :: RefFunc , "table is not of type funcref" ) ;
177
174
178
- let func_ref = table
179
- . borrow ( )
180
- . get ( func_idx as usize ) ?
181
- . addr ( )
182
- . ok_or_else ( || Trap :: UninitializedElement { index : func_idx as usize } ) ?;
175
+ let func_ref = {
176
+ table
177
+ . borrow ( )
178
+ . get ( table_idx as usize ) ?
179
+ . addr ( )
180
+ . ok_or ( Trap :: UninitializedElement { index : table_idx as usize } ) ?
181
+ } ;
183
182
184
- let func_inst = store. get_func ( func_ref as usize ) ?;
183
+ let func_inst = store. get_func ( func_ref as usize ) ?. clone ( ) ;
185
184
let func_ty = func_inst. func . ty ( ) ;
186
185
187
- let func = match & func_inst. func {
188
- crate :: Function :: Wasm ( ref f) => f,
186
+ log:: info!( "type_addr: {}" , type_addr) ;
187
+ log:: info!( "types: {:?}" , module. func_tys( ) ) ;
188
+ let call_ty = module. func_ty ( * type_addr) ;
189
+
190
+ log:: info!( "call_indirect: current fn owner: {:?}" , module. id( ) ) ;
191
+ log:: info!( "call_indirect: func owner: {:?}" , func_inst. owner) ;
192
+
193
+ if func_ty != call_ty {
194
+ log:: error!( "indirect call type mismatch: {:?} != {:?}" , func_ty, call_ty) ;
195
+ return Err (
196
+ Trap :: IndirectCallTypeMismatch { actual : func_ty. clone ( ) , expected : call_ty. clone ( ) } . into ( )
197
+ ) ;
198
+ }
199
+
200
+ let locals = match & func_inst. func {
201
+ crate :: Function :: Wasm ( ref f) => f. locals . to_vec ( ) ,
189
202
crate :: Function :: Host ( host_func) => {
190
203
let func = host_func. func . clone ( ) ;
191
204
let params = stack. values . pop_params ( & func_ty. params ) ?;
@@ -195,14 +208,8 @@ fn exec_one(
195
208
}
196
209
} ;
197
210
198
- if func_ty != call_ty {
199
- return Err (
200
- Trap :: IndirectCallTypeMismatch { actual : func_ty. clone ( ) , expected : call_ty. clone ( ) } . into ( )
201
- ) ;
202
- }
203
-
204
211
let params = stack. values . pop_n_rev ( func_ty. params . len ( ) ) ?;
205
- let call_frame = CallFrame :: new_raw ( func_ref as usize , & params, func . locals . to_vec ( ) , func_inst . _owner ) ;
212
+ let call_frame = CallFrame :: new_raw ( func_inst , & params, locals) ;
206
213
207
214
// push the call frame
208
215
cf. instr_ptr += 1 ; // skip the call instruction
0 commit comments