@@ -429,6 +429,8 @@ impl TableElement {
429
429
}
430
430
}
431
431
432
+ const MAX_TABLE_SIZE : u32 = 10000000 ;
433
+
432
434
/// A WebAssembly Table Instance
433
435
///
434
436
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#table-instances>
@@ -459,28 +461,42 @@ impl TableInstance {
459
461
}
460
462
461
463
pub ( crate ) fn set ( & mut self , table_idx : usize , value : Addr ) -> Result < ( ) > {
462
- let el = self
463
- . elements
464
- . get_mut ( table_idx)
465
- . ok_or_else ( || Error :: Other ( format ! ( "table element {} not found" , table_idx) ) ) ?;
466
- * el = TableElement :: Initialized ( value) ;
467
- Ok ( ( ) )
464
+ self . grow_to_fit ( table_idx + 1 )
465
+ . ok_or_else ( || {
466
+ Error :: Trap ( crate :: Trap :: TableOutOfBounds { offset : table_idx, len : 1 , max : self . elements . len ( ) } )
467
+ } )
468
+ . and_then ( |_| {
469
+ self . elements [ table_idx] = TableElement :: Initialized ( value) ;
470
+ Ok ( ( ) )
471
+ } )
472
+ }
473
+
474
+ pub ( crate ) fn grow_to_fit ( & mut self , new_size : usize ) -> Option < ( ) > {
475
+ if new_size > self . elements . len ( ) {
476
+ if new_size <= self . kind . size_max . unwrap_or ( MAX_TABLE_SIZE ) as usize {
477
+ self . elements . resize ( new_size, TableElement :: Uninitialized ) ;
478
+ } else {
479
+ return None ;
480
+ }
481
+ }
482
+ Some ( ( ) )
468
483
}
469
484
470
485
pub ( crate ) fn size ( & self ) -> i32 {
471
486
self . elements . len ( ) as i32
472
487
}
473
488
474
- pub ( crate ) fn init ( & mut self , func_addrs : & [ u32 ] , offset : i32 , init : & [ Addr ] ) -> Result < ( ) > {
489
+ pub ( crate ) fn init ( & mut self , func_addrs : & [ u32 ] , offset : i32 , init : & [ Option < Addr > ] ) -> Result < ( ) > {
475
490
let init = init
476
491
. iter ( )
477
- . map ( |item| {
478
- TableElement :: Initialized ( match self . kind . element_type == ValType :: RefFunc {
492
+ . map ( |item| match item {
493
+ None => TableElement :: Uninitialized ,
494
+ Some ( item) => TableElement :: Initialized ( match self . kind . element_type == ValType :: RefFunc {
479
495
true => * func_addrs. get ( * item as usize ) . expect (
480
496
"error initializing table: function not found. This should have been caught by the validator" ,
481
497
) ,
482
498
false => * item,
483
- } )
499
+ } ) ,
484
500
} )
485
501
. collect :: < Vec < _ > > ( ) ;
486
502
@@ -620,12 +636,12 @@ impl GlobalInstance {
620
636
#[ derive( Debug ) ]
621
637
pub ( crate ) struct ElementInstance {
622
638
pub ( crate ) kind : ElementKind ,
623
- pub ( crate ) items : Option < Vec < u32 > > , // none is the element was dropped
624
- _owner : ModuleInstanceAddr , // index into store.module_instances
639
+ pub ( crate ) items : Option < Vec < Option < u32 > > > , // none is the element was dropped
640
+ _owner : ModuleInstanceAddr , // index into store.module_instances
625
641
}
626
642
627
643
impl ElementInstance {
628
- pub ( crate ) fn new ( kind : ElementKind , owner : ModuleInstanceAddr , items : Option < Vec < u32 > > ) -> Self {
644
+ pub ( crate ) fn new ( kind : ElementKind , owner : ModuleInstanceAddr , items : Option < Vec < Option < u32 > > > ) -> Self {
629
645
Self { kind, _owner : owner, items }
630
646
}
631
647
}
0 commit comments