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(
|
let table_inst = module_ref.table_by_index(DEFAULT_TABLE_INDEX).expect(
|
||||||
"Due to validation default table should exists",
|
"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() {
|
for (j, func_idx) in element_segment.members().into_iter().enumerate() {
|
||||||
let func = module_ref.func_by_index(*func_idx).expect(
|
let func = module_ref.func_by_index(*func_idx).expect(
|
||||||
"Due to validation funcs from element segments should exists",
|
"Due to validation funcs from element segments should exists",
|
||||||
|
|
|
@ -7,7 +7,7 @@ use wasmi::{
|
||||||
GlobalInstance, GlobalRef, ImportResolver, ImportsBuilder, MemoryDescriptor,
|
GlobalInstance, GlobalRef, ImportResolver, ImportsBuilder, MemoryDescriptor,
|
||||||
MemoryInstance, MemoryRef, Module, ModuleImportResolver, ModuleInstance, ModuleRef,
|
MemoryInstance, MemoryRef, Module, ModuleImportResolver, ModuleInstance, ModuleRef,
|
||||||
RuntimeArgs, RuntimeValue, Signature, TableDescriptor, TableInstance, TableRef, Trap,
|
RuntimeArgs, RuntimeValue, Signature, TableDescriptor, TableInstance, TableRef, Trap,
|
||||||
ValueType};
|
};
|
||||||
use wasmi::memory_units::Pages;
|
use wasmi::memory_units::Pages;
|
||||||
use wabt::script::{self, Action, Command, CommandKind, ScriptParser, Value};
|
use wabt::script::{self, Action, Command, CommandKind, ScriptParser, Value};
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ struct SpecModule {
|
||||||
table: TableRef,
|
table: TableRef,
|
||||||
memory: MemoryRef,
|
memory: MemoryRef,
|
||||||
global_i32: GlobalRef,
|
global_i32: GlobalRef,
|
||||||
global_i64: GlobalRef,
|
|
||||||
global_f32: GlobalRef,
|
global_f32: GlobalRef,
|
||||||
global_f64: GlobalRef,
|
global_f64: GlobalRef,
|
||||||
}
|
}
|
||||||
|
@ -55,7 +54,6 @@ impl SpecModule {
|
||||||
table: TableInstance::alloc(10, Some(20)).unwrap(),
|
table: TableInstance::alloc(10, Some(20)).unwrap(),
|
||||||
memory: MemoryInstance::alloc(Pages(1), Some(Pages(2))).unwrap(),
|
memory: MemoryInstance::alloc(Pages(1), Some(Pages(2))).unwrap(),
|
||||||
global_i32: GlobalInstance::alloc(RuntimeValue::I32(666), false),
|
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_f32: GlobalInstance::alloc(RuntimeValue::F32(666.0), false),
|
||||||
global_f64: GlobalInstance::alloc(RuntimeValue::F64(666.0), false),
|
global_f64: GlobalInstance::alloc(RuntimeValue::F64(666.0), false),
|
||||||
}
|
}
|
||||||
|
@ -86,42 +84,46 @@ impl ModuleImportResolver for SpecModule {
|
||||||
field_name: &str,
|
field_name: &str,
|
||||||
func_type: &Signature,
|
func_type: &Signature,
|
||||||
) -> Result<FuncRef, InterpreterError> {
|
) -> Result<FuncRef, InterpreterError> {
|
||||||
if field_name == "print" {
|
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
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if func_type.return_type().is_some() {
|
if func_type.return_type().is_some() {
|
||||||
return Err(InterpreterError::Instantiation(
|
return Err(InterpreterError::Instantiation(
|
||||||
"Function `print` have unit return type".into(),
|
"Function `print_` have unit return type".into(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let func = FuncInstance::alloc_host(func_type.clone(), PRINT_FUNC_INDEX);
|
let func = FuncInstance::alloc_host(func_type.clone(), index);
|
||||||
return Ok(func);
|
return Ok(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(InterpreterError::Instantiation(format!(
|
|
||||||
"Unknown host func import {}",
|
|
||||||
field_name
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_global(
|
fn resolve_global(
|
||||||
&self,
|
&self,
|
||||||
field_name: &str,
|
field_name: &str,
|
||||||
global_type: &GlobalDescriptor,
|
_global_type: &GlobalDescriptor,
|
||||||
) -> Result<GlobalRef, InterpreterError> {
|
) -> Result<GlobalRef, InterpreterError> {
|
||||||
if field_name == "global" {
|
match field_name {
|
||||||
return match global_type.value_type() {
|
"global_i32" => Ok(self.global_i32.clone()),
|
||||||
ValueType::I32 => Ok(self.global_i32.clone()),
|
"global_f32" => Ok(self.global_f32.clone()),
|
||||||
ValueType::I64 => Ok(self.global_i64.clone()),
|
"global_f64" => Ok(self.global_f64.clone()),
|
||||||
ValueType::F32 => Ok(self.global_f32.clone()),
|
_ => Err(InterpreterError::Instantiation(format!(
|
||||||
ValueType::F64 => Ok(self.global_f64.clone()),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(InterpreterError::Instantiation(format!(
|
|
||||||
"Unknown host global import {}",
|
"Unknown host global import {}",
|
||||||
field_name
|
field_name
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_memory(
|
fn resolve_memory(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit b38bf51ea9c956951b9466aa8243d9727d009bb2
|
Subproject commit c538faa43217146f458b9bc2d4b704d0a4d80963
|
Loading…
Reference in New Issue