Skip to content

Commit

Permalink
feat: table.init
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
  • Loading branch information
explodingcamera committed Jan 22, 2024
1 parent 85deebc commit 4125110
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 21 deletions.
5 changes: 5 additions & 0 deletions crates/tinywasm/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ impl ModuleInstance {
*self.0.mem_addrs.get(addr as usize).expect("No mem addr for mem, this is a bug")
}

// resolve a memory address to the global store address
pub(crate) fn resolve_elem_addr(&self, addr: ElemAddr) -> ElemAddr {
*self.0.elem_addrs.get(addr as usize).expect("No elem addr for elem, this is a bug")
}

// resolve a global address to the global store address
pub(crate) fn resolve_global_addr(&self, addr: GlobalAddr) -> GlobalAddr {
self.0.global_addrs[addr as usize]
Expand Down
26 changes: 24 additions & 2 deletions crates/tinywasm/src/runtime/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
CallFrame, Error, LabelArgs, ModuleInstance, Result, Store, Trap,
};
use alloc::{string::ToString, vec::Vec};
use tinywasm_types::Instruction;
use tinywasm_types::{ElementKind, Instruction};

mod macros;
mod traits;
Expand Down Expand Up @@ -111,7 +111,10 @@ fn exec_one(
Nop => { /* do nothing */ }
Unreachable => return Ok(ExecResult::Trap(crate::Trap::Unreachable)), // we don't need to include the call frame here because it's already on the stack
Drop => stack.values.pop().map(|_| ())?,
Select(t) => {

Select(
_valtype, // due to validation, we know that the type of the values on the stack are correct
) => {
// due to validation, we know that the type of the values on the stack
let cond: i32 = stack.values.pop()?.into();
let val2 = stack.values.pop()?;
Expand Down Expand Up @@ -554,6 +557,7 @@ fn exec_one(
I64TruncF32U => checked_conv_float!(f32, u64, i64, stack),
I64TruncF64U => checked_conv_float!(f64, u64, i64, stack),

// TODO: uninitialized element traps
TableGet(table_index) => {
let table_idx = module.resolve_table_addr(*table_index);
let table = store.get_table(table_idx as usize)?;
Expand All @@ -575,6 +579,24 @@ fn exec_one(
stack.values.push(table.borrow().size().into());
}

TableInit(table_index, elem_index) => {
let table_idx = module.resolve_table_addr(*table_index);
let table = store.get_table(table_idx as usize)?;

let elem_idx = module.resolve_elem_addr(*elem_index);
let elem = store.get_elem(elem_idx as usize)?;

if elem.kind != ElementKind::Passive {
return Err(Trap::TableOutOfBounds { offset: 0, len: 0, max: 0 }.into());
}

let Some(items) = elem.items.as_ref() else {
return Err(Trap::TableOutOfBounds { offset: 0, len: 0, max: 0 }.into());
};

table.borrow_mut().init(0, items)?;
}

I32TruncSatF32S => arithmetic_single!(trunc, f32, i32, stack),
I32TruncSatF32U => arithmetic_single!(trunc, f32, u32, stack),
I32TruncSatF64S => arithmetic_single!(trunc, f64, i32, stack),
Expand Down
10 changes: 0 additions & 10 deletions crates/tinywasm/src/runtime/stack/value_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,6 @@ impl ValueStack {
Ok(&self.stack[self.top - n..self.top])
}

#[inline]
pub(crate) fn pop_n(&mut self, n: usize) -> Result<Vec<RawWasmValue>> {
if self.top < n {
return Err(Error::StackUnderflow);
}
self.top -= n;
let res = self.stack.drain(self.top..).rev().collect::<Vec<_>>();
Ok(res)
}

#[inline]
pub(crate) fn pop_n_rev(&mut self, n: usize) -> Result<Vec<RawWasmValue>> {
if self.top < n {
Expand Down
13 changes: 9 additions & 4 deletions crates/tinywasm/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,11 @@ impl Store {
self.data.tables.get(addr).ok_or_else(|| Error::Other(format!("table {} not found", addr)))
}

/// Get the element at the actual index in the store
pub(crate) fn get_elem(&self, addr: usize) -> Result<&ElemInstance> {
self.data.elems.get(addr).ok_or_else(|| Error::Other(format!("element {} not found", addr)))
}

/// Get the global at the actual index in the store
pub(crate) fn get_global_val(&self, addr: usize) -> Result<RawWasmValue> {
self.data
Expand Down Expand Up @@ -548,14 +553,14 @@ impl GlobalInstance {
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#element-instances>
#[derive(Debug)]
pub(crate) struct ElemInstance {
_kind: ElementKind,
_items: Option<Vec<u32>>, // none is the element was dropped
_owner: ModuleInstanceAddr, // index into store.module_instances
pub(crate) kind: ElementKind,
pub(crate) items: Option<Vec<u32>>, // none is the element was dropped
_owner: ModuleInstanceAddr, // index into store.module_instances
}

impl ElemInstance {
pub(crate) fn new(kind: ElementKind, owner: ModuleInstanceAddr, items: Option<Vec<u32>>) -> Self {
Self { _kind: kind, _owner: owner, _items: items }
Self { kind, _owner: owner, items }
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/tinywasm/tests/generated/mvp.csv

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions crates/tinywasm/tests/generated/progress-mvp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion crates/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ pub struct Element {
pub ty: ValType,
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub enum ElementKind {
Passive,
Active { table: TableAddr, offset: ConstInstruction },
Expand Down

0 comments on commit 4125110

Please sign in to comment.