Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4125110

Browse files
feat: table.init
Signed-off-by: Henry Gressmann <[email protected]>
1 parent 85deebc commit 4125110

File tree

7 files changed

+43
-21
lines changed

7 files changed

+43
-21
lines changed

crates/tinywasm/src/instance.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ impl ModuleInstance {
144144
*self.0.mem_addrs.get(addr as usize).expect("No mem addr for mem, this is a bug")
145145
}
146146

147+
// resolve a memory address to the global store address
148+
pub(crate) fn resolve_elem_addr(&self, addr: ElemAddr) -> ElemAddr {
149+
*self.0.elem_addrs.get(addr as usize).expect("No elem addr for elem, this is a bug")
150+
}
151+
147152
// resolve a global address to the global store address
148153
pub(crate) fn resolve_global_addr(&self, addr: GlobalAddr) -> GlobalAddr {
149154
self.0.global_addrs[addr as usize]

crates/tinywasm/src/runtime/executor/mod.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
CallFrame, Error, LabelArgs, ModuleInstance, Result, Store, Trap,
88
};
99
use alloc::{string::ToString, vec::Vec};
10-
use tinywasm_types::Instruction;
10+
use tinywasm_types::{ElementKind, Instruction};
1111

1212
mod macros;
1313
mod traits;
@@ -111,7 +111,10 @@ fn exec_one(
111111
Nop => { /* do nothing */ }
112112
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
113113
Drop => stack.values.pop().map(|_| ())?,
114-
Select(t) => {
114+
115+
Select(
116+
_valtype, // due to validation, we know that the type of the values on the stack are correct
117+
) => {
115118
// due to validation, we know that the type of the values on the stack
116119
let cond: i32 = stack.values.pop()?.into();
117120
let val2 = stack.values.pop()?;
@@ -554,6 +557,7 @@ fn exec_one(
554557
I64TruncF32U => checked_conv_float!(f32, u64, i64, stack),
555558
I64TruncF64U => checked_conv_float!(f64, u64, i64, stack),
556559

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

582+
TableInit(table_index, elem_index) => {
583+
let table_idx = module.resolve_table_addr(*table_index);
584+
let table = store.get_table(table_idx as usize)?;
585+
586+
let elem_idx = module.resolve_elem_addr(*elem_index);
587+
let elem = store.get_elem(elem_idx as usize)?;
588+
589+
if elem.kind != ElementKind::Passive {
590+
return Err(Trap::TableOutOfBounds { offset: 0, len: 0, max: 0 }.into());
591+
}
592+
593+
let Some(items) = elem.items.as_ref() else {
594+
return Err(Trap::TableOutOfBounds { offset: 0, len: 0, max: 0 }.into());
595+
};
596+
597+
table.borrow_mut().init(0, items)?;
598+
}
599+
578600
I32TruncSatF32S => arithmetic_single!(trunc, f32, i32, stack),
579601
I32TruncSatF32U => arithmetic_single!(trunc, f32, u32, stack),
580602
I32TruncSatF64S => arithmetic_single!(trunc, f64, i32, stack),

crates/tinywasm/src/runtime/stack/value_stack.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,6 @@ impl ValueStack {
106106
Ok(&self.stack[self.top - n..self.top])
107107
}
108108

109-
#[inline]
110-
pub(crate) fn pop_n(&mut self, n: usize) -> Result<Vec<RawWasmValue>> {
111-
if self.top < n {
112-
return Err(Error::StackUnderflow);
113-
}
114-
self.top -= n;
115-
let res = self.stack.drain(self.top..).rev().collect::<Vec<_>>();
116-
Ok(res)
117-
}
118-
119109
#[inline]
120110
pub(crate) fn pop_n_rev(&mut self, n: usize) -> Result<Vec<RawWasmValue>> {
121111
if self.top < n {

crates/tinywasm/src/store.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,11 @@ impl Store {
342342
self.data.tables.get(addr).ok_or_else(|| Error::Other(format!("table {} not found", addr)))
343343
}
344344

345+
/// Get the element at the actual index in the store
346+
pub(crate) fn get_elem(&self, addr: usize) -> Result<&ElemInstance> {
347+
self.data.elems.get(addr).ok_or_else(|| Error::Other(format!("element {} not found", addr)))
348+
}
349+
345350
/// Get the global at the actual index in the store
346351
pub(crate) fn get_global_val(&self, addr: usize) -> Result<RawWasmValue> {
347352
self.data
@@ -548,14 +553,14 @@ impl GlobalInstance {
548553
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#element-instances>
549554
#[derive(Debug)]
550555
pub(crate) struct ElemInstance {
551-
_kind: ElementKind,
552-
_items: Option<Vec<u32>>, // none is the element was dropped
553-
_owner: ModuleInstanceAddr, // index into store.module_instances
556+
pub(crate) kind: ElementKind,
557+
pub(crate) items: Option<Vec<u32>>, // none is the element was dropped
558+
_owner: ModuleInstanceAddr, // index into store.module_instances
554559
}
555560

556561
impl ElemInstance {
557562
pub(crate) fn new(kind: ElementKind, owner: ModuleInstanceAddr, items: Option<Vec<u32>>) -> Self {
558-
Self { _kind: kind, _owner: owner, _items: items }
563+
Self { kind, _owner: owner, items }
559564
}
560565
}
561566

crates/tinywasm/tests/generated/mvp.csv

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

crates/tinywasm/tests/generated/progress-mvp.svg

Lines changed: 3 additions & 3 deletions
Loading

crates/types/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ pub struct Element {
465465
pub ty: ValType,
466466
}
467467

468-
#[derive(Debug, Clone)]
468+
#[derive(Debug, Clone, PartialEq)]
469469
pub enum ElementKind {
470470
Passive,
471471
Active { table: TableAddr, offset: ConstInstruction },

0 commit comments

Comments
 (0)