Update spec testsuite; Fix instantiation bug (#61)
The bug was about instantiating a module with elements segment being out-of-bounds, however, it was with zero length. E.g.: ``` (module (table 0 anyfunc) (elem (i32.const 1)) ) ``` In our impl there was no out-of-bounds, because there was no attempt to set any table entry. This change adds early check for specifically this case.
This commit is contained in:
parent
d02b0f8527
commit
9140e869e2
|
@ -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",
|
||||
|
|
|
@ -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<FuncRef, InterpreterError> {
|
||||
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<GlobalRef, InterpreterError> {
|
||||
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(
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit b38bf51ea9c956951b9466aa8243d9727d009bb2
|
||||
Subproject commit c538faa43217146f458b9bc2d4b704d0a4d80963
|
Loading…
Reference in New Issue