MCPcopy Index your code
hub / github.com/explodingcamera/tinywasm / init_elements

Method init_elements

crates/tinywasm/src/store/mod.rs:415–470  ·  view source on GitHub ↗

Add elements to the store, returning their addresses in the store Should be called after the tables have been added

(
        &mut self,
        table_addrs: &[TableAddr],
        func_addrs: &[FuncAddr],
        global_addrs: &[Addr],
        elements: &[Element],
    )

Source from the content-addressed store, hash-verified

413 /// Add elements to the store, returning their addresses in the store
414 /// Should be called after the tables have been added
415 pub(crate) fn init_elements(
416 &mut self,
417 table_addrs: &[TableAddr],
418 func_addrs: &[FuncAddr],
419 global_addrs: &[Addr],
420 elements: &[Element],
421 ) -> Result<(Box<[Addr]>, Option<Trap>)> {
422 let elem_count = self.state.elements.len();
423 let mut elem_addrs = Vec::with_capacity(elem_count);
424 for (i, element) in elements.iter().enumerate() {
425 let init = element
426 .items
427 .iter()
428 .map(|item| Ok(TableElement::from(self.elem_addr(item, global_addrs, func_addrs)?)))
429 .collect::<Result<Vec<_>>>()?;
430
431 let items = match &element.kind {
432 // doesn't need to be initialized, can be initialized lazily using the `table.init` instruction
433 ElementKind::Passive => Some(init),
434
435 // this one is not available to the runtime but needs to be initialized to declare references
436 ElementKind::Declared => None, // a. Execute the instruction elm.drop i
437
438 // this one is active, so we need to initialize it (essentially a `table.init` instruction)
439 ElementKind::Active { offset, table } => {
440 let offset = self.eval_size_const(offset, global_addrs, func_addrs)?;
441 let table_addr = table_addrs
442 .get(*table as usize)
443 .copied()
444 .ok_or_else(|| Error::Other(format!("table {table} not found for element {i}")))?;
445
446 let Some(table) = self.state.tables.get_mut(table_addr as usize) else {
447 return Err(Error::Other(format!("table {table} not found for element {i}")));
448 };
449
450 // In wasm 2.0, it's possible to call a function that hasn't been instantiated yet,
451 // when using a partially initialized active element segments.
452 // This isn't mentioned in the spec, but the "unofficial" testsuite has a test for it:
453 // https://github.com/WebAssembly/testsuite/blob/5a1a590603d81f40ef471abba70a90a9ae5f4627/linking.wast#L264-L276
454 // I have NO IDEA why this is allowed, but it is.
455 if let Err(trap) = table.init(offset, &init) {
456 return Ok((elem_addrs.into_boxed_slice(), Some(trap)));
457 }
458
459 // f. Execute the instruction elm.drop i
460 None
461 }
462 };
463
464 self.state.elements.push(ElementInstance::new(element.kind.clone(), items));
465 elem_addrs.push((i + elem_count) as Addr);
466 }
467
468 // this should be optimized out by the compiler
469 Ok((elem_addrs.into_boxed_slice(), None))
470 }
471
472 /// Add data to the store, returning their addresses in the store

Callers 1

instantiate_no_startMethod · 0.80

Calls 7

mapMethod · 0.80
elem_addrMethod · 0.80
eval_size_constMethod · 0.80
initMethod · 0.80
lenMethod · 0.45
getMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected