@@ -429,6 +429,8 @@ impl TableElement {
429429 }
430430}
431431
432+ const MAX_TABLE_SIZE : u32 = 10000000 ;
433+
432434/// A WebAssembly Table Instance
433435///
434436/// See <https://webassembly.github.io/spec/core/exec/runtime.html#table-instances>
@@ -459,28 +461,42 @@ impl TableInstance {
459461 }
460462
461463 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 ( ( ) )
468483 }
469484
470485 pub ( crate ) fn size ( & self ) -> i32 {
471486 self . elements . len ( ) as i32
472487 }
473488
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 < ( ) > {
475490 let init = init
476491 . 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 {
479495 true => * func_addrs. get ( * item as usize ) . expect (
480496 "error initializing table: function not found. This should have been caught by the validator" ,
481497 ) ,
482498 false => * item,
483- } )
499+ } ) ,
484500 } )
485501 . collect :: < Vec < _ > > ( ) ;
486502
@@ -620,12 +636,12 @@ impl GlobalInstance {
620636#[ derive( Debug ) ]
621637pub ( crate ) struct ElementInstance {
622638 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
625641}
626642
627643impl 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 {
629645 Self { kind, _owner : owner, items }
630646 }
631647}
0 commit comments