diff --git a/src/module.rs b/src/module.rs index 155bd05..fda54bd 100644 --- a/src/module.rs +++ b/src/module.rs @@ -403,6 +403,15 @@ impl ModuleInstance { let table_inst = module_ref.table_by_index(DEFAULT_TABLE_INDEX).expect( "Due to validation default table should exists", ); + + // This check is not only for bailing out early, but also to check the case when + // segment consist of 0 members. + if offset_val as usize + element_segment.members().len() > table_inst.current_size() as usize { + return Err( + Error::Instantiation("elements segment does not fit".to_string()) + ); + } + for (j, func_idx) in element_segment.members().into_iter().enumerate() { let func = module_ref.func_by_index(*func_idx).expect( "Due to validation funcs from element segments should exists", diff --git a/tests/spec/run.rs b/tests/spec/run.rs index 0938f97..d2d40ad 100644 --- a/tests/spec/run.rs +++ b/tests/spec/run.rs @@ -7,7 +7,7 @@ use wasmi::{ GlobalInstance, GlobalRef, ImportResolver, ImportsBuilder, MemoryDescriptor, MemoryInstance, MemoryRef, Module, ModuleImportResolver, ModuleInstance, ModuleRef, RuntimeArgs, RuntimeValue, Signature, TableDescriptor, TableInstance, TableRef, Trap, - ValueType}; +}; use wasmi::memory_units::Pages; use wabt::script::{self, Action, Command, CommandKind, ScriptParser, Value}; @@ -44,7 +44,6 @@ struct SpecModule { table: TableRef, memory: MemoryRef, global_i32: GlobalRef, - global_i64: GlobalRef, global_f32: GlobalRef, global_f64: GlobalRef, } @@ -55,7 +54,6 @@ impl SpecModule { table: TableInstance::alloc(10, Some(20)).unwrap(), memory: MemoryInstance::alloc(Pages(1), Some(Pages(2))).unwrap(), global_i32: GlobalInstance::alloc(RuntimeValue::I32(666), false), - global_i64: GlobalInstance::alloc(RuntimeValue::I64(666), false), global_f32: GlobalInstance::alloc(RuntimeValue::F32(666.0), false), global_f64: GlobalInstance::alloc(RuntimeValue::F64(666.0), false), } @@ -86,41 +84,45 @@ impl ModuleImportResolver for SpecModule { field_name: &str, func_type: &Signature, ) -> Result { - if field_name == "print" { - if func_type.return_type().is_some() { - return Err(InterpreterError::Instantiation( - "Function `print` have unit return type".into(), - )); - } + let index = match field_name { + "print" => PRINT_FUNC_INDEX, + "print_i32" => PRINT_FUNC_INDEX, + "print_i32_f32" => PRINT_FUNC_INDEX, + "print_f64_f64" => PRINT_FUNC_INDEX, + "print_f32" => PRINT_FUNC_INDEX, + "print_f64" => PRINT_FUNC_INDEX, + _ => { + return Err(InterpreterError::Instantiation(format!( + "Unknown host func import {}", + field_name + ))); + } + }; - let func = FuncInstance::alloc_host(func_type.clone(), PRINT_FUNC_INDEX); - return Ok(func); - } + if func_type.return_type().is_some() { + return Err(InterpreterError::Instantiation( + "Function `print_` have unit return type".into(), + )); + } - Err(InterpreterError::Instantiation(format!( - "Unknown host func import {}", - field_name - ))) + let func = FuncInstance::alloc_host(func_type.clone(), index); + return Ok(func); } fn resolve_global( &self, field_name: &str, - global_type: &GlobalDescriptor, + _global_type: &GlobalDescriptor, ) -> Result { - if field_name == "global" { - return match global_type.value_type() { - ValueType::I32 => Ok(self.global_i32.clone()), - ValueType::I64 => Ok(self.global_i64.clone()), - ValueType::F32 => Ok(self.global_f32.clone()), - ValueType::F64 => Ok(self.global_f64.clone()), - }; - } - - Err(InterpreterError::Instantiation(format!( - "Unknown host global import {}", - field_name - ))) + match field_name { + "global_i32" => Ok(self.global_i32.clone()), + "global_f32" => Ok(self.global_f32.clone()), + "global_f64" => Ok(self.global_f64.clone()), + _ => Err(InterpreterError::Instantiation(format!( + "Unknown host global import {}", + field_name + ))) + } } fn resolve_memory( diff --git a/tests/spec/testsuite b/tests/spec/testsuite index b38bf51..c538faa 160000 --- a/tests/spec/testsuite +++ b/tests/spec/testsuite @@ -1 +1 @@ -Subproject commit b38bf51ea9c956951b9466aa8243d9727d009bb2 +Subproject commit c538faa43217146f458b9bc2d4b704d0a4d80963