diff options
| author | Henry Gressmann <mail@henrygressmann.de> | 2024-01-15 18:44:16 +0100 |
|---|---|---|
| committer | Henry Gressmann <mail@henrygressmann.de> | 2024-01-15 18:44:16 +0100 |
| commit | 9c82f366fc1e0ae8088660abe51d3708d42132f8 (patch) | |
| tree | 703d3d44f04641500c0b2c6690f0b814b99fed94 | |
| parent | a5e9fdadb0f15f3dcdca84c2f275b181d2965598 (diff) | |
chore: change panics to UnimplementedFeature errors
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
| -rw-r--r-- | Cargo.lock | 89 | ||||
| -rw-r--r-- | crates/parser/src/conversion.rs | 6 | ||||
| -rw-r--r-- | crates/tinywasm/src/func.rs | 2 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/executor/mod.rs | 16 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/stack/call_stack.rs | 49 | ||||
| -rw-r--r-- | crates/tinywasm/src/store.rs | 55 | ||||
| -rw-r--r-- | crates/types/src/lib.rs | 11 |
7 files changed, 109 insertions, 119 deletions
@@ -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, + } + } +} |
