mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-07-06 18:11:54 +00:00
Replace all memories with Rcs
This commit is contained in:
@ -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()
|
||||
|
@ -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())?;
|
||||
}
|
||||
|
||||
|
@ -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]);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)];
|
||||
|
Reference in New Issue
Block a user