summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-01-15 18:44:16 +0100
committerHenry Gressmann <mail@henrygressmann.de>2024-01-15 18:44:16 +0100
commit9c82f366fc1e0ae8088660abe51d3708d42132f8 (patch)
tree703d3d44f04641500c0b2c6690f0b814b99fed94
parenta5e9fdadb0f15f3dcdca84c2f275b181d2965598 (diff)
chore: change panics to UnimplementedFeature errors
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
-rw-r--r--Cargo.lock89
-rw-r--r--crates/parser/src/conversion.rs6
-rw-r--r--crates/tinywasm/src/func.rs2
-rw-r--r--crates/tinywasm/src/runtime/executor/mod.rs16
-rw-r--r--crates/tinywasm/src/runtime/stack/call_stack.rs49
-rw-r--r--crates/tinywasm/src/store.rs55
-rw-r--r--crates/types/src/lib.rs11
7 files changed, 109 insertions, 119 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4baa78c..acd3d65 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -223,15 +223,6 @@ dependencies = [
]
[[package]]
-name = "cmake"
-version = "0.1.50"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
-dependencies = [
- "cc",
-]
-
-[[package]]
name = "color-eyre"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -488,9 +479,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "freetype"
-version = "0.7.0"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bee38378a9e3db1cc693b4f88d166ae375338a0ff75cb8263e1c601d51f35dc6"
+checksum = "efc8599a3078adf8edeb86c71e9f8fa7d88af5ca31e806a867756081f90f5d83"
dependencies = [
"freetype-sys",
"libc",
@@ -498,11 +489,11 @@ dependencies = [
[[package]]
name = "freetype-sys"
-version = "0.13.1"
+version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a"
+checksum = "66ee28c39a43d89fbed8b4798fb4ba56722cfd2b5af81f9326c27614ba88ecd5"
dependencies = [
- "cmake",
+ "cc",
"libc",
"pkg-config",
]
@@ -609,15 +600,14 @@ dependencies = [
[[package]]
name = "image"
-version = "0.24.7"
+version = "0.24.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711"
+checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"jpeg-decoder",
- "num-rational",
"num-traits",
"png",
]
@@ -653,15 +643,15 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "jpeg-decoder"
-version = "0.3.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e"
+checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
[[package]]
name = "js-sys"
-version = "0.3.66"
+version = "0.3.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca"
+checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1"
dependencies = [
"wasm-bindgen",
]
@@ -734,27 +724,6 @@ dependencies = [
]
[[package]]
-name = "num-integer"
-version = "0.1.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
-dependencies = [
- "autocfg",
- "num-traits",
-]
-
-[[package]]
-name = "num-rational"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -863,9 +832,9 @@ dependencies = [
[[package]]
name = "png"
-version = "0.17.10"
+version = "0.17.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64"
+checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
@@ -1067,9 +1036,9 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.38.28"
+version = "0.38.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
+checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca"
dependencies = [
"bitflags 2.4.1",
"errno",
@@ -1189,9 +1158,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "termcolor"
-version = "1.4.0"
+version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
+checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
@@ -1331,9 +1300,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
-version = "0.2.89"
+version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e"
+checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@@ -1341,9 +1310,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.89"
+version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826"
+checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd"
dependencies = [
"bumpalo",
"log",
@@ -1356,9 +1325,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.89"
+version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2"
+checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -1366,9 +1335,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.89"
+version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
+checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7"
dependencies = [
"proc-macro2",
"quote",
@@ -1379,9 +1348,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.89"
+version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
+checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
[[package]]
name = "wasm-encoder"
@@ -1422,9 +1391,9 @@ dependencies = [
[[package]]
name = "web-sys"
-version = "0.3.66"
+version = "0.3.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f"
+checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed"
dependencies = [
"js-sys",
"wasm-bindgen",
diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs
index b9e674e..7b36dcd 100644
--- a/crates/parser/src/conversion.rs
+++ b/crates/parser/src/conversion.rs
@@ -1,5 +1,5 @@
use alloc::{boxed::Box, format, string::ToString, vec::Vec};
-use log::info;
+use log::debug;
use tinywasm_types::{
BlockArgs, ConstInstruction, ElementItem, Export, ExternalKind, FuncType, Global, GlobalType, Import, ImportKind,
Instruction, MemArg, MemoryArch, MemoryType, TableType, ValType,
@@ -322,7 +322,7 @@ pub fn process_operators<'a>(
let mut labels_ptrs = Vec::new(); // indexes into the instructions array
for op in ops {
- info!("op: {:?}", op);
+ debug!("op: {:?}", op);
let op = op?;
validator.op(offset, &op)?;
@@ -359,7 +359,7 @@ pub fn process_operators<'a>(
}
End => {
if let Some(label_pointer) = labels_ptrs.pop() {
- info!("ending block: {:?}", instructions[label_pointer]);
+ debug!("ending block: {:?}", instructions[label_pointer]);
let current_instr_ptr = instructions.len();
diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs
index b0b359d..7a6fd1c 100644
--- a/crates/tinywasm/src/func.rs
+++ b/crates/tinywasm/src/func.rs
@@ -68,7 +68,7 @@ impl FuncHandle {
let result_m = func_ty.results.len();
// 1. Assert: m values are on the top of the stack (Ensured by validation)
- debug_assert!(stack.values.len() >= result_m);
+ assert!(stack.values.len() >= result_m);
// 2. Pop m values from the stack
let res = stack.values.last_n(result_m)?;
diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs
index 541c0a7..fe27d5a 100644
--- a/crates/tinywasm/src/runtime/executor/mod.rs
+++ b/crates/tinywasm/src/runtime/executor/mod.rs
@@ -7,7 +7,6 @@ use crate::{
CallFrame, Error, LabelArgs, ModuleInstance, Result, Store,
};
use alloc::vec::Vec;
-use log::info;
use tinywasm_types::Instruction;
mod macros;
@@ -104,7 +103,7 @@ fn exec_one(
store: &mut Store,
module: &ModuleInstance,
) -> Result<ExecResult> {
- info!("ptr: {} instr: {:?}", cf.instr_ptr, instr);
+ debug!("ptr: {} instr: {:?}", cf.instr_ptr, instr);
use tinywasm_types::Instruction::*;
match instr {
@@ -217,7 +216,11 @@ fn exec_one(
.collect::<Result<Vec<_>>>()?;
if instr.len() != *len {
- panic!("Expected {} BrLabel instructions, got {}", len, instr.len());
+ panic!(
+ "Expected {} BrLabel instructions, got {}, this should have been validated by the parser",
+ len,
+ instr.len()
+ );
}
let idx = stack.values.pop_t::<i32>()? as usize;
@@ -241,7 +244,7 @@ fn exec_one(
},
EndFunc => {
- debug_assert!(
+ assert!(
cf.labels.len() == 0,
"endfunc: block frames not empty, this should have been validated by the parser"
);
@@ -499,7 +502,10 @@ fn exec_one(
i => {
log::error!("unimplemented instruction: {:?}", i);
- panic!("Unimplemented instruction: {:?}", i)
+ return Err(Error::UnsupportedFeature(alloc::format!(
+ "unimplemented instruction: {:?}",
+ i
+ )));
}
};
diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs
index 239659c..c4397c2 100644
--- a/crates/tinywasm/src/runtime/stack/call_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/call_stack.rs
@@ -39,27 +39,12 @@ impl CallStack {
}
#[inline]
- pub(crate) fn _top(&self) -> Result<&CallFrame> {
- assert!(self.top <= self.stack.len());
- if self.top == 0 {
- return Err(Error::CallStackEmpty);
- }
- Ok(&self.stack[self.top - 1])
- }
-
- #[inline]
- pub(crate) fn _top_mut(&mut self) -> Result<&mut CallFrame> {
- assert!(self.top <= self.stack.len());
- if self.top == 0 {
- return Err(Error::CallStackEmpty);
- }
- Ok(&mut self.stack[self.top - 1])
- }
-
- #[inline]
pub(crate) fn push(&mut self, call_frame: CallFrame) {
- assert!(self.top <= self.stack.len());
- assert!(self.stack.len() <= CALL_STACK_MAX_SIZE);
+ assert!(self.top <= self.stack.len(), "stack is too small");
+ assert!(
+ self.stack.len() <= CALL_STACK_MAX_SIZE,
+ "call stack size exceeded, this should have been caught"
+ );
self.top += 1;
self.stack.push(call_frame);
@@ -68,7 +53,6 @@ impl CallStack {
#[derive(Debug, Clone)]
pub(crate) struct CallFrame {
- // having real pointers here would be nice :( but we can't really do that in safe rust
pub(crate) instr_ptr: usize,
pub(crate) func_ptr: usize,
@@ -115,19 +99,6 @@ impl CallFrame {
}
}
- // self.instr_ptr = block_frame.instr_ptr;
- // value_stack.trim(block_frame.stack_ptr);
-
- // // // Adjusting how to trim the blocks stack based on the block type
- // // let trim_index = match block_frame.block {
- // // // if we are breaking to a loop, we want to jump back to the start of the loop
- // // BlockFrameInner::Loop => block_index as usize - 1,
- // // // if we are breaking to any other block, we want to jump to the end of the block
- // // // TODO: check if this is correct
- // // BlockFrameInner::If | BlockFrameInner::Else | BlockFrameInner::Block => block_index as usize - 1,
- // // };
-
- // self.block_frames.trim(block_index as usize);
Some(())
}
@@ -155,19 +126,13 @@ impl CallFrame {
#[inline]
pub(crate) fn set_local(&mut self, local_index: usize, value: RawWasmValue) {
- if local_index >= self.local_count {
- panic!("Invalid local index");
- }
-
+ assert!(local_index < self.local_count, "Invalid local index");
self.locals[local_index] = value;
}
#[inline]
pub(crate) fn get_local(&self, local_index: usize) -> RawWasmValue {
- if local_index >= self.local_count {
- panic!("Invalid local index");
- }
-
+ assert!(local_index < self.local_count, "Invalid local index");
self.locals[local_index]
}
}
diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs
index 564232d..73eb503 100644
--- a/crates/tinywasm/src/store.rs
+++ b/crates/tinywasm/src/store.rs
@@ -202,6 +202,21 @@ impl Store {
Ok(global_addrs)
}
+ pub(crate) fn eval_i32_const(&self, const_instr: &tinywasm_types::ConstInstruction) -> Result<i32> {
+ use tinywasm_types::ConstInstruction::*;
+ let val = match const_instr {
+ I32Const(i) => *i,
+ GlobalGet(addr) => {
+ let addr = *addr as usize;
+ let global = self.data.globals[addr].clone();
+ let val = global.borrow().value;
+ i32::from(val)
+ }
+ _ => return Err(Error::Other("expected i32".to_string())),
+ };
+ Ok(val)
+ }
+
pub(crate) fn eval_const(&self, const_instr: &tinywasm_types::ConstInstruction) -> Result<RawWasmValue> {
use tinywasm_types::ConstInstruction::*;
let val = match const_instr {
@@ -227,27 +242,50 @@ impl Store {
let elem_count = self.data.elems.len();
let mut elem_addrs = Vec::with_capacity(elem_count);
for (i, elem) in elems.into_iter().enumerate() {
- match elem.kind {
+ let items = match elem.kind {
// doesn't need to be initialized, can be initialized lazily using the `table.init` instruction
- ElementKind::Passive => {}
+ ElementKind::Passive => None,
+ // TODO: ElementKind::Passive => Some(elem.items.iter().map(|item| item.addr()).collect()),
// this one is active, so we need to initialize it (essentially a `table.init` instruction)
- ElementKind::Active { .. } => {
+ ElementKind::Active { offset, table } => {
+ let init = elem
+ .items
+ .iter()
+ .map(|item| {
+ item.addr().ok_or_else(|| {
+ Error::UnsupportedFeature(format!("const expression other than ref: {:?}", item))
+ })
+ })
+ .collect::<Result<Vec<_>>>()?;
+
// a. Let n be the length of the vector elem[i].init
+ let n = elem.items.len();
+
// b. Execute the instruction sequence einstrs
+ let table_idx = self.eval_i32_const(&offset)? as usize;
+
// c. Execute the instruction i32.const 0
+ let elem_idx = 0;
+
// d. Execute the instruction i32.const n
+ let elem_count = n;
+
// e. Execute the instruction table.init tableidx i
+ // self.data.tables[table_idx].elements[elem_idx..elem_count].copy_from_slice(&init);
+
// f. Execute the instruction elm.drop i
+ None
}
// this one is not available to the runtime but needs to be initialized to declare references
ElementKind::Declared => {
// a. Execute the instruction elm.drop i
+ None
}
- }
+ };
- self.data.elems.push(ElemInstance::new(elem.kind, idx));
+ self.data.elems.push(ElemInstance::new(elem.kind, idx, items));
elem_addrs.push((i + elem_count) as Addr);
}
@@ -377,7 +415,7 @@ pub(crate) struct MemoryInstance {
impl MemoryInstance {
pub(crate) fn new(kind: MemoryType, owner: ModuleInstanceAddr) -> Self {
- debug_assert!(kind.page_count_initial <= kind.page_count_max.unwrap_or(MAX_PAGES as u64));
+ assert!(kind.page_count_initial <= kind.page_count_max.unwrap_or(MAX_PAGES as u64));
log::debug!("initializing memory with {} pages", kind.page_count_initial);
Self {
@@ -480,12 +518,13 @@ impl GlobalInstance {
#[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
}
impl ElemInstance {
- pub(crate) fn new(kind: ElementKind, owner: ModuleInstanceAddr) -> Self {
- Self { kind, owner }
+ pub(crate) fn new(kind: ElementKind, owner: ModuleInstanceAddr, items: Option<Vec<u32>>) -> Self {
+ Self { kind, owner, items }
}
}
diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs
index d3bf81a..4ea7b55 100644
--- a/crates/types/src/lib.rs
+++ b/crates/types/src/lib.rs
@@ -434,3 +434,14 @@ pub enum ElementItem {
Func(FuncAddr),
Expr(ConstInstruction),
}
+
+impl ElementItem {
+ pub fn addr(&self) -> Option<FuncAddr> {
+ match self {
+ Self::Func(addr) => Some(*addr),
+ Self::Expr(ConstInstruction::RefFunc(addr)) => Some(*addr),
+ Self::Expr(ConstInstruction::RefNull(_ty)) => Some(0),
+ _ => None,
+ }
+ }
+}