mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-13 23:11:53 +00:00
callindirect_1
This commit is contained in:
@ -6,6 +6,7 @@ mod code;
|
|||||||
mod misc;
|
mod misc;
|
||||||
mod import;
|
mod import;
|
||||||
mod memory;
|
mod memory;
|
||||||
|
mod table;
|
||||||
|
|
||||||
pub use self::module::{module, from_module, ModuleBuilder};
|
pub use self::module::{module, from_module, ModuleBuilder};
|
||||||
pub use self::code::{signatures, signature, function};
|
pub use self::code::{signatures, signature, function};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use super::invoke::{Invoke, Identity};
|
use super::invoke::{Invoke, Identity};
|
||||||
use super::code::{self, SignaturesBuilder, FunctionBuilder};
|
use super::code::{self, SignaturesBuilder, FunctionBuilder};
|
||||||
use super::memory::{self, MemoryBuilder};
|
use super::memory::{self, MemoryBuilder};
|
||||||
|
use super::table::{self, TableBuilder};
|
||||||
use super::import;
|
use super::import;
|
||||||
use elements;
|
use elements;
|
||||||
|
|
||||||
@ -208,6 +209,18 @@ impl<F> ModuleBuilder<F> where F: Invoke<elements::Module> {
|
|||||||
(entries.len() - 1) as u32
|
(entries.len() - 1) as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Push table
|
||||||
|
pub fn push_table(&mut self, mut table: table::TableDefinition) -> u32 {
|
||||||
|
let entries = self.module.table.entries_mut();
|
||||||
|
entries.push(elements::TableType::new(table.min, Some(table.min)));
|
||||||
|
let table_index = (entries.len() - 1) as u32;
|
||||||
|
for entry in table.elements.drain(..) {
|
||||||
|
self.module.element.entries_mut()
|
||||||
|
.push(elements::ElementSegment::new(table_index, entry.offset, entry.values))
|
||||||
|
}
|
||||||
|
table_index
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_type_ref(&mut self, signature: code::Signature) -> u32 {
|
fn resolve_type_ref(&mut self, signature: code::Signature) -> u32 {
|
||||||
match signature {
|
match signature {
|
||||||
code::Signature::Inline(func_type) => {
|
code::Signature::Inline(func_type) => {
|
||||||
@ -254,6 +267,11 @@ impl<F> ModuleBuilder<F> where F: Invoke<elements::Module> {
|
|||||||
MemoryBuilder::with_callback(self)
|
MemoryBuilder::with_callback(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add new table using dedicated builder
|
||||||
|
pub fn table(self) -> TableBuilder<Self> {
|
||||||
|
TableBuilder::with_callback(self)
|
||||||
|
}
|
||||||
|
|
||||||
/// Define functions section
|
/// Define functions section
|
||||||
pub fn functions(self) -> SignaturesBuilder<Self> {
|
pub fn functions(self) -> SignaturesBuilder<Self> {
|
||||||
SignaturesBuilder::with_callback(self)
|
SignaturesBuilder::with_callback(self)
|
||||||
@ -321,6 +339,18 @@ impl<F> Invoke<memory::MemoryDefinition> for ModuleBuilder<F>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F> Invoke<table::TableDefinition> for ModuleBuilder<F>
|
||||||
|
where F: Invoke<elements::Module>
|
||||||
|
{
|
||||||
|
type Result = Self;
|
||||||
|
|
||||||
|
fn invoke(self, def: table::TableDefinition) -> Self {
|
||||||
|
let mut b = self;
|
||||||
|
b.push_table(def);
|
||||||
|
b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<F> Invoke<elements::ImportEntry> for ModuleBuilder<F>
|
impl<F> Invoke<elements::ImportEntry> for ModuleBuilder<F>
|
||||||
where F: Invoke<elements::Module>
|
where F: Invoke<elements::Module>
|
||||||
{
|
{
|
||||||
|
58
src/builder/table.rs
Normal file
58
src/builder/table.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use elements;
|
||||||
|
use super::invoke::{Invoke, Identity};
|
||||||
|
|
||||||
|
pub struct TableDefinition {
|
||||||
|
pub min: u32,
|
||||||
|
pub elements: Vec<TableEntryDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TableEntryDefinition {
|
||||||
|
pub offset: elements::InitExpr,
|
||||||
|
pub values: Vec<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TableBuilder<F=Identity> {
|
||||||
|
callback: F,
|
||||||
|
table: TableDefinition,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TableBuilder {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
TableBuilder::with_callback(Identity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F> TableBuilder<F> where F: Invoke<TableDefinition> {
|
||||||
|
pub fn with_callback(callback: F) -> Self {
|
||||||
|
TableBuilder {
|
||||||
|
callback: callback,
|
||||||
|
table: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_min(mut self, min: u32) -> Self {
|
||||||
|
self.table.min = min;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_element(mut self, index: u32, values: Vec<u32>) -> Self {
|
||||||
|
self.table.elements.push(TableEntryDefinition {
|
||||||
|
offset: elements::InitExpr::new(vec![elements::Opcode::I32Const(index as i32)]),
|
||||||
|
values: values,
|
||||||
|
});
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(self) -> F::Result {
|
||||||
|
self.callback.invoke(self.table)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TableDefinition {
|
||||||
|
fn default() -> Self {
|
||||||
|
TableDefinition {
|
||||||
|
min: 0,
|
||||||
|
elements: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -323,6 +323,11 @@ impl TableSection {
|
|||||||
pub fn entries(&self) -> &[TableType] {
|
pub fn entries(&self) -> &[TableType] {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mutable table entries.
|
||||||
|
pub fn entries_mut(&mut self) -> &mut Vec<TableType> {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deserialize for TableSection {
|
impl Deserialize for TableSection {
|
||||||
@ -538,6 +543,11 @@ impl ElementSection {
|
|||||||
pub fn entries(&self) -> &[ElementSegment] {
|
pub fn entries(&self) -> &[ElementSegment] {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mutable elements entries in the section
|
||||||
|
pub fn entries_mut(&mut self) -> &mut Vec<ElementSegment> {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deserialize for ElementSection {
|
impl Deserialize for ElementSection {
|
||||||
|
@ -649,3 +649,56 @@ fn call_zero_args() {
|
|||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_main(vec![]).unwrap().unwrap(), RuntimeValue::I32(43));
|
assert_eq!(module.execute_main(vec![]).unwrap().unwrap(), RuntimeValue::I32(43));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/callimport-zero-args.txt
|
||||||
|
#[test]
|
||||||
|
fn callimport_zero_zrgs() {
|
||||||
|
// TODO: import needed
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/callindirect.txt#L31
|
||||||
|
#[test]
|
||||||
|
fn callindirect_1() {
|
||||||
|
let body1 = Opcodes::new(vec![
|
||||||
|
Opcode::I32Const(0),
|
||||||
|
Opcode::End,
|
||||||
|
]);
|
||||||
|
|
||||||
|
let body2 = Opcodes::new(vec![
|
||||||
|
Opcode::I32Const(1),
|
||||||
|
Opcode::End,
|
||||||
|
]);
|
||||||
|
|
||||||
|
let body3 = Opcodes::new(vec![
|
||||||
|
Opcode::GetLocal(0),
|
||||||
|
Opcode::CallIndirect(0, false),
|
||||||
|
Opcode::End,
|
||||||
|
]);
|
||||||
|
|
||||||
|
let module = module()
|
||||||
|
.table()
|
||||||
|
.with_min(2)
|
||||||
|
.with_element(0, vec![0, 1])
|
||||||
|
.build()
|
||||||
|
.function()
|
||||||
|
.signature().return_type().i32().build()
|
||||||
|
.body().with_opcodes(body1).build()
|
||||||
|
.build()
|
||||||
|
.function()
|
||||||
|
.signature().return_type().i32().build()
|
||||||
|
.body().with_opcodes(body2).build()
|
||||||
|
.build()
|
||||||
|
.function().main()
|
||||||
|
.signature()
|
||||||
|
.param().i32()
|
||||||
|
.return_type().i32()
|
||||||
|
.build()
|
||||||
|
.body().with_opcodes(body3).build()
|
||||||
|
.build()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let program = ProgramInstance::new();
|
||||||
|
let module = program.add_module("main", module).unwrap();
|
||||||
|
assert_eq!(module.execute_main(vec![RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
|
assert_eq!(module.execute_main(vec![RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user