mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-21 10:41:54 +00:00
builders intial
This commit is contained in:
141
src/builder/code.rs
Normal file
141
src/builder/code.rs
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
use super::invoke::{Invoke, Identity};
|
||||||
|
use elements;
|
||||||
|
|
||||||
|
pub enum Signature {
|
||||||
|
TypeReference(u32),
|
||||||
|
Inline(elements::FunctionType),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SignatureBuilder<F=Identity> {
|
||||||
|
callback: F,
|
||||||
|
signature: Signature,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F> SignatureBuilder<F> where F: Invoke<Signature> {
|
||||||
|
pub fn with_callback(callback: F) -> Self {
|
||||||
|
SignatureBuilder {
|
||||||
|
callback: callback,
|
||||||
|
signature: Signature::TypeReference(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_ref(mut self, val: u32) -> Self {
|
||||||
|
self.signature = Signature::TypeReference(val);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn param(mut self, value_type: elements::ValueType) -> Self {
|
||||||
|
{
|
||||||
|
let signature = &mut self.signature;
|
||||||
|
if let Signature::TypeReference(_) = *signature {
|
||||||
|
*signature = Signature::Inline(elements::FunctionType::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Signature::Inline(ref mut func_type) = *signature {
|
||||||
|
func_type.params_mut().push(value_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn return_type(mut self, value_type: elements::ValueType) -> Self {
|
||||||
|
{
|
||||||
|
let signature = &mut self.signature;
|
||||||
|
if let Signature::TypeReference(_) = *signature {
|
||||||
|
*signature = Signature::Inline(elements::FunctionType::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Signature::Inline(ref mut func_type) = *signature {
|
||||||
|
*func_type.return_type_mut() = Some(value_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(self) -> F::Result {
|
||||||
|
self.callback.invoke(self.signature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FunctionsBuilder<F=Identity> {
|
||||||
|
callback: F,
|
||||||
|
section: Vec<Signature>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FunctionsBuilder {
|
||||||
|
/// New empty functions section builder
|
||||||
|
pub fn new() -> Self {
|
||||||
|
FunctionsBuilder::with_callback(Identity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F> FunctionsBuilder<F> {
|
||||||
|
pub fn with_callback(callback: F) -> Self {
|
||||||
|
FunctionsBuilder {
|
||||||
|
callback: callback,
|
||||||
|
section: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_signature(mut self, signature: Signature) -> Self {
|
||||||
|
self.section.push(signature);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn signature(self) -> SignatureBuilder<Self> {
|
||||||
|
SignatureBuilder::with_callback(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F> Invoke<Signature> for FunctionsBuilder<F> {
|
||||||
|
type Result = Self;
|
||||||
|
|
||||||
|
fn invoke(self, signature: Signature) -> Self {
|
||||||
|
self.with_signature(signature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F> FunctionsBuilder<F> where F: Invoke<elements::FunctionsSection> {
|
||||||
|
pub fn build(self) -> F::Result {
|
||||||
|
let mut result = elements::FunctionsSection::new();
|
||||||
|
for f in self.section.into_iter() {
|
||||||
|
if let Signature::TypeReference(type_ref) = f {
|
||||||
|
result.entries_mut().push(elements::Func::new(type_ref));
|
||||||
|
} else {
|
||||||
|
unreachable!(); // never possible with current generics impl-s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.callback.invoke(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type SignatureBindings = Vec<Signature>;
|
||||||
|
|
||||||
|
impl<F> FunctionsBuilder<F> where F: Invoke<SignatureBindings> {
|
||||||
|
pub fn bind(self) -> F::Result {
|
||||||
|
self.callback.invoke(self.section)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use super::FunctionsBuilder;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn example() {
|
||||||
|
let result = FunctionsBuilder::new()
|
||||||
|
.signature().type_ref(1).build()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assert_eq!(result.entries().len(), 1);
|
||||||
|
|
||||||
|
let result = FunctionsBuilder::new()
|
||||||
|
.signature().type_ref(1).build()
|
||||||
|
.bind();
|
||||||
|
|
||||||
|
assert_eq!(result.len(), 1);
|
||||||
|
}
|
||||||
|
}
|
15
src/builder/invoke.rs
Normal file
15
src/builder/invoke.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//! invoke helper
|
||||||
|
|
||||||
|
pub trait Invoke<A> {
|
||||||
|
type Result;
|
||||||
|
|
||||||
|
fn invoke(self, arg: A) -> Self::Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Identity;
|
||||||
|
|
||||||
|
impl<A> Invoke<A> for Identity {
|
||||||
|
type Result = A;
|
||||||
|
|
||||||
|
fn invoke(self, arg: A) -> A { arg }
|
||||||
|
}
|
7
src/builder/mod.rs
Normal file
7
src/builder/mod.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
//! Various builders to generate/alter wasm components
|
||||||
|
|
||||||
|
mod invoke;
|
||||||
|
mod module;
|
||||||
|
mod code;
|
||||||
|
|
||||||
|
pub use self::module::{module, ModuleBuilder};
|
76
src/builder/module.rs
Normal file
76
src/builder/module.rs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
use super::invoke::{Invoke, Identity};
|
||||||
|
use super::code::FunctionsBuilder;
|
||||||
|
use elements;
|
||||||
|
|
||||||
|
/// Module builder
|
||||||
|
pub struct ModuleBuilder<F=Identity> {
|
||||||
|
callback: F,
|
||||||
|
sections: Vec<elements::Section>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModuleBuilder {
|
||||||
|
/// New empty module builder
|
||||||
|
pub fn new() -> Self {
|
||||||
|
ModuleBuilder::with_callback(Identity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F> ModuleBuilder<F> where F: Invoke<elements::Module> {
|
||||||
|
/// New module builder with bound callback
|
||||||
|
pub fn with_callback(callback: F) -> Self {
|
||||||
|
ModuleBuilder {
|
||||||
|
callback: callback,
|
||||||
|
sections: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fill module with sections from iterator
|
||||||
|
pub fn with_sections<I>(mut self, sections: I) -> Self
|
||||||
|
where I: IntoIterator<Item=elements::Section>
|
||||||
|
{
|
||||||
|
self.sections.extend(sections);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_section(mut self, section: elements::Section) -> Self {
|
||||||
|
self.sections.push(section);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn functions(self) -> FunctionsBuilder<Self> {
|
||||||
|
FunctionsBuilder::with_callback(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build module (final step)
|
||||||
|
pub fn build(self) -> F::Result {
|
||||||
|
self.callback.invoke(elements::Module::new(self.sections))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F> Invoke<elements::FunctionsSection> for ModuleBuilder<F>
|
||||||
|
where F: Invoke<elements::Module>
|
||||||
|
{
|
||||||
|
type Result = Self;
|
||||||
|
|
||||||
|
fn invoke(self, section: elements::FunctionsSection) -> Self {
|
||||||
|
self.with_section(elements::Section::Function(section))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start new module builder
|
||||||
|
pub fn module() -> ModuleBuilder {
|
||||||
|
ModuleBuilder::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use super::module;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn smoky() {
|
||||||
|
let module = module().build();
|
||||||
|
assert_eq!(module.sections().len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -14,7 +14,10 @@ mod func;
|
|||||||
mod segment;
|
mod segment;
|
||||||
|
|
||||||
pub use self::module::Module;
|
pub use self::module::Module;
|
||||||
pub use self::section::Section;
|
pub use self::section::{
|
||||||
|
Section, FunctionsSection, CodeSection, MemorySection, DataSection,
|
||||||
|
ImportSection, ExportSection, GlobalSection,
|
||||||
|
};
|
||||||
pub use self::import_entry::{ImportEntry, MemoryType, TableType, GlobalType, External};
|
pub use self::import_entry::{ImportEntry, MemoryType, TableType, GlobalType, External};
|
||||||
pub use self::export_entry::{ExportEntry, Internal};
|
pub use self::export_entry::{ExportEntry, Internal};
|
||||||
pub use self::global_entry::GlobalEntry;
|
pub use self::global_entry::GlobalEntry;
|
||||||
@ -22,7 +25,7 @@ pub use self::primitives::{
|
|||||||
VarUint32, VarUint7, VarUint1, VarInt7, Uint32,
|
VarUint32, VarUint7, VarUint1, VarInt7, Uint32,
|
||||||
Uint64, VarUint64, CountedList, CountedWriter, CountedListWriter,
|
Uint64, VarUint64, CountedList, CountedWriter, CountedListWriter,
|
||||||
};
|
};
|
||||||
pub use self::types::{ValueType, BlockType};
|
pub use self::types::{ValueType, BlockType, FunctionType};
|
||||||
pub use self::ops::{Opcode, Opcodes, InitExpr};
|
pub use self::ops::{Opcode, Opcodes, InitExpr};
|
||||||
pub use self::func::{Func, FuncBody, Local};
|
pub use self::func::{Func, FuncBody, Local};
|
||||||
pub use self::segment::{ElementSegment, DataSegment};
|
pub use self::segment::{ElementSegment, DataSegment};
|
||||||
|
@ -10,6 +10,15 @@ pub struct Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Module {
|
impl Module {
|
||||||
|
/// New module with sections
|
||||||
|
pub fn new(sections: Vec<Section>) -> Self {
|
||||||
|
Module {
|
||||||
|
magic: 0x6d736100,
|
||||||
|
version: 1,
|
||||||
|
sections: sections,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Version of module.
|
/// Version of module.
|
||||||
pub fn version(&self) -> u32 { self.version }
|
pub fn version(&self) -> u32 { self.version }
|
||||||
|
|
||||||
|
@ -251,6 +251,14 @@ impl Serialize for ImportSection {
|
|||||||
pub struct FunctionsSection(Vec<Func>);
|
pub struct FunctionsSection(Vec<Func>);
|
||||||
|
|
||||||
impl FunctionsSection {
|
impl FunctionsSection {
|
||||||
|
pub fn new() -> FunctionsSection {
|
||||||
|
FunctionsSection(Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn entries_mut(&mut self) -> &mut Vec<Func> {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
|
||||||
pub fn entries(&self) -> &[Func] {
|
pub fn entries(&self) -> &[Func] {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
@ -121,13 +121,27 @@ pub struct FunctionType {
|
|||||||
return_type: Option<ValueType>,
|
return_type: Option<ValueType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for FunctionType {
|
||||||
|
fn default() -> Self {
|
||||||
|
FunctionType {
|
||||||
|
form: 0x60,
|
||||||
|
params: Vec::new(),
|
||||||
|
return_type: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FunctionType {
|
impl FunctionType {
|
||||||
/// Function form (currently only valid value is `0x60`)
|
/// Function form (currently only valid value is `0x60`)
|
||||||
pub fn form(&self) -> u8 { self.form }
|
pub fn form(&self) -> u8 { self.form }
|
||||||
/// Parameters in the function signature.
|
/// Parameters in the function signature.
|
||||||
pub fn params(&self) -> &[ValueType] { &self.params }
|
pub fn params(&self) -> &[ValueType] { &self.params }
|
||||||
|
/// Mutable parameters in the function signature.
|
||||||
|
pub fn params_mut(&mut self) -> &mut Vec<ValueType> { &mut self.params }
|
||||||
/// Return type in the function signature, if any.
|
/// Return type in the function signature, if any.
|
||||||
pub fn return_type(&self) -> Option<ValueType> { self.return_type }
|
pub fn return_type(&self) -> Option<ValueType> { self.return_type }
|
||||||
|
/// Mutable type in the function signature, if any.
|
||||||
|
pub fn return_type_mut(&mut self) -> &mut Option<ValueType> { &mut self.return_type }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deserialize for FunctionType {
|
impl Deserialize for FunctionType {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
|
||||||
pub mod elements;
|
pub mod elements;
|
||||||
|
pub mod builder;
|
||||||
|
|
||||||
pub use elements::{
|
pub use elements::{
|
||||||
Error as SerializationError,
|
Error as SerializationError,
|
||||||
|
Reference in New Issue
Block a user