Replace all memories with Rcs

This commit is contained in:
Sergey Pepyakin
2017-12-13 13:40:40 +01:00
parent 85bac6dba3
commit 0927e359f3
5 changed files with 34 additions and 56 deletions

View File

@ -546,8 +546,7 @@ impl<'a, St: 'static> Interpreter<'a, St> {
let address = effective_address(offset, context.value_stack_mut().pop_as()?)?;
let m = context.module()
.memory_by_index(self.store, DEFAULT_MEMORY_INDEX)
.expect("Due to validation memory should exists")
.resolve(self.store);
.expect("Due to validation memory should exists");
let b = m.get(address, mem::size_of::<T>())?;
let n = T::from_little_endian(b)?;
context.value_stack_mut().push(n.into())?;
@ -559,8 +558,7 @@ impl<'a, St: 'static> Interpreter<'a, St> {
let address = effective_address(offset, context.value_stack_mut().pop_as()?)?;
let m = context.module()
.memory_by_index(self.store, DEFAULT_MEMORY_INDEX)
.expect("Due to validation memory should exists")
.resolve(self.store);
.expect("Due to validation memory should exists");
let b = m.get(address, mem::size_of::<T>())?;
let v = T::from_little_endian(b)?;
let stack_value: U = v.extend_into();
@ -581,8 +579,7 @@ impl<'a, St: 'static> Interpreter<'a, St> {
let m = context.module()
.memory_by_index(self.store, DEFAULT_MEMORY_INDEX)
.expect("Due to validation memory should exists")
.resolve(self.store);
.expect("Due to validation memory should exists");
m.set(address, &stack_value)?;
Ok(InstructionOutcome::RunNextInstruction)
}
@ -607,8 +604,7 @@ impl<'a, St: 'static> Interpreter<'a, St> {
let address = effective_address(offset, context.value_stack_mut().pop_as::<u32>()?)?;
let m = context.module()
.memory_by_index(self.store, DEFAULT_MEMORY_INDEX)
.expect("Due to validation memory should exists")
.resolve(self.store);
.expect("Due to validation memory should exists");
m.set(address, &stack_value)?;
Ok(InstructionOutcome::RunNextInstruction)
}
@ -616,8 +612,7 @@ impl<'a, St: 'static> Interpreter<'a, St> {
fn run_current_memory(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Error> {
let m = context.module()
.memory_by_index(self.store, DEFAULT_MEMORY_INDEX)
.expect("Due to validation memory should exists")
.resolve(self.store);
.expect("Due to validation memory should exists");
let s = m.size();
context
.value_stack_mut()
@ -629,8 +624,7 @@ impl<'a, St: 'static> Interpreter<'a, St> {
let pages: u32 = context.value_stack_mut().pop_as()?;
let m = context.module()
.memory_by_index(self.store, DEFAULT_MEMORY_INDEX)
.expect("Due to validation memory should exists")
.resolve(self.store);
.expect("Due to validation memory should exists");
let m = m.grow(pages)?;
context
.value_stack_mut()

View File

@ -31,7 +31,7 @@ impl TypeId {
pub struct ModuleId(u32);
impl ModuleId {
pub fn memory_by_index(&self, store: &Store, idx: u32) -> Option<MemoryId> {
pub fn memory_by_index(&self, store: &Store, idx: u32) -> Option<Rc<MemoryInstance>> {
store.resolve_module(*self)
.memories
.get(idx as usize)
@ -74,18 +74,6 @@ impl ModuleId {
}
}
#[derive(Copy, Clone, Debug)]
pub struct MemoryId(u32);
impl MemoryId {
pub fn resolve<'s>(&self, store: &'s Store) -> &'s MemoryInstance {
store
.memories
.get(self.0 as usize)
.expect("ID should be always valid")
}
}
#[derive(Copy, Clone, Debug)]
pub struct GlobalId(u32);
@ -93,7 +81,7 @@ pub struct GlobalId(u32);
pub enum ExternVal {
Func(Rc<FuncInstance>),
Table(Rc<TableInstance>),
Memory(MemoryId),
Memory(Rc<MemoryInstance>),
Global(GlobalId),
}
@ -112,9 +100,9 @@ impl ExternVal {
}
}
pub fn as_memory(&self) -> Option<MemoryId> {
pub fn as_memory(&self) -> Option<Rc<MemoryInstance>> {
match *self {
ExternVal::Memory(memory) => Some(memory),
ExternVal::Memory(ref memory) => Some(Rc::clone(memory)),
_ => None,
}
}
@ -199,7 +187,7 @@ pub struct ModuleInstance {
types: Vec<TypeId>,
tables: Vec<Rc<TableInstance>>,
funcs: Vec<Rc<FuncInstance>>,
memories: Vec<MemoryId>,
memories: Vec<Rc<MemoryInstance>>,
globals: Vec<GlobalId>,
exports: HashMap<String, ExternVal>,
}
@ -269,11 +257,9 @@ impl Store {
Ok(Rc::new(table))
}
pub fn alloc_memory(&mut self, mem_type: &MemoryType) -> Result<MemoryId, Error> {
let mem = MemoryInstance::new(&mem_type)?;
self.memories.push(mem);
let mem_id = self.memories.len() - 1;
Ok(MemoryId(mem_id as u32))
pub fn alloc_memory(&mut self, mem_type: &MemoryType) -> Result<Rc<MemoryInstance>, Error> {
let memory = MemoryInstance::new(&mem_type)?;
Ok(Rc::new(memory))
}
pub fn alloc_global(&mut self, global_type: GlobalType, val: RuntimeValue) -> GlobalId {
@ -327,9 +313,9 @@ impl Store {
match_limits(table.limits(), tt.limits())?;
instance.tables.push(Rc::clone(table));
}
(&External::Memory(ref mt), &ExternVal::Memory(memory)) => {
match_limits(memory.resolve(self).limits(), mt.limits())?;
instance.memories.push(memory);
(&External::Memory(ref mt), &ExternVal::Memory(ref memory)) => {
match_limits(memory.limits(), mt.limits())?;
instance.memories.push(Rc::clone(memory));
}
(&External::Global(ref gl), &ExternVal::Global(global)) => {
// TODO: check globals
@ -420,11 +406,11 @@ impl Store {
ExternVal::Global(*global_id)
}
Internal::Memory(idx) => {
let memory_id = instance
let memory = instance
.memories
.get(idx as usize)
.expect("Due to validation memory should exists");
ExternVal::Memory(*memory_id)
ExternVal::Memory(Rc::clone(memory))
}
Internal::Table(idx) => {
let table = instance
@ -482,14 +468,10 @@ impl Store {
_ => panic!("Due to validation data segment offset should evaluate to i32"),
};
let memory_id = instance
let memory_inst = instance
.memories
.get(DEFAULT_MEMORY_INDEX as usize)
.expect("Due to validation default memory should exists");
let memory_inst = self.memories
.get_mut(memory_id.0 as usize)
.expect("ID should be always valid");
memory_inst.set(offset_val, data_segment.value())?;
}

View File

@ -1,12 +1,14 @@
///! Basic tests for instructions/constructions, missing in wabt tests
use std::rc::Rc;
use builder::module;
use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType,
InitExpr, ValueType, Opcodes, Opcode, TableType, MemoryType};
use interpreter::{Error, UserError, ProgramInstance};
use interpreter::value::RuntimeValue;
use interpreter::host::{HostModuleBuilder, HostModule};
use interpreter::store::{Store, MemoryId};
use interpreter::store::Store;
use interpreter::memory::MemoryInstance;
use super::utils::program_with_default_env;
#[test]
@ -114,31 +116,31 @@ impl UserError for UserErrorWithCode {}
// TODO: Rename to state
// user function executor
struct FunctionExecutor {
pub memory: MemoryId,
pub memory: Rc<MemoryInstance>,
pub values: Vec<i32>,
}
fn build_env_module() -> HostModule {
let mut builder = HostModuleBuilder::<FunctionExecutor>::new();
builder.with_func2("add", |store: &mut Store, state: &mut FunctionExecutor, arg: i32, unused: i32| {
let memory_value = state.memory.resolve(store).get(0, 1).unwrap()[0];
builder.with_func2("add", |_store: &mut Store, state: &mut FunctionExecutor, arg: i32, unused: i32| {
let memory_value = state.memory.get(0, 1).unwrap()[0];
let fn_argument_unused = unused as u8;
let fn_argument = arg as u8;
assert_eq!(fn_argument_unused, 0);
let sum = memory_value + fn_argument;
state.memory.resolve(store).set(0, &vec![sum]).unwrap();
state.memory.set(0, &vec![sum]).unwrap();
state.values.push(sum as i32);
Ok(Some(sum as i32))
});
builder.with_func2("sub", |store: &mut Store, state: &mut FunctionExecutor, arg: i32, unused: i32| {
let memory_value = state.memory.resolve(store).get(0, 1).unwrap()[0];
builder.with_func2("sub", |_store: &mut Store, state: &mut FunctionExecutor, arg: i32, unused: i32| {
let memory_value = state.memory.get(0, 1).unwrap()[0];
let fn_argument_unused = unused as u8;
let fn_argument = arg as u8;
assert_eq!(fn_argument_unused, 0);
let diff = memory_value - fn_argument;
state.memory.resolve(store).set(0, &vec![diff]).unwrap();
state.memory.set(0, &vec![diff]).unwrap();
state.values.push(diff as i32);
Ok(Some(diff as i32))
});
@ -208,7 +210,7 @@ fn native_env_function() {
}
}
assert_eq!(state.memory.resolve(program.store()).get(0, 1).unwrap()[0], 42);
assert_eq!(state.memory.get(0, 1).unwrap()[0], 42);
assert_eq!(state.values, vec![7, 57, 42]);
}

View File

@ -465,11 +465,11 @@ fn return_void() {
program.invoke_index("main", 0, vec![RuntimeValue::I32(0)], &mut ()).unwrap();
let memory = module.memory_by_index(program.store(), 0).unwrap();
assert_eq!(memory.resolve(program.store()).get(0, 4).unwrap(), vec![0, 0, 0, 0]);
assert_eq!(memory.get(0, 4).unwrap(), vec![0, 0, 0, 0]);
program.invoke_index("main", 0, vec![RuntimeValue::I32(1)], &mut ()).unwrap();
let memory = module.memory_by_index(program.store(), 0).unwrap();
assert_eq!(memory.resolve(program.store()).get(0, 4).unwrap(), vec![1, 0, 0, 0]);
assert_eq!(memory.get(0, 4).unwrap(), vec![1, 0, 0, 0]);
}
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/call.txt#L3

View File

@ -51,7 +51,7 @@ fn interpreter_accumulate_u8() {
// Place the octet-sequence at index 0 in linear memory
let offset: u32 = 0;
let _ = env_memory.resolve(program.store()).set(offset, BUF);
let _ = env_memory.set(offset, BUF);
// Set up the function argument list and invoke the function
let args = vec![RuntimeValue::I32(BUF.len() as i32), RuntimeValue::I32(offset as i32)];