@@ -82,7 +82,6 @@ impl Default for Store {
82
82
///
83
83
/// Data should only be addressable by the module that owns it
84
84
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#store>
85
- // TODO: Arena allocate these?
86
85
pub ( crate ) struct StoreData {
87
86
pub ( crate ) funcs : Vec < Rc < FunctionInstance > > ,
88
87
pub ( crate ) tables : Vec < Rc < RefCell < TableInstance > > > ,
@@ -178,6 +177,7 @@ impl Store {
178
177
pub ( crate ) fn init_elements (
179
178
& mut self ,
180
179
table_addrs : & [ TableAddr ] ,
180
+ func_addrs : & [ FuncAddr ] ,
181
181
elements : Vec < Element > ,
182
182
idx : ModuleInstanceAddr ,
183
183
) -> Result < Box < [ Addr ] > > {
@@ -194,6 +194,8 @@ impl Store {
194
194
} )
195
195
. collect :: < Result < Vec < _ > > > ( ) ?;
196
196
197
+ log:: error!( "element kind: {:?}" , element. kind) ;
198
+
197
199
let items = match element. kind {
198
200
// doesn't need to be initialized, can be initialized lazily using the `table.init` instruction
199
201
ElementKind :: Passive => Some ( init) ,
@@ -218,7 +220,7 @@ impl Store {
218
220
// d. Execute the instruction i32.const n
219
221
// e. Execute the instruction table.init tableidx i
220
222
if let Some ( table) = self . data . tables . get_mut ( table_addr as usize ) {
221
- table. borrow_mut ( ) . init ( offset, & init) ?;
223
+ table. borrow_mut ( ) . init ( func_addrs , offset, & init) ?;
222
224
} else {
223
225
log:: error!( "table {} not found" , table) ;
224
226
}
@@ -385,8 +387,6 @@ impl Store {
385
387
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#function-instances>
386
388
pub struct FunctionInstance {
387
389
pub ( crate ) func : Function ,
388
-
389
- // TODO: this is important for call_indirect
390
390
pub ( crate ) _type_idx : TypeAddr ,
391
391
pub ( crate ) _owner : ModuleInstanceAddr , // index into store.module_instances, none for host functions
392
392
}
@@ -408,52 +408,77 @@ impl FunctionInstance {
408
408
}
409
409
}
410
410
411
+ #[ derive( Debug , Clone , Copy ) ]
412
+ pub ( crate ) enum TableElement {
413
+ Uninitialized ,
414
+ Initialized ( Addr ) ,
415
+ }
416
+
417
+ impl TableElement {
418
+ pub ( crate ) fn addr ( & self ) -> Option < Addr > {
419
+ match self {
420
+ TableElement :: Uninitialized => None ,
421
+ TableElement :: Initialized ( addr) => Some ( * addr) ,
422
+ }
423
+ }
424
+ }
425
+
411
426
/// A WebAssembly Table Instance
412
427
///
413
428
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#table-instances>
414
429
#[ derive( Debug ) ]
415
430
pub ( crate ) struct TableInstance {
416
- pub ( crate ) elements : Vec < Option < Addr > > ,
431
+ pub ( crate ) elements : Vec < TableElement > ,
417
432
pub ( crate ) kind : TableType ,
418
433
pub ( crate ) _owner : ModuleInstanceAddr , // index into store.module_instances
419
434
}
420
435
421
436
impl TableInstance {
422
437
pub ( crate ) fn new ( kind : TableType , owner : ModuleInstanceAddr ) -> Self {
423
- Self { elements : vec ! [ None ; kind. size_initial as usize ] , kind, _owner : owner }
438
+ Self { elements : vec ! [ TableElement :: Uninitialized ; kind. size_initial as usize ] , kind, _owner : owner }
424
439
}
425
440
426
441
pub ( crate ) fn get_wasm_val ( & self , addr : usize ) -> Result < WasmValue > {
442
+ let val = self . get ( addr) ?. addr ( ) ;
443
+
427
444
Ok ( match self . kind . element_type {
428
- ValType :: RefFunc => {
429
- self . get ( addr) ?. map ( |v| WasmValue :: RefFunc ( v) ) . unwrap_or ( WasmValue :: RefNull ( ValType :: RefFunc ) )
430
- }
445
+ ValType :: RefFunc => val. map ( |v| WasmValue :: RefFunc ( v) ) . unwrap_or ( WasmValue :: RefNull ( ValType :: RefFunc ) ) ,
431
446
ValType :: RefExtern => {
432
- self . get ( addr ) ? . map ( |v| WasmValue :: RefExtern ( v) ) . unwrap_or ( WasmValue :: RefNull ( ValType :: RefExtern ) )
447
+ val . map ( |v| WasmValue :: RefExtern ( v) ) . unwrap_or ( WasmValue :: RefNull ( ValType :: RefExtern ) )
433
448
}
434
449
_ => unimplemented ! ( "unsupported table type: {:?}" , self . kind. element_type) ,
435
450
} )
436
451
}
437
452
438
- pub ( crate ) fn get ( & self , addr : usize ) -> Result < Option < Addr > > {
439
- self . elements . get ( addr) . copied ( ) . ok_or_else ( || Error :: Trap ( Trap :: UndefinedElement { index : addr } ) )
453
+ pub ( crate ) fn get ( & self , addr : usize ) -> Result < & TableElement > {
454
+ self . elements . get ( addr) . ok_or_else ( || Error :: Trap ( Trap :: UndefinedElement { index : addr } ) )
440
455
}
441
456
442
- pub ( crate ) fn set ( & mut self , addr : usize , value : Addr ) -> Result < ( ) > {
443
- if addr > = self . elements . len ( ) {
444
- return Err ( Error :: Other ( format ! ( "table element {} not found" , addr ) ) ) ;
445
- }
446
-
447
- self . elements [ addr ] = Some ( value) ;
457
+ pub ( crate ) fn set ( & mut self , table_idx : usize , value : Addr ) -> Result < ( ) > {
458
+ let el = self
459
+ . elements
460
+ . get_mut ( table_idx )
461
+ . ok_or_else ( || Error :: Other ( format ! ( "table element {} not found" , table_idx ) ) ) ? ;
462
+ * el = TableElement :: Initialized ( value) ;
448
463
Ok ( ( ) )
449
464
}
450
465
451
466
pub ( crate ) fn size ( & self ) -> i32 {
452
467
self . elements . len ( ) as i32
453
468
}
454
469
455
- pub ( crate ) fn init ( & mut self , offset : i32 , init : & [ Addr ] ) -> Result < ( ) > {
456
- let init = init. iter ( ) . map ( |item| Some ( * item) ) . collect :: < Vec < _ > > ( ) ;
470
+ pub ( crate ) fn init ( & mut self , func_addrs : & [ u32 ] , offset : i32 , init : & [ Addr ] ) -> Result < ( ) > {
471
+ let init = init
472
+ . iter ( )
473
+ . map ( |item| {
474
+ TableElement :: Initialized ( match self . kind . element_type == ValType :: RefFunc {
475
+ true => * func_addrs. get ( * item as usize ) . expect (
476
+ "error initializing table: function not found. This should have been caught by the validator" ,
477
+ ) ,
478
+ false => * item,
479
+ } )
480
+ } )
481
+ . collect :: < Vec < _ > > ( ) ;
457
482
458
483
let offset = offset as usize ;
459
484
let end = offset. checked_add ( init. len ( ) ) . ok_or_else ( || {
@@ -465,6 +490,7 @@ impl TableInstance {
465
490
}
466
491
467
492
self . elements [ offset..end] . copy_from_slice ( & init) ;
493
+ log:: debug!( "table: {:?}" , self . elements) ;
468
494
Ok ( ( ) )
469
495
}
470
496
}
0 commit comments