repair invalid test

This commit is contained in:
Andrew Dirksen 2018-11-19 13:39:08 -08:00
parent 57c48ecada
commit df3bce60d3
1 changed files with 74 additions and 144 deletions

View File

@ -1,11 +1,11 @@
use {
Error, Signature, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder,
MemoryInstance, MemoryRef, TableInstance, TableRef, ModuleImportResolver, ModuleInstance, ModuleRef,
RuntimeValue, RuntimeArgs, TableDescriptor, MemoryDescriptor, Trap, TrapKind, ResumableError,
};
use types::ValueType;
use memory_units::Pages;
use super::parse_wat; use super::parse_wat;
use memory_units::Pages;
use types::ValueType;
use {
Error, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder, MemoryDescriptor, MemoryInstance, MemoryRef,
ModuleImportResolver, ModuleInstance, ModuleRef, ResumableError, RuntimeArgs, RuntimeValue, Signature,
TableDescriptor, TableInstance, TableRef, Trap, TrapKind,
};
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
struct HostErrorWithCode { struct HostErrorWithCode {
@ -85,11 +85,7 @@ const RECURSE_FUNC_INDEX: usize = 4;
const TRAP_SUB_FUNC_INDEX: usize = 5; const TRAP_SUB_FUNC_INDEX: usize = 5;
impl Externals for TestHost { impl Externals for TestHost {
fn invoke_index( fn invoke_index(&mut self, index: usize, args: RuntimeArgs) -> Result<Option<RuntimeValue>, Trap> {
&mut self,
index: usize,
args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Trap> {
match index { match index {
SUB_FUNC_INDEX => { SUB_FUNC_INDEX => {
let a: i32 = args.nth(0); let a: i32 = args.nth(0);
@ -107,9 +103,10 @@ impl Externals for TestHost {
INC_MEM_FUNC_INDEX => { INC_MEM_FUNC_INDEX => {
let ptr: u32 = args.nth(0); let ptr: u32 = args.nth(0);
let memory = self.memory.as_ref().expect( let memory = self
"Function 'inc_mem' expects attached memory", .memory
); .as_ref()
.expect("Function 'inc_mem' expects attached memory");
let mut buf = [0u8; 1]; let mut buf = [0u8; 1];
memory.get_into(ptr, &mut buf).unwrap(); memory.get_into(ptr, &mut buf).unwrap();
buf[0] += 1; buf[0] += 1;
@ -120,9 +117,10 @@ impl Externals for TestHost {
GET_MEM_FUNC_INDEX => { GET_MEM_FUNC_INDEX => {
let ptr: u32 = args.nth(0); let ptr: u32 = args.nth(0);
let memory = self.memory.as_ref().expect( let memory = self
"Function 'get_mem' expects attached memory", .memory
); .as_ref()
.expect("Function 'get_mem' expects attached memory");
let mut buf = [0u8; 1]; let mut buf = [0u8; 1];
memory.get_into(ptr, &mut buf).unwrap(); memory.get_into(ptr, &mut buf).unwrap();
@ -131,7 +129,8 @@ impl Externals for TestHost {
RECURSE_FUNC_INDEX => { RECURSE_FUNC_INDEX => {
let val = args.nth_value_checked(0).expect("Exactly one argument expected"); let val = args.nth_value_checked(0).expect("Exactly one argument expected");
let instance = self.instance let instance = self
.instance
.as_ref() .as_ref()
.expect("Function 'recurse' expects attached module instance") .expect("Function 'recurse' expects attached module instance")
.clone(); .clone();
@ -191,32 +190,21 @@ impl ModuleImportResolver for TestHost {
"get_mem" => GET_MEM_FUNC_INDEX, "get_mem" => GET_MEM_FUNC_INDEX,
"recurse" => RECURSE_FUNC_INDEX, "recurse" => RECURSE_FUNC_INDEX,
"trap_sub" => TRAP_SUB_FUNC_INDEX, "trap_sub" => TRAP_SUB_FUNC_INDEX,
_ => { _ => return Err(Error::Instantiation(format!("Export {} not found", field_name))),
return Err(Error::Instantiation(
format!("Export {} not found", field_name),
))
}
}; };
if !self.check_signature(index, signature) { if !self.check_signature(index, signature) {
return Err(Error::Instantiation(format!( return Err(Error::Instantiation(format!(
"Export `{}` doesnt match expected type {:?}", "Export `{}` doesnt match expected type {:?}",
field_name, field_name, signature
signature
))); )));
} }
Ok(FuncInstance::alloc_host(signature.clone(), index)) Ok(FuncInstance::alloc_host(signature.clone(), index))
} }
fn resolve_memory( fn resolve_memory(&self, field_name: &str, _memory_type: &MemoryDescriptor) -> Result<MemoryRef, Error> {
&self, Err(Error::Instantiation(format!("Export {} not found", field_name)))
field_name: &str,
_memory_type: &MemoryDescriptor,
) -> Result<MemoryRef, Error> {
Err(Error::Instantiation(
format!("Export {} not found", field_name),
))
} }
} }
@ -244,9 +232,9 @@ fn call_host_func() {
.assert_no_start(); .assert_no_start();
assert_eq!( assert_eq!(
instance.invoke_export("test", &[], &mut env).expect( instance
"Failed to invoke 'test' function", .invoke_export("test", &[], &mut env)
), .expect("Failed to invoke 'test' function",),
Some(RuntimeValue::I32(-2)) Some(RuntimeValue::I32(-2))
); );
} }
@ -276,20 +264,21 @@ fn resume_call_host_func() {
let export = instance.export_by_name("test").unwrap(); let export = instance.export_by_name("test").unwrap();
let func_instance = export.as_func().unwrap(); let func_instance = export.as_func().unwrap();
let return_type = func_instance.signature().return_type();
let mut invocation = FuncInstance::invoke_resumable(&func_instance, &[]).unwrap(); let mut invocation = FuncInstance::invoke_resumable(&func_instance, &[]).unwrap();
let result = invocation.start_execution(&mut env); let result = invocation.start_execution(&mut env, func_instance, &[], return_type);
match result { match result {
Err(ResumableError::Trap(_)) => {}, Err(ResumableError::Trap(_)) => {}
_ => panic!(), _ => panic!(),
} }
assert!(invocation.is_resumable()); assert!(invocation.is_resumable());
let trap_sub_result = env.trap_sub_result.take(); let trap_sub_result = env.trap_sub_result.take();
assert_eq!( assert_eq!(
invocation.resume_execution(trap_sub_result, &mut env).expect( invocation
"Failed to invoke 'test' function", .resume_execution(trap_sub_result, &mut env, return_type)
), .expect("Failed to invoke 'test' function",),
Some(RuntimeValue::I32(-2)) Some(RuntimeValue::I32(-2))
); );
} }
@ -316,13 +305,15 @@ fn host_err() {
.expect("Failed to instantiate module") .expect("Failed to instantiate module")
.assert_no_start(); .assert_no_start();
let error = instance.invoke_export("test", &[], &mut env).expect_err( let error = instance
"`test` expected to return error", .invoke_export("test", &[], &mut env)
); .expect_err("`test` expected to return error");
let error_with_code = error.as_host_error().expect("Expected host error").downcast_ref::<HostErrorWithCode>().expect( let error_with_code = error
"Failed to downcast to expected error type", .as_host_error()
); .expect("Expected host error")
.downcast_ref::<HostErrorWithCode>()
.expect("Failed to downcast to expected error type");
assert_eq!(error_with_code.error_code, 228); assert_eq!(error_with_code.error_code, 228);
} }
@ -351,9 +342,9 @@ fn modify_mem_with_host_funcs() {
.expect("Failed to instantiate module") .expect("Failed to instantiate module")
.assert_no_start(); .assert_no_start();
instance.invoke_export("modify_mem", &[], &mut env).expect( instance
"Failed to invoke 'test' function", .invoke_export("modify_mem", &[], &mut env)
); .expect("Failed to invoke 'test' function");
// Check contents of memory at address 12. // Check contents of memory at address 12.
let mut buf = [0u8; 1]; let mut buf = [0u8; 1];
@ -451,9 +442,9 @@ fn recursion() {
env.instance = Some(instance.clone()); env.instance = Some(instance.clone());
assert_eq!( assert_eq!(
instance.invoke_export("test", &[], &mut env).expect( instance
"Failed to invoke 'test' function", .invoke_export("test", &[], &mut env)
), .expect("Failed to invoke 'test' function",),
// 363 = 321 + 42 // 363 = 321 + 42
Some(RuntimeValue::I64(363)) Some(RuntimeValue::I64(363))
); );
@ -472,38 +463,25 @@ fn defer_providing_externals() {
} }
impl ModuleImportResolver for HostImportResolver { impl ModuleImportResolver for HostImportResolver {
fn resolve_func( fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
&self,
field_name: &str,
signature: &Signature,
) -> Result<FuncRef, Error> {
if field_name != "inc" { if field_name != "inc" {
return Err(Error::Instantiation( return Err(Error::Instantiation(format!("Export {} not found", field_name)));
format!("Export {} not found", field_name),
));
} }
if signature.params() != &[ValueType::I32] || signature.return_type() != None { if signature.params() != &[ValueType::I32] || signature.return_type() != None {
return Err(Error::Instantiation(format!( return Err(Error::Instantiation(format!(
"Export `{}` doesnt match expected type {:?}", "Export `{}` doesnt match expected type {:?}",
field_name, field_name, signature
signature
))); )));
} }
Ok(FuncInstance::alloc_host(signature.clone(), INC_FUNC_INDEX)) Ok(FuncInstance::alloc_host(signature.clone(), INC_FUNC_INDEX))
} }
fn resolve_memory( fn resolve_memory(&self, field_name: &str, _memory_type: &MemoryDescriptor) -> Result<MemoryRef, Error> {
&self,
field_name: &str,
_memory_type: &MemoryDescriptor,
) -> Result<MemoryRef, Error> {
if field_name == "mem" { if field_name == "mem" {
Ok(self.mem.clone()) Ok(self.mem.clone())
} else { } else {
Err(Error::Instantiation( Err(Error::Instantiation(format!("Export {} not found", field_name)))
format!("Export {} not found", field_name),
))
} }
} }
} }
@ -515,11 +493,7 @@ fn defer_providing_externals() {
} }
impl<'a> Externals for HostExternals<'a> { impl<'a> Externals for HostExternals<'a> {
fn invoke_index( fn invoke_index(&mut self, index: usize, args: RuntimeArgs) -> Result<Option<RuntimeValue>, Trap> {
&mut self,
index: usize,
args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Trap> {
match index { match index {
INC_FUNC_INDEX => { INC_FUNC_INDEX => {
let a = args.nth::<u32>(0); let a = args.nth::<u32>(0);
@ -547,26 +521,23 @@ fn defer_providing_externals() {
// Create HostImportResolver with some initialized memory instance. // Create HostImportResolver with some initialized memory instance.
// This memory instance will be provided as 'mem' export. // This memory instance will be provided as 'mem' export.
let host_import_resolver = let host_import_resolver = HostImportResolver {
HostImportResolver { mem: MemoryInstance::alloc(Pages(1), Some(Pages(1))).unwrap() }; mem: MemoryInstance::alloc(Pages(1), Some(Pages(1))).unwrap(),
};
// Instantiate module with `host_import_resolver` as import resolver for "host" module. // Instantiate module with `host_import_resolver` as import resolver for "host" module.
let instance = ModuleInstance::new( let instance = ModuleInstance::new(
&module, &module,
&ImportsBuilder::new().with_resolver("host", &host_import_resolver), &ImportsBuilder::new().with_resolver("host", &host_import_resolver),
).expect("Failed to instantiate module") ).expect("Failed to instantiate module")
.assert_no_start(); .assert_no_start();
let mut acc = 89; let mut acc = 89;
{ {
let mut host_externals = HostExternals { acc: &mut acc }; let mut host_externals = HostExternals { acc: &mut acc };
instance instance.invoke_export("test", &[], &mut host_externals).unwrap(); // acc += 1;
.invoke_export("test", &[], &mut host_externals) instance.invoke_export("test", &[], &mut host_externals).unwrap(); // acc += 1;
.unwrap(); // acc += 1;
instance
.invoke_export("test", &[], &mut host_externals)
.unwrap(); // acc += 1;
} }
assert_eq!(acc, 91); assert_eq!(acc, 91);
} }
@ -579,11 +550,7 @@ fn two_envs_one_externals() {
struct HostExternals; struct HostExternals;
impl Externals for HostExternals { impl Externals for HostExternals {
fn invoke_index( fn invoke_index(&mut self, index: usize, _args: RuntimeArgs) -> Result<Option<RuntimeValue>, Trap> {
&mut self,
index: usize,
_args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Trap> {
match index { match index {
PRIVILEGED_FUNC_INDEX => { PRIVILEGED_FUNC_INDEX => {
println!("privileged!"); println!("privileged!");
@ -599,19 +566,11 @@ fn two_envs_one_externals() {
struct OrdinaryResolver; struct OrdinaryResolver;
impl ModuleImportResolver for PrivilegedResolver { impl ModuleImportResolver for PrivilegedResolver {
fn resolve_func( fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
&self,
field_name: &str,
signature: &Signature,
) -> Result<FuncRef, Error> {
let index = match field_name { let index = match field_name {
"ordinary" => ORDINARY_FUNC_INDEX, "ordinary" => ORDINARY_FUNC_INDEX,
"privileged" => PRIVILEGED_FUNC_INDEX, "privileged" => PRIVILEGED_FUNC_INDEX,
_ => { _ => return Err(Error::Instantiation(format!("Export {} not found", field_name))),
return Err(Error::Instantiation(
format!("Export {} not found", field_name),
))
}
}; };
Ok(FuncInstance::alloc_host(signature.clone(), index)) Ok(FuncInstance::alloc_host(signature.clone(), index))
@ -619,11 +578,7 @@ fn two_envs_one_externals() {
} }
impl ModuleImportResolver for OrdinaryResolver { impl ModuleImportResolver for OrdinaryResolver {
fn resolve_func( fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
&self,
field_name: &str,
signature: &Signature,
) -> Result<FuncRef, Error> {
let index = match field_name { let index = match field_name {
"ordinary" => ORDINARY_FUNC_INDEX, "ordinary" => ORDINARY_FUNC_INDEX,
"privileged" => { "privileged" => {
@ -631,11 +586,7 @@ fn two_envs_one_externals() {
"'priveleged' can be imported only in privileged context".into(), "'priveleged' can be imported only in privileged context".into(),
)) ))
} }
_ => { _ => return Err(Error::Instantiation(format!("Export {} not found", field_name))),
return Err(Error::Instantiation(
format!("Export {} not found", field_name),
))
}
}; };
Ok(FuncInstance::alloc_host(signature.clone(), index)) Ok(FuncInstance::alloc_host(signature.clone(), index))
@ -674,7 +625,7 @@ fn two_envs_one_externals() {
&trusted_module, &trusted_module,
&ImportsBuilder::new().with_resolver("env", &PrivilegedResolver), &ImportsBuilder::new().with_resolver("env", &PrivilegedResolver),
).expect("Failed to instantiate module") ).expect("Failed to instantiate module")
.assert_no_start(); .assert_no_start();
let untrusted_instance = ModuleInstance::new( let untrusted_instance = ModuleInstance::new(
&untrusted_module, &untrusted_module,
@ -682,7 +633,7 @@ fn two_envs_one_externals() {
.with_resolver("env", &OrdinaryResolver) .with_resolver("env", &OrdinaryResolver)
.with_resolver("trusted", &trusted_instance), .with_resolver("trusted", &trusted_instance),
).expect("Failed to instantiate module") ).expect("Failed to instantiate module")
.assert_no_start(); .assert_no_start();
untrusted_instance untrusted_instance
.invoke_export("test", &[], &mut HostExternals) .invoke_export("test", &[], &mut HostExternals)
@ -699,11 +650,7 @@ fn dynamically_add_host_func() {
} }
impl Externals for HostExternals { impl Externals for HostExternals {
fn invoke_index( fn invoke_index(&mut self, index: usize, _args: RuntimeArgs) -> Result<Option<RuntimeValue>, Trap> {
&mut self,
index: usize,
_args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Trap> {
match index { match index {
ADD_FUNC_FUNC_INDEX => { ADD_FUNC_FUNC_INDEX => {
// Allocate indicies for the new function. // Allocate indicies for the new function.
@ -716,47 +663,32 @@ fn dynamically_add_host_func() {
Signature::new(&[][..], Some(ValueType::I32)), Signature::new(&[][..], Some(ValueType::I32)),
host_func_index as usize, host_func_index as usize,
); );
self.table.set(table_index, Some(added_func)) self.table
.set(table_index, Some(added_func))
.map_err(|_| TrapKind::TableAccessOutOfBounds)?; .map_err(|_| TrapKind::TableAccessOutOfBounds)?;
Ok(Some(RuntimeValue::I32(table_index as i32))) Ok(Some(RuntimeValue::I32(table_index as i32)))
} }
index if index as u32 <= self.added_funcs => { index if index as u32 <= self.added_funcs => Ok(Some(RuntimeValue::I32(index as i32))),
Ok(Some(RuntimeValue::I32(index as i32)))
}
_ => panic!("'env' module doesn't provide function at index {}", index), _ => panic!("'env' module doesn't provide function at index {}", index),
} }
} }
} }
impl ModuleImportResolver for HostExternals { impl ModuleImportResolver for HostExternals {
fn resolve_func( fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
&self,
field_name: &str,
signature: &Signature,
) -> Result<FuncRef, Error> {
let index = match field_name { let index = match field_name {
"add_func" => ADD_FUNC_FUNC_INDEX, "add_func" => ADD_FUNC_FUNC_INDEX,
_ => { _ => return Err(Error::Instantiation(format!("Export {} not found", field_name))),
return Err(Error::Instantiation(
format!("Export {} not found", field_name),
))
}
}; };
Ok(FuncInstance::alloc_host(signature.clone(), index)) Ok(FuncInstance::alloc_host(signature.clone(), index))
} }
fn resolve_table( fn resolve_table(&self, field_name: &str, _table_type: &TableDescriptor) -> Result<TableRef, Error> {
&self,
field_name: &str,
_table_type: &TableDescriptor,
) -> Result<TableRef, Error> {
if field_name == "table" { if field_name == "table" {
Ok(self.table.clone()) Ok(self.table.clone())
} else { } else {
Err(Error::Instantiation( Err(Error::Instantiation(format!("Export {} not found", field_name)))
format!("Export {} not found", field_name),
))
} }
} }
} }
@ -785,10 +717,8 @@ fn dynamically_add_host_func() {
"#, "#,
); );
let instance = ModuleInstance::new( let instance = ModuleInstance::new(&module, &ImportsBuilder::new().with_resolver("env", &host_externals))
&module, .expect("Failed to instantiate module")
&ImportsBuilder::new().with_resolver("env", &host_externals),
).expect("Failed to instantiate module")
.assert_no_start(); .assert_no_start();
assert_eq!( assert_eq!(