@@ -158,13 +158,20 @@ impl Store {
158158 }
159159
160160 /// Add globals to the store, returning their addresses in the store
161- pub ( crate ) fn init_globals ( & mut self , globals : Vec < Global > , idx : ModuleInstanceAddr ) -> Result < Vec < Addr > > {
161+ pub ( crate ) fn init_globals (
162+ & mut self ,
163+ mut imported_globals : Vec < GlobalAddr > ,
164+ new_globals : Vec < Global > ,
165+ idx : ModuleInstanceAddr ,
166+ ) -> Result < Vec < Addr > > {
162167 let global_count = self . data . globals . len ( ) ;
163- let mut global_addrs = Vec :: with_capacity ( global_count) ;
164- for ( i, global) in globals. iter ( ) . enumerate ( ) {
168+ imported_globals. reserve_exact ( new_globals. len ( ) ) ;
169+ let mut global_addrs = imported_globals;
170+
171+ for ( i, global) in new_globals. iter ( ) . enumerate ( ) {
165172 self . data . globals . push ( Rc :: new ( RefCell :: new ( GlobalInstance :: new (
166173 global. ty ,
167- self . eval_const ( & global. init ) ?,
174+ self . eval_const ( & global. init , & global_addrs ) ?,
168175 idx,
169176 ) ) ) ) ;
170177 global_addrs. push ( ( i + global_count) as Addr ) ;
@@ -173,27 +180,41 @@ impl Store {
173180 Ok ( global_addrs)
174181 }
175182
183+ fn elem_addr ( & self , item : & ElementItem , globals : & [ Addr ] ) -> Result < Option < u32 > > {
184+ let res = match item {
185+ ElementItem :: Func ( addr) => Some ( * addr) ,
186+ ElementItem :: Expr ( ConstInstruction :: RefFunc ( addr) ) => Some ( * addr) ,
187+ ElementItem :: Expr ( ConstInstruction :: RefNull ( _ty) ) => None ,
188+ ElementItem :: Expr ( ConstInstruction :: GlobalGet ( addr) ) => {
189+ let addr = globals. get ( * addr as usize ) . copied ( ) . ok_or_else ( || {
190+ Error :: Other ( format ! ( "global {} not found. This should have been caught by the validator" , addr) )
191+ } ) ?;
192+
193+ let global = self . data . globals [ addr as usize ] . clone ( ) ;
194+ let val = global. borrow ( ) . value ;
195+ Some ( val. into ( ) )
196+ }
197+ _ => return Err ( Error :: UnsupportedFeature ( format ! ( "const expression other than ref: {:?}" , item) ) ) ,
198+ } ;
199+
200+ Ok ( res)
201+ }
202+
176203 /// Add elements to the store, returning their addresses in the store
177204 /// Should be called after the tables have been added
178205 pub ( crate ) fn init_elements (
179206 & mut self ,
180207 table_addrs : & [ TableAddr ] ,
181208 func_addrs : & [ FuncAddr ] ,
209+ global_addrs : & [ Addr ] ,
182210 elements : Vec < Element > ,
183211 idx : ModuleInstanceAddr ,
184212 ) -> Result < ( Box < [ Addr ] > , Option < Trap > ) > {
185213 let elem_count = self . data . elements . len ( ) ;
186214 let mut elem_addrs = Vec :: with_capacity ( elem_count) ;
187215 for ( i, element) in elements. into_iter ( ) . enumerate ( ) {
188- let init = element
189- . items
190- . iter ( )
191- . map ( |item| {
192- item. addr ( ) . ok_or_else ( || {
193- Error :: UnsupportedFeature ( format ! ( "const expression other than ref: {:?}" , item) )
194- } )
195- } )
196- . collect :: < Result < Vec < _ > > > ( ) ?;
216+ let init =
217+ element. items . iter ( ) . map ( |item| self . elem_addr ( item, global_addrs) ) . collect :: < Result < Vec < _ > > > ( ) ?;
197218
198219 log:: error!( "element kind: {:?}" , element. kind) ;
199220
@@ -330,16 +351,23 @@ impl Store {
330351 }
331352
332353 /// Evaluate a constant expression
333- pub ( crate ) fn eval_const ( & self , const_instr : & tinywasm_types:: ConstInstruction ) -> Result < RawWasmValue > {
354+ pub ( crate ) fn eval_const (
355+ & self ,
356+ const_instr : & tinywasm_types:: ConstInstruction ,
357+ module_global_addrs : & [ Addr ] ,
358+ ) -> Result < RawWasmValue > {
334359 use tinywasm_types:: ConstInstruction :: * ;
335360 let val = match const_instr {
336361 F32Const ( f) => RawWasmValue :: from ( * f) ,
337362 F64Const ( f) => RawWasmValue :: from ( * f) ,
338363 I32Const ( i) => RawWasmValue :: from ( * i) ,
339364 I64Const ( i) => RawWasmValue :: from ( * i) ,
340365 GlobalGet ( addr) => {
341- let addr = * addr as usize ;
342- let global = self . data . globals [ addr] . clone ( ) ;
366+ let addr = module_global_addrs. get ( * addr as usize ) . copied ( ) . ok_or_else ( || {
367+ Error :: Other ( format ! ( "global {} not found. This should have been caught by the validator" , addr) )
368+ } ) ?;
369+
370+ let global = self . data . globals [ addr as usize ] . clone ( ) ;
343371 let val = global. borrow ( ) . value ;
344372 val
345373 }
@@ -369,8 +397,16 @@ impl Store {
369397 self . data . elements . get ( addr) . ok_or_else ( || Error :: Other ( format ! ( "element {} not found" , addr) ) )
370398 }
371399
400+ /// Get the global at the actual index in the store
401+ pub ( crate ) fn get_global ( & self , addr : usize ) -> Result < & Rc < RefCell < GlobalInstance > > > {
402+ self . data . globals . get ( addr) . ok_or_else ( || Error :: Other ( format ! ( "global {} not found" , addr) ) )
403+ }
404+
372405 /// Get the global at the actual index in the store
373406 pub fn get_global_val ( & self , addr : usize ) -> Result < RawWasmValue > {
407+ log:: error!( "getting global: {}" , addr) ;
408+ log:: error!( "globals: {:?}" , self . data. globals) ;
409+
374410 self . data
375411 . globals
376412 . get ( addr)
@@ -461,25 +497,18 @@ impl TableInstance {
461497 }
462498
463499 pub ( crate ) fn set ( & mut self , table_idx : usize , value : Addr ) -> Result < ( ) > {
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- } )
500+ self . grow_to_fit ( table_idx + 1 ) . map ( |_| self . elements [ table_idx] = TableElement :: Initialized ( value) )
472501 }
473502
474- pub ( crate ) fn grow_to_fit ( & mut self , new_size : usize ) -> Option < ( ) > {
503+ pub ( crate ) fn grow_to_fit ( & mut self , new_size : usize ) -> Result < ( ) > {
475504 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 ;
505+ if new_size > self . kind . size_max . unwrap_or ( MAX_TABLE_SIZE ) as usize {
506+ return Err ( crate :: Trap :: TableOutOfBounds { offset : new_size, len : 1 , max : self . elements . len ( ) } . into ( ) ) ;
480507 }
508+
509+ self . elements . resize ( new_size, TableElement :: Uninitialized ) ;
481510 }
482- Some ( ( ) )
511+ Ok ( ( ) )
483512 }
484513
485514 pub ( crate ) fn size ( & self ) -> i32 {
@@ -620,13 +649,13 @@ impl MemoryInstance {
620649#[ derive( Debug ) ]
621650pub ( crate ) struct GlobalInstance {
622651 pub ( crate ) value : RawWasmValue ,
623- pub ( crate ) _ty : GlobalType ,
652+ pub ( crate ) ty : GlobalType ,
624653 pub ( crate ) _owner : ModuleInstanceAddr , // index into store.module_instances
625654}
626655
627656impl GlobalInstance {
628657 pub ( crate ) fn new ( ty : GlobalType , value : RawWasmValue , owner : ModuleInstanceAddr ) -> Self {
629- Self { _ty : ty, value, _owner : owner }
658+ Self { ty, value, _owner : owner }
630659 }
631660}
632661
0 commit comments