@@ -158,13 +158,20 @@ impl Store {
158
158
}
159
159
160
160
/// 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 > > {
162
167
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 ( ) {
165
172
self . data . globals . push ( Rc :: new ( RefCell :: new ( GlobalInstance :: new (
166
173
global. ty ,
167
- self . eval_const ( & global. init ) ?,
174
+ self . eval_const ( & global. init , & global_addrs ) ?,
168
175
idx,
169
176
) ) ) ) ;
170
177
global_addrs. push ( ( i + global_count) as Addr ) ;
@@ -173,27 +180,41 @@ impl Store {
173
180
Ok ( global_addrs)
174
181
}
175
182
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
+
176
203
/// Add elements to the store, returning their addresses in the store
177
204
/// Should be called after the tables have been added
178
205
pub ( crate ) fn init_elements (
179
206
& mut self ,
180
207
table_addrs : & [ TableAddr ] ,
181
208
func_addrs : & [ FuncAddr ] ,
209
+ global_addrs : & [ Addr ] ,
182
210
elements : Vec < Element > ,
183
211
idx : ModuleInstanceAddr ,
184
212
) -> Result < ( Box < [ Addr ] > , Option < Trap > ) > {
185
213
let elem_count = self . data . elements . len ( ) ;
186
214
let mut elem_addrs = Vec :: with_capacity ( elem_count) ;
187
215
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 < _ > > > ( ) ?;
197
218
198
219
log:: error!( "element kind: {:?}" , element. kind) ;
199
220
@@ -330,16 +351,23 @@ impl Store {
330
351
}
331
352
332
353
/// 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 > {
334
359
use tinywasm_types:: ConstInstruction :: * ;
335
360
let val = match const_instr {
336
361
F32Const ( f) => RawWasmValue :: from ( * f) ,
337
362
F64Const ( f) => RawWasmValue :: from ( * f) ,
338
363
I32Const ( i) => RawWasmValue :: from ( * i) ,
339
364
I64Const ( i) => RawWasmValue :: from ( * i) ,
340
365
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 ( ) ;
343
371
let val = global. borrow ( ) . value ;
344
372
val
345
373
}
@@ -369,8 +397,16 @@ impl Store {
369
397
self . data . elements . get ( addr) . ok_or_else ( || Error :: Other ( format ! ( "element {} not found" , addr) ) )
370
398
}
371
399
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
+
372
405
/// Get the global at the actual index in the store
373
406
pub fn get_global_val ( & self , addr : usize ) -> Result < RawWasmValue > {
407
+ log:: error!( "getting global: {}" , addr) ;
408
+ log:: error!( "globals: {:?}" , self . data. globals) ;
409
+
374
410
self . data
375
411
. globals
376
412
. get ( addr)
@@ -461,25 +497,18 @@ impl TableInstance {
461
497
}
462
498
463
499
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) )
472
501
}
473
502
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 < ( ) > {
475
504
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 ( ) ) ;
480
507
}
508
+
509
+ self . elements . resize ( new_size, TableElement :: Uninitialized ) ;
481
510
}
482
- Some ( ( ) )
511
+ Ok ( ( ) )
483
512
}
484
513
485
514
pub ( crate ) fn size ( & self ) -> i32 {
@@ -620,13 +649,13 @@ impl MemoryInstance {
620
649
#[ derive( Debug ) ]
621
650
pub ( crate ) struct GlobalInstance {
622
651
pub ( crate ) value : RawWasmValue ,
623
- pub ( crate ) _ty : GlobalType ,
652
+ pub ( crate ) ty : GlobalType ,
624
653
pub ( crate ) _owner : ModuleInstanceAddr , // index into store.module_instances
625
654
}
626
655
627
656
impl GlobalInstance {
628
657
pub ( crate ) fn new ( ty : GlobalType , value : RawWasmValue , owner : ModuleInstanceAddr ) -> Self {
629
- Self { _ty : ty, value, _owner : owner }
658
+ Self { ty, value, _owner : owner }
630
659
}
631
660
}
632
661
0 commit comments