This commit is contained in:
Svyatoslav Nikolsky
2017-05-02 19:10:23 +03:00
parent 354c444470
commit cf773eceda
5 changed files with 92 additions and 4 deletions

View File

@ -1,8 +1,15 @@
use elements;
use super::invoke::{Invoke, Identity}; use super::invoke::{Invoke, Identity};
pub struct MemoryDefinition { pub struct MemoryDefinition {
pub min: u32, pub min: u32,
pub max: Option<u32>, pub max: Option<u32>,
pub data: Vec<MemoryDataDefinition>,
}
pub struct MemoryDataDefinition {
pub offset: elements::InitExpr,
pub values: Vec<u8>,
} }
pub struct MemoryBuilder<F=Identity> { pub struct MemoryBuilder<F=Identity> {
@ -34,6 +41,14 @@ impl<F> MemoryBuilder<F> where F: Invoke<MemoryDefinition> {
self self
} }
pub fn with_data(mut self, index: u32, values: Vec<u8>) -> Self {
self.memory.data.push(MemoryDataDefinition {
offset: elements::InitExpr::new(vec![elements::Opcode::I32Const(index as i32)]),
values: values,
});
self
}
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke(self.memory) self.callback.invoke(self.memory)
} }
@ -44,6 +59,7 @@ impl Default for MemoryDefinition {
MemoryDefinition { MemoryDefinition {
min: 1, min: 1,
max: None, max: None,
data: Vec::new(),
} }
} }
} }

View File

@ -203,10 +203,15 @@ impl<F> ModuleBuilder<F> where F: Invoke<elements::Module> {
} }
/// Push linear memory region /// Push linear memory region
pub fn push_memory(&mut self, memory: memory::MemoryDefinition) -> u32 { pub fn push_memory(&mut self, mut memory: memory::MemoryDefinition) -> u32 {
let entries = self.module.memory.entries_mut(); let entries = self.module.memory.entries_mut();
entries.push(elements::MemoryType::new(memory.min, memory.max)); entries.push(elements::MemoryType::new(memory.min, memory.max));
(entries.len() - 1) as u32 let memory_index = (entries.len() - 1) as u32;
for data in memory.data.drain(..) {
self.module.data.entries_mut()
.push(elements::DataSegment::new(memory_index, data.offset, data.values))
}
memory_index
} }
/// Push table /// Push table

View File

@ -591,6 +591,11 @@ impl DataSection {
pub fn entries(&self) -> &[DataSegment] { pub fn entries(&self) -> &[DataSegment] {
&self.0 &self.0
} }
/// Mutable list of all data entries in the section
pub fn entries_mut(&mut self) -> &mut Vec<DataSegment> {
&mut self.0
}
} }
impl Deserialize for DataSection { impl Deserialize for DataSection {

View File

@ -1,5 +1,7 @@
///! Tests from https://github.com/WebAssembly/wabt/tree/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp ///! Tests from https://github.com/WebAssembly/wabt/tree/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp
// TODO: https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/import.txt
use std::sync::Weak; use std::sync::Weak;
use builder::module; use builder::module;
use elements::{Module, ValueType, Opcodes, Opcode, BlockType, FunctionType}; use elements::{Module, ValueType, Opcodes, Opcode, BlockType, FunctionType};
@ -2551,3 +2553,63 @@ fn convert_f64() {
assert_eq!(module.execute(3, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); assert_eq!(module.execute(3, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000));
assert_eq!(module.execute(4, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); assert_eq!(module.execute(4, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L9
#[test]
fn load_i32() {
let module = module()
.memory()
.with_data(0, vec![0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xce, 0x41,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x8f, 0x40,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
.build()
.function()
.signature().return_type().i32().build()
.body().with_opcodes(Opcodes::new(vec![
Opcode::I32Const(0),
Opcode::I32Load8S(0, 0),
Opcode::End,
])).build()
.build()
.function()
.signature().return_type().i32().build()
.body().with_opcodes(Opcodes::new(vec![
Opcode::I32Const(0),
Opcode::I32Load16S(0, 0),
Opcode::End,
])).build()
.build()
.function()
.signature().return_type().i32().build()
.body().with_opcodes(Opcodes::new(vec![
Opcode::I32Const(0),
Opcode::I32Load(0, 0),
Opcode::End,
])).build()
.build()
.function()
.signature().return_type().i32().build()
.body().with_opcodes(Opcodes::new(vec![
Opcode::I32Const(0),
Opcode::I32Load8U(0, 0),
Opcode::End,
])).build()
.build()
.function()
.signature().return_type().i32().build()
.body().with_opcodes(Opcodes::new(vec![
Opcode::I32Const(0),
Opcode::I32Load16U(0, 0),
Opcode::End,
])).build()
.build()
.build();
let program = ProgramInstance::new();
let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1));
assert_eq!(module.execute(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1));
assert_eq!(module.execute(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1));
assert_eq!(module.execute(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(255));
assert_eq!(module.execute(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(65535));
}