Merge 'origin/master' into api-overhaul

Conflicts:
	src/interpreter/native.rs
	src/interpreter/runner.rs
	src/interpreter/tests/wabt.rs
	src/interpreter/validator.rs
This commit is contained in:
Sergey Pepyakin 2018-01-17 16:55:33 +03:00
commit 367807663d
21 changed files with 192 additions and 57 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "parity-wasm" name = "parity-wasm"
version = "0.19.0" version = "0.20.0"
authors = ["Nikolay Volf <nikvolf@gmail.com>", "Svyatoslav Nikolsky <svyatonik@yandex.ru>", "Sergey Shulepov <s.pepyakin@gmail.com>"] authors = ["Nikolay Volf <nikvolf@gmail.com>", "Svyatoslav Nikolsky <svyatonik@yandex.ru>", "Sergey Shulepov <s.pepyakin@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
readme = "README.md" readme = "README.md"

View File

@ -13,8 +13,8 @@ along with experimental interpreter
extern crate parity_wasm; extern crate parity_wasm;
let module = parity_wasm::deserialize_file("./res/cases/v1/hello.wasm"); let module = parity_wasm::deserialize_file("./res/cases/v1/hello.wasm").unwrap();
assert_eq!(module.code_section().is_some()); assert!(module.code_section().is_some());
let code_section = module.code_section().unwrap(); // Part of the module with functions code let code_section = module.code_section().unwrap(); // Part of the module with functions code

View File

@ -2,61 +2,73 @@ use elements;
use super::invoke::{Invoke, Identity}; use super::invoke::{Invoke, Identity};
use super::misc::{ValueTypeBuilder, ValueTypesBuilder, OptionalValueTypeBuilder}; use super::misc::{ValueTypeBuilder, ValueTypesBuilder, OptionalValueTypeBuilder};
/// Signature template description
pub enum Signature { pub enum Signature {
TypeReference(u32), TypeReference(u32),
Inline(elements::FunctionType), Inline(elements::FunctionType),
} }
/// Signature builder
pub struct SignatureBuilder<F=Identity> { pub struct SignatureBuilder<F=Identity> {
callback: F, callback: F,
signature: elements::FunctionType, signature: elements::FunctionType,
} }
impl SignatureBuilder { impl SignatureBuilder {
/// New signature builder
pub fn new() -> Self { pub fn new() -> Self {
SignatureBuilder::with_callback(Identity) SignatureBuilder::with_callback(Identity)
} }
} }
impl<F> SignatureBuilder<F> where F: Invoke<elements::FunctionType> { impl<F> SignatureBuilder<F> where F: Invoke<elements::FunctionType> {
/// New builder with callback function specified
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
SignatureBuilder { SignatureBuilder {
callback: callback, callback: callback,
signature: elements::FunctionType::default(), signature: elements::FunctionType::default(),
} }
} }
/// Add argument to signature builder
pub fn with_param(mut self, value_type: elements::ValueType) -> Self { pub fn with_param(mut self, value_type: elements::ValueType) -> Self {
self.signature.params_mut().push(value_type); self.signature.params_mut().push(value_type);
self self
} }
/// Add multiple arguments to signature builder
pub fn with_params(mut self, value_types: Vec<elements::ValueType>) -> Self { pub fn with_params(mut self, value_types: Vec<elements::ValueType>) -> Self {
self.signature.params_mut().extend(value_types); self.signature.params_mut().extend(value_types);
self self
} }
/// Override signature return type
pub fn with_return_type(mut self, return_type: Option<elements::ValueType>) -> Self { pub fn with_return_type(mut self, return_type: Option<elements::ValueType>) -> Self {
*self.signature.return_type_mut() = return_type; *self.signature.return_type_mut() = return_type;
self self
} }
/// Start build new argument
pub fn param(self) -> ValueTypeBuilder<Self> { pub fn param(self) -> ValueTypeBuilder<Self> {
ValueTypeBuilder::with_callback(self) ValueTypeBuilder::with_callback(self)
} }
/// Start build multiple arguments
pub fn params(self) -> ValueTypesBuilder<Self> { pub fn params(self) -> ValueTypesBuilder<Self> {
ValueTypesBuilder::with_callback(self) ValueTypesBuilder::with_callback(self)
} }
/// Start building return type
pub fn return_type(self) -> OptionalValueTypeBuilder<Self> { pub fn return_type(self) -> OptionalValueTypeBuilder<Self> {
OptionalValueTypeBuilder::with_callback(self) OptionalValueTypeBuilder::with_callback(self)
} }
/// Finish current builder
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke(self.signature) self.callback.invoke(self.signature)
} }
/// Finish current builder returning intermediate `Signature` struct
pub fn build_sig(self) -> Signature { pub fn build_sig(self) -> Signature {
Signature::Inline(self.signature) Signature::Inline(self.signature)
} }
@ -82,8 +94,8 @@ impl<F> Invoke<Option<elements::ValueType>> for SignatureBuilder<F>
} }
} }
impl<F> Invoke<elements::ValueType> for SignatureBuilder<F> impl<F> Invoke<elements::ValueType> for SignatureBuilder<F>
where F: Invoke<elements::FunctionType> where F: Invoke<elements::FunctionType>
{ {
type Result = Self; type Result = Self;
@ -92,27 +104,32 @@ impl<F> Invoke<elements::ValueType> for SignatureBuilder<F>
} }
} }
/// Type (signature) reference builder (for function/import/indirect call)
pub struct TypeRefBuilder<F=Identity> { pub struct TypeRefBuilder<F=Identity> {
callback: F, callback: F,
type_ref: u32, type_ref: u32,
} }
impl<F> TypeRefBuilder<F> where F: Invoke<u32> { impl<F> TypeRefBuilder<F> where F: Invoke<u32> {
/// New builder chained with specified callback
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
TypeRefBuilder { TypeRefBuilder {
callback: callback, callback: callback,
type_ref: 0 type_ref: 0
} }
} }
/// Set/override of type reference
pub fn val(mut self, val: u32) -> Self { pub fn val(mut self, val: u32) -> Self {
self.type_ref = val; self.type_ref = val;
self self
} }
/// Finish current builder
pub fn build(self) -> F::Result { self.callback.invoke(self.type_ref) } pub fn build(self) -> F::Result { self.callback.invoke(self.type_ref) }
} }
/// Multiple signatures builder
pub struct SignaturesBuilder<F=Identity> { pub struct SignaturesBuilder<F=Identity> {
callback: F, callback: F,
section: Vec<Signature>, section: Vec<Signature>,
@ -126,6 +143,7 @@ impl SignaturesBuilder {
} }
impl<F> SignaturesBuilder<F> { impl<F> SignaturesBuilder<F> {
/// New builder chained with specified callback
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
SignaturesBuilder { SignaturesBuilder {
callback: callback, callback: callback,
@ -133,17 +151,20 @@ impl<F> SignaturesBuilder<F> {
} }
} }
/// Push new signature into the builder output
pub fn with_signature(mut self, signature: Signature) -> Self { pub fn with_signature(mut self, signature: Signature) -> Self {
self.section.push(signature); self.section.push(signature);
self self
} }
/// Start building new signature with `TypeRefBuilder`
pub fn type_ref(self) -> TypeRefBuilder<Self> { pub fn type_ref(self) -> TypeRefBuilder<Self> {
TypeRefBuilder::with_callback(self) TypeRefBuilder::with_callback(self)
} }
} }
impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> { impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> {
/// Start building new signature with dedicated builder
pub fn signature(self) -> SignatureBuilder<Self> { pub fn signature(self) -> SignatureBuilder<Self> {
SignatureBuilder::with_callback(self) SignatureBuilder::with_callback(self)
} }
@ -154,7 +175,7 @@ impl<F> Invoke<elements::FunctionType> for SignaturesBuilder<F> {
fn invoke(self, signature: elements::FunctionType) -> Self { fn invoke(self, signature: elements::FunctionType) -> Self {
self.with_signature(Signature::Inline(signature)) self.with_signature(Signature::Inline(signature))
} }
} }
impl<F> Invoke<u32> for SignaturesBuilder<F> { impl<F> Invoke<u32> for SignaturesBuilder<F> {
@ -162,10 +183,12 @@ impl<F> Invoke<u32> for SignaturesBuilder<F> {
fn invoke(self, type_ref: u32) -> Self { fn invoke(self, type_ref: u32) -> Self {
self.with_signature(Signature::TypeReference(type_ref)) self.with_signature(Signature::TypeReference(type_ref))
} }
} }
impl<F> SignaturesBuilder<F> where F: Invoke<elements::FunctionSection> { impl<F> SignaturesBuilder<F> where F: Invoke<elements::FunctionSection> {
/// Finalize builder spawning element
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
let mut result = elements::FunctionSection::default(); let mut result = elements::FunctionSection::default();
for f in self.section.into_iter() { for f in self.section.into_iter() {
@ -179,20 +202,24 @@ impl<F> SignaturesBuilder<F> where F: Invoke<elements::FunctionSection> {
} }
} }
/// Signature bindings
pub type SignatureBindings = Vec<Signature>; pub type SignatureBindings = Vec<Signature>;
impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> { impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> {
/// Bind signature list
pub fn bind(self) -> F::Result { pub fn bind(self) -> F::Result {
self.callback.invoke(self.section) self.callback.invoke(self.section)
} }
} }
/// Function body (code) builder
pub struct FuncBodyBuilder<F=Identity> { pub struct FuncBodyBuilder<F=Identity> {
callback: F, callback: F,
body: elements::FuncBody, body: elements::FuncBody,
} }
impl<F> FuncBodyBuilder<F> { impl<F> FuncBodyBuilder<F> {
/// New body (code) builder given the chain callback
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
FuncBodyBuilder { FuncBodyBuilder {
callback: callback, callback: callback,
@ -202,29 +229,37 @@ impl<F> FuncBodyBuilder<F> {
} }
impl<F> FuncBodyBuilder<F> where F: Invoke<elements::FuncBody> { impl<F> FuncBodyBuilder<F> where F: Invoke<elements::FuncBody> {
/// Set/override entirely with FuncBody struct
pub fn with_func(mut self, func: elements::FuncBody) -> Self { pub fn with_func(mut self, func: elements::FuncBody) -> Self {
self.body = func; self.body = func;
self self
} }
/// Extend function local list with new entries
pub fn with_locals(mut self, locals: Vec<elements::Local>) -> Self { pub fn with_locals(mut self, locals: Vec<elements::Local>) -> Self {
self.body.locals_mut().extend(locals); self.body.locals_mut().extend(locals);
self self
} }
/// Set code of the function
pub fn with_opcodes(mut self, opcodes: elements::Opcodes) -> Self { pub fn with_opcodes(mut self, opcodes: elements::Opcodes) -> Self {
*self.body.code_mut() = opcodes; *self.body.code_mut() = opcodes;
self self
} }
/// Finish current builder spawning resulting struct
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke(self.body) self.callback.invoke(self.body)
} }
} }
/// Function definition (extended structure to specify function entirely, incl. signature, mainness and code)
pub struct FunctionDefinition { pub struct FunctionDefinition {
/// Is this function is start function
pub is_main: bool, pub is_main: bool,
/// Signature description
pub signature: Signature, pub signature: Signature,
/// Body (code) of the function
pub code: elements::FuncBody, pub code: elements::FuncBody,
} }
@ -238,18 +273,21 @@ impl Default for FunctionDefinition {
} }
} }
/// Function definition builder
pub struct FunctionBuilder<F=Identity> { pub struct FunctionBuilder<F=Identity> {
callback: F, callback: F,
func: FunctionDefinition, func: FunctionDefinition,
} }
impl FunctionBuilder { impl FunctionBuilder {
/// New function builder
pub fn new() -> Self { pub fn new() -> Self {
FunctionBuilder::with_callback(Identity) FunctionBuilder::with_callback(Identity)
} }
} }
impl<F> FunctionBuilder<F> where F: Invoke<FunctionDefinition> { impl<F> FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
/// New function builder with chained callback
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
FunctionBuilder { FunctionBuilder {
callback: callback, callback: callback,
@ -257,29 +295,35 @@ impl<F> FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
} }
} }
/// Set that this function is main entry point
pub fn main(mut self) -> Self { pub fn main(mut self) -> Self {
self.func.is_main = true; self.func.is_main = true;
self self
} }
/// Start signature builder of the function
pub fn signature(self) -> SignatureBuilder<Self> { pub fn signature(self) -> SignatureBuilder<Self> {
SignatureBuilder::with_callback(self) SignatureBuilder::with_callback(self)
} }
/// Override current signature entirely with new one from known struct
pub fn with_signature(mut self, signature: Signature) -> Self { pub fn with_signature(mut self, signature: Signature) -> Self {
self.func.signature = signature; self.func.signature = signature;
self self
} }
/// Start code (body) builder
pub fn body(self) -> FuncBodyBuilder<Self> { pub fn body(self) -> FuncBodyBuilder<Self> {
FuncBodyBuilder::with_callback(self) FuncBodyBuilder::with_callback(self)
} }
/// Set body (code) for this function
pub fn with_body(mut self, body: elements::FuncBody) -> Self { pub fn with_body(mut self, body: elements::FuncBody) -> Self {
self.func.code = body; self.func.code = body;
self self
} }
/// Finalize current builder spawning resulting struct in the callback
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke(self.func) self.callback.invoke(self.func)
} }
@ -290,7 +334,7 @@ impl<F> Invoke<elements::FunctionType> for FunctionBuilder<F> where F: Invoke<Fu
fn invoke(self, signature: elements::FunctionType) -> Self { fn invoke(self, signature: elements::FunctionType) -> Self {
self.with_signature(Signature::Inline(signature)) self.with_signature(Signature::Inline(signature))
} }
} }
impl<F> Invoke<u32> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> { impl<F> Invoke<u32> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
@ -298,7 +342,7 @@ impl<F> Invoke<u32> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
fn invoke(self, type_ref: u32) -> Self { fn invoke(self, type_ref: u32) -> Self {
self.with_signature(Signature::TypeReference(type_ref)) self.with_signature(Signature::TypeReference(type_ref))
} }
} }
impl<F> Invoke<elements::FuncBody> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> { impl<F> Invoke<elements::FuncBody> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
@ -344,7 +388,7 @@ mod tests {
.param().i32() .param().i32()
.return_type().i64() .return_type().i64()
.build() .build()
.bind(); .bind();
assert_eq!(result.len(), 1); assert_eq!(result.len(), 1);
} }

View File

@ -1,6 +1,7 @@
use super::invoke::{Identity, Invoke}; use super::invoke::{Identity, Invoke};
use elements; use elements;
/// Data segment builder
pub struct DataSegmentBuilder<F=Identity> { pub struct DataSegmentBuilder<F=Identity> {
callback: F, callback: F,
// todo: add mapper once multiple memory refs possible // todo: add mapper once multiple memory refs possible
@ -10,12 +11,14 @@ pub struct DataSegmentBuilder<F=Identity> {
} }
impl DataSegmentBuilder { impl DataSegmentBuilder {
/// New data segment builder
pub fn new() -> Self { pub fn new() -> Self {
DataSegmentBuilder::with_callback(Identity) DataSegmentBuilder::with_callback(Identity)
} }
} }
impl<F> DataSegmentBuilder<F> { impl<F> DataSegmentBuilder<F> {
/// New data segment builder inside the chain context
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
DataSegmentBuilder { DataSegmentBuilder {
callback: callback, callback: callback,
@ -25,11 +28,13 @@ impl<F> DataSegmentBuilder<F> {
} }
} }
/// Set offset initialization opcode. `End` opcode will be added automatically.
pub fn offset(mut self, opcode: elements::Opcode) -> Self { pub fn offset(mut self, opcode: elements::Opcode) -> Self {
self.offset = elements::InitExpr::new(vec![opcode, elements::Opcode::End]); self.offset = elements::InitExpr::new(vec![opcode, elements::Opcode::End]);
self self
} }
/// Set the bytes value of the segment
pub fn value(mut self, value: Vec<u8>) -> Self { pub fn value(mut self, value: Vec<u8>) -> Self {
self.value = value; self.value = value;
self self
@ -37,6 +42,7 @@ impl<F> DataSegmentBuilder<F> {
} }
impl<F> DataSegmentBuilder<F> where F: Invoke<elements::DataSegment> { impl<F> DataSegmentBuilder<F> where F: Invoke<elements::DataSegment> {
/// Finish current builder, spawning resulting struct
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke( self.callback.invoke(
elements::DataSegment::new( elements::DataSegment::new(

View File

@ -1,6 +1,7 @@
use super::invoke::{Invoke, Identity}; use super::invoke::{Invoke, Identity};
use elements; use elements;
/// Export entry builder
pub struct ExportBuilder<F=Identity> { pub struct ExportBuilder<F=Identity> {
callback: F, callback: F,
field: String, field: String,
@ -8,6 +9,7 @@ pub struct ExportBuilder<F=Identity> {
} }
impl ExportBuilder { impl ExportBuilder {
/// New export builder
pub fn new() -> Self { pub fn new() -> Self {
ExportBuilder::with_callback(Identity) ExportBuilder::with_callback(Identity)
} }
@ -15,6 +17,7 @@ impl ExportBuilder {
impl<F> ExportBuilder<F> { impl<F> ExportBuilder<F> {
/// New export entry builder in the specified chained context
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
ExportBuilder { ExportBuilder {
callback: callback, callback: callback,
@ -23,22 +26,26 @@ impl<F> ExportBuilder<F> {
} }
} }
/// Set the field name of the export entry
pub fn field(mut self, field: &str) -> Self { pub fn field(mut self, field: &str) -> Self {
self.field = field.to_owned(); self.field = field.to_owned();
self self
} }
/// Specify the internal module mapping for this entry
pub fn with_internal(mut self, external: elements::Internal) -> Self { pub fn with_internal(mut self, external: elements::Internal) -> Self {
self.binding = external; self.binding = external;
self self
} }
/// Start the internal builder for this export entry
pub fn internal(self) -> ExportInternalBuilder<Self> { pub fn internal(self) -> ExportInternalBuilder<Self> {
ExportInternalBuilder::with_callback(self) ExportInternalBuilder::with_callback(self)
} }
} }
impl<F> ExportBuilder<F> where F: Invoke<elements::ExportEntry> { impl<F> ExportBuilder<F> where F: Invoke<elements::ExportEntry> {
/// Finalize export entry builder spawning the resulting struct
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke(elements::ExportEntry::new(self.field, self.binding)) self.callback.invoke(elements::ExportEntry::new(self.field, self.binding))
} }
@ -51,12 +58,14 @@ impl<F> Invoke<elements::Internal> for ExportBuilder<F> {
} }
} }
/// Internal mapping builder for export entry
pub struct ExportInternalBuilder<F=Identity> { pub struct ExportInternalBuilder<F=Identity> {
callback: F, callback: F,
binding: elements::Internal, binding: elements::Internal,
} }
impl<F> ExportInternalBuilder<F> where F: Invoke<elements::Internal> { impl<F> ExportInternalBuilder<F> where F: Invoke<elements::Internal> {
/// New export entry internal mapping for the chained context
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
ExportInternalBuilder{ ExportInternalBuilder{
callback: callback, callback: callback,
@ -64,21 +73,25 @@ impl<F> ExportInternalBuilder<F> where F: Invoke<elements::Internal> {
} }
} }
/// Map to function by index
pub fn func(mut self, index: u32) -> F::Result { pub fn func(mut self, index: u32) -> F::Result {
self.binding = elements::Internal::Function(index); self.binding = elements::Internal::Function(index);
self.callback.invoke(self.binding) self.callback.invoke(self.binding)
} }
/// Map to memory
pub fn memory(mut self, index: u32) -> F::Result { pub fn memory(mut self, index: u32) -> F::Result {
self.binding = elements::Internal::Memory(index); self.binding = elements::Internal::Memory(index);
self.callback.invoke(self.binding) self.callback.invoke(self.binding)
} }
/// Map to table
pub fn table(mut self, index: u32) -> F::Result { pub fn table(mut self, index: u32) -> F::Result {
self.binding = elements::Internal::Table(index); self.binding = elements::Internal::Table(index);
self.callback.invoke(self.binding) self.callback.invoke(self.binding)
} }
/// Map to global
pub fn global(mut self, index: u32) -> F::Result { pub fn global(mut self, index: u32) -> F::Result {
self.binding = elements::Internal::Global(index); self.binding = elements::Internal::Global(index);
self.callback.invoke(self.binding) self.callback.invoke(self.binding)

View File

@ -2,6 +2,7 @@ use super::invoke::{Invoke, Identity};
use super::misc::ValueTypeBuilder; use super::misc::ValueTypeBuilder;
use elements; use elements;
/// Global builder
pub struct GlobalBuilder<F=Identity> { pub struct GlobalBuilder<F=Identity> {
callback: F, callback: F,
value_type: elements::ValueType, value_type: elements::ValueType,
@ -10,12 +11,14 @@ pub struct GlobalBuilder<F=Identity> {
} }
impl GlobalBuilder { impl GlobalBuilder {
/// New global builder
pub fn new() -> Self { pub fn new() -> Self {
GlobalBuilder::with_callback(Identity) GlobalBuilder::with_callback(Identity)
} }
} }
impl<F> GlobalBuilder<F> { impl<F> GlobalBuilder<F> {
/// New global builder with callback (in chained context)
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
GlobalBuilder { GlobalBuilder {
callback: callback, callback: callback,
@ -25,31 +28,36 @@ impl<F> GlobalBuilder<F> {
} }
} }
/// Set/override resulting global type
pub fn with_type(mut self, value_type: elements::ValueType) -> Self { pub fn with_type(mut self, value_type: elements::ValueType) -> Self {
self.value_type = value_type; self.value_type = value_type;
self self
} }
/// Set mutabilty to true
pub fn mutable(mut self) -> Self { pub fn mutable(mut self) -> Self {
self.is_mutable = true; self.is_mutable = true;
self self
} }
/// Set initialization expression opcode for this global (`end` opcode will be added automatically)
pub fn init_expr(mut self, opcode: elements::Opcode) -> Self { pub fn init_expr(mut self, opcode: elements::Opcode) -> Self {
self.init_expr = elements::InitExpr::new(vec![opcode, elements::Opcode::End]); self.init_expr = elements::InitExpr::new(vec![opcode, elements::Opcode::End]);
self self
} }
/// Start value type builder
pub fn value_type(self) -> ValueTypeBuilder<Self> { pub fn value_type(self) -> ValueTypeBuilder<Self> {
ValueTypeBuilder::with_callback(self) ValueTypeBuilder::with_callback(self)
} }
} }
impl<F> GlobalBuilder<F> where F: Invoke<elements::GlobalEntry> { impl<F> GlobalBuilder<F> where F: Invoke<elements::GlobalEntry> {
/// Finalize current builder spawning resulting struct
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke( self.callback.invoke(
elements::GlobalEntry::new( elements::GlobalEntry::new(
elements::GlobalType::new(self.value_type, self.is_mutable), elements::GlobalType::new(self.value_type, self.is_mutable),
self.init_expr, self.init_expr,
) )
) )

View File

@ -1,6 +1,7 @@
use super::invoke::{Invoke, Identity}; use super::invoke::{Invoke, Identity};
use elements; use elements;
/// Import builder
pub struct ImportBuilder<F=Identity> { pub struct ImportBuilder<F=Identity> {
callback: F, callback: F,
module: String, module: String,
@ -9,13 +10,14 @@ pub struct ImportBuilder<F=Identity> {
} }
impl ImportBuilder { impl ImportBuilder {
/// New import builder
pub fn new() -> Self { pub fn new() -> Self {
ImportBuilder::with_callback(Identity) ImportBuilder::with_callback(Identity)
} }
} }
impl<F> ImportBuilder<F> { impl<F> ImportBuilder<F> {
/// New import builder with callback (in chained context)
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
ImportBuilder { ImportBuilder {
callback: callback, callback: callback,
@ -25,31 +27,37 @@ impl<F> ImportBuilder<F> {
} }
} }
/// Set/override module name
pub fn module(mut self, name: &str) -> Self { pub fn module(mut self, name: &str) -> Self {
self.module = name.to_owned(); self.module = name.to_owned();
self self
} }
/// Set/override field name
pub fn field(mut self, name: &str) -> Self { pub fn field(mut self, name: &str) -> Self {
self.field = name.to_owned(); self.field = name.to_owned();
self self
} }
/// Set/override both module name and field name
pub fn path(self, module: &str, field: &str) -> Self { pub fn path(self, module: &str, field: &str) -> Self {
self.module(module).field(field) self.module(module).field(field)
} }
/// Set/override external mapping for this import
pub fn with_external(mut self, external: elements::External) -> Self { pub fn with_external(mut self, external: elements::External) -> Self {
self.binding = external; self.binding = external;
self self
} }
/// Start new external mapping builder
pub fn external(self) -> ImportExternalBuilder<Self> { pub fn external(self) -> ImportExternalBuilder<Self> {
ImportExternalBuilder::with_callback(self) ImportExternalBuilder::with_callback(self)
} }
} }
impl<F> ImportBuilder<F> where F: Invoke<elements::ImportEntry> { impl<F> ImportBuilder<F> where F: Invoke<elements::ImportEntry> {
/// Finalize current builder spawning the resulting struct
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke(elements::ImportEntry::new(self.module, self.field, self.binding)) self.callback.invoke(elements::ImportEntry::new(self.module, self.field, self.binding))
} }
@ -62,12 +70,14 @@ impl<F> Invoke<elements::External> for ImportBuilder<F> {
} }
} }
/// Import to external mapping builder
pub struct ImportExternalBuilder<F=Identity> { pub struct ImportExternalBuilder<F=Identity> {
callback: F, callback: F,
binding: elements::External, binding: elements::External,
} }
impl<F> ImportExternalBuilder<F> where F: Invoke<elements::External> { impl<F> ImportExternalBuilder<F> where F: Invoke<elements::External> {
/// New import to external mapping builder with callback (in chained context)
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
ImportExternalBuilder{ ImportExternalBuilder{
callback: callback, callback: callback,
@ -75,21 +85,25 @@ impl<F> ImportExternalBuilder<F> where F: Invoke<elements::External> {
} }
} }
/// Function mapping with type reference
pub fn func(mut self, index: u32) -> F::Result { pub fn func(mut self, index: u32) -> F::Result {
self.binding = elements::External::Function(index); self.binding = elements::External::Function(index);
self.callback.invoke(self.binding) self.callback.invoke(self.binding)
} }
/// Memory mapping with specified limits
pub fn memory(mut self, min: u32, max: Option<u32>) -> F::Result { pub fn memory(mut self, min: u32, max: Option<u32>) -> F::Result {
self.binding = elements::External::Memory(elements::MemoryType::new(min, max)); self.binding = elements::External::Memory(elements::MemoryType::new(min, max));
self.callback.invoke(self.binding) self.callback.invoke(self.binding)
} }
/// Table mapping with specified limits
pub fn table(mut self, min: u32, max: Option<u32>) -> F::Result { pub fn table(mut self, min: u32, max: Option<u32>) -> F::Result {
self.binding = elements::External::Table(elements::TableType::new(min, max)); self.binding = elements::External::Table(elements::TableType::new(min, max));
self.callback.invoke(self.binding) self.callback.invoke(self.binding)
} }
/// Global mapping with speciifed type and mutability
pub fn global(mut self, value_type: elements::ValueType, is_mut: bool) -> F::Result { pub fn global(mut self, value_type: elements::ValueType, is_mut: bool) -> F::Result {
self.binding = elements::External::Global(elements::GlobalType::new(value_type, is_mut)); self.binding = elements::External::Global(elements::GlobalType::new(value_type, is_mut));
self.callback.invoke(self.binding) self.callback.invoke(self.binding)

View File

@ -1,11 +1,13 @@
//! invoke helper //! invoke helper
/// Helper trait to allow chaining
pub trait Invoke<A> { pub trait Invoke<A> {
type Result; type Result;
fn invoke(self, arg: A) -> Self::Result; fn invoke(self, arg: A) -> Self::Result;
} }
/// Identity chain element
pub struct Identity; pub struct Identity;
impl<A> Invoke<A> for Identity { impl<A> Invoke<A> for Identity {

View File

@ -1,31 +1,41 @@
use elements; use elements;
use super::invoke::{Invoke, Identity}; use super::invoke::{Invoke, Identity};
/// Memory definition struct
#[derive(Debug)] #[derive(Debug)]
pub struct MemoryDefinition { pub struct MemoryDefinition {
/// Minimum memory size
pub min: u32, pub min: u32,
/// Maximum memory size
pub max: Option<u32>, pub max: Option<u32>,
/// Memory data segments (static regions)
pub data: Vec<MemoryDataDefinition>, pub data: Vec<MemoryDataDefinition>,
} }
/// Memory static region entry definition
#[derive(Debug)] #[derive(Debug)]
pub struct MemoryDataDefinition { pub struct MemoryDataDefinition {
/// Segment initialization expression for offset
pub offset: elements::InitExpr, pub offset: elements::InitExpr,
/// Raw bytes of static region
pub values: Vec<u8>, pub values: Vec<u8>,
} }
/// Memory and static regions builder
pub struct MemoryBuilder<F=Identity> { pub struct MemoryBuilder<F=Identity> {
callback: F, callback: F,
memory: MemoryDefinition, memory: MemoryDefinition,
} }
impl MemoryBuilder { impl MemoryBuilder {
/// New memory builder
pub fn new() -> Self { pub fn new() -> Self {
MemoryBuilder::with_callback(Identity) MemoryBuilder::with_callback(Identity)
} }
} }
impl<F> MemoryBuilder<F> where F: Invoke<MemoryDefinition> { impl<F> MemoryBuilder<F> where F: Invoke<MemoryDefinition> {
/// New memory builder with callback (in chained context)
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
MemoryBuilder { MemoryBuilder {
callback: callback, callback: callback,
@ -33,16 +43,19 @@ impl<F> MemoryBuilder<F> where F: Invoke<MemoryDefinition> {
} }
} }
/// Set/override minimum size
pub fn with_min(mut self, min: u32) -> Self { pub fn with_min(mut self, min: u32) -> Self {
self.memory.min = min; self.memory.min = min;
self self
} }
/// Set/override maximum size
pub fn with_max(mut self, max: Option<u32>) -> Self { pub fn with_max(mut self, max: Option<u32>) -> Self {
self.memory.max = max; self.memory.max = max;
self self
} }
/// Push new static region with initialized offset expression and raw bytes
pub fn with_data(mut self, index: u32, values: Vec<u8>) -> Self { pub fn with_data(mut self, index: u32, values: Vec<u8>) -> Self {
self.memory.data.push(MemoryDataDefinition { self.memory.data.push(MemoryDataDefinition {
offset: elements::InitExpr::new(vec![ offset: elements::InitExpr::new(vec![
@ -54,6 +67,7 @@ impl<F> MemoryBuilder<F> where F: Invoke<MemoryDefinition> {
self self
} }
/// Finalize current builder, spawning resulting struct
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke(self.memory) self.callback.invoke(self.memory)
} }

View File

@ -11,8 +11,15 @@ mod export;
mod global; mod global;
mod data; mod data;
pub use self::code::{
signatures, signature, function, SignatureBuilder, SignaturesBuilder,
FunctionBuilder, TypeRefBuilder, FuncBodyBuilder, FunctionDefinition,
};
pub use self::data::DataSegmentBuilder;
pub use self::export::{export, ExportBuilder, ExportInternalBuilder};
pub use self::global::{global, GlobalBuilder};
pub use self::import::{import, ImportBuilder};
pub use self::invoke::Identity;
pub use self::memory::MemoryBuilder;
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::table::{TableBuilder, TableDefinition, TableEntryDefinition};
pub use self::import::import;
pub use self::export::export;
pub use self::global::global;

View File

@ -1,31 +1,41 @@
use elements; use elements;
use super::invoke::{Invoke, Identity}; use super::invoke::{Invoke, Identity};
/// Table definition
#[derive(Debug)] #[derive(Debug)]
pub struct TableDefinition { pub struct TableDefinition {
/// Minimum length
pub min: u32, pub min: u32,
/// Maximum length, if any
pub max: Option<u32>, pub max: Option<u32>,
/// Element segments, if any
pub elements: Vec<TableEntryDefinition>, pub elements: Vec<TableEntryDefinition>,
} }
/// Table elements entry definition
#[derive(Debug)] #[derive(Debug)]
pub struct TableEntryDefinition { pub struct TableEntryDefinition {
/// Offset initialization expression
pub offset: elements::InitExpr, pub offset: elements::InitExpr,
/// Values of initialization
pub values: Vec<u32>, pub values: Vec<u32>,
} }
/// Table builder
pub struct TableBuilder<F=Identity> { pub struct TableBuilder<F=Identity> {
callback: F, callback: F,
table: TableDefinition, table: TableDefinition,
} }
impl TableBuilder { impl TableBuilder {
/// New table builder
pub fn new() -> Self { pub fn new() -> Self {
TableBuilder::with_callback(Identity) TableBuilder::with_callback(Identity)
} }
} }
impl<F> TableBuilder<F> where F: Invoke<TableDefinition> { impl<F> TableBuilder<F> where F: Invoke<TableDefinition> {
/// New table builder with callback in chained context
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
TableBuilder { TableBuilder {
callback: callback, callback: callback,
@ -33,16 +43,19 @@ impl<F> TableBuilder<F> where F: Invoke<TableDefinition> {
} }
} }
/// Set/override minimum length
pub fn with_min(mut self, min: u32) -> Self { pub fn with_min(mut self, min: u32) -> Self {
self.table.min = min; self.table.min = min;
self self
} }
/// Set/override maximum length
pub fn with_max(mut self, max: Option<u32>) -> Self { pub fn with_max(mut self, max: Option<u32>) -> Self {
self.table.max = max; self.table.max = max;
self self
} }
/// Generate initialization expression and element values on specified index
pub fn with_element(mut self, index: u32, values: Vec<u32>) -> Self { pub fn with_element(mut self, index: u32, values: Vec<u32>) -> Self {
self.table.elements.push(TableEntryDefinition { self.table.elements.push(TableEntryDefinition {
offset: elements::InitExpr::new(vec![ offset: elements::InitExpr::new(vec![
@ -54,6 +67,7 @@ impl<F> TableBuilder<F> where F: Invoke<TableDefinition> {
self self
} }
/// Finalize current builder spawning resulting struct
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke(self.table) self.callback.invoke(self.table)
} }

View File

@ -5,7 +5,7 @@ use super::{
}; };
/// Function signature (type reference) /// Function signature (type reference)
#[derive(Clone)] #[derive(Debug, Copy, Clone)]
pub struct Func(u32); pub struct Func(u32);
impl Func { impl Func {
@ -24,7 +24,7 @@ impl Func {
} }
/// Local definition inside the function body. /// Local definition inside the function body.
#[derive(Debug, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Local { pub struct Local {
count: u32, count: u32,
value_type: ValueType, value_type: ValueType,

View File

@ -5,7 +5,7 @@ use super::{
}; };
/// Global definition struct /// Global definition struct
#[derive(Debug, Clone)] #[derive(Debug, Copy, Clone)]
pub struct GlobalType { pub struct GlobalType {
content_type: ValueType, content_type: ValueType,
is_mutable: bool, is_mutable: bool,
@ -51,7 +51,7 @@ impl Serialize for GlobalType {
} }
/// Table entry /// Table entry
#[derive(Debug, Clone)] #[derive(Debug, Copy, Clone)]
pub struct TableType { pub struct TableType {
elem_type: TableElementType, elem_type: TableElementType,
limits: ResizableLimits, limits: ResizableLimits,
@ -96,7 +96,7 @@ impl Serialize for TableType {
} }
/// Memory limits /// Memory limits
#[derive(Debug, Clone)] #[derive(Debug, Copy, Clone)]
pub struct ResizableLimits { pub struct ResizableLimits {
initial: u32, initial: u32,
maximum: Option<u32>, maximum: Option<u32>,
@ -150,7 +150,7 @@ impl Serialize for ResizableLimits {
} }
/// Memory entry. /// Memory entry.
#[derive(Debug, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MemoryType(ResizableLimits); pub struct MemoryType(ResizableLimits);
impl MemoryType { impl MemoryType {
@ -181,7 +181,7 @@ impl Serialize for MemoryType {
} }
/// External to local binding. /// External to local binding.
#[derive(Debug, Clone)] #[derive(Debug, Copy, Clone)]
pub enum External { pub enum External {
/// Binds to function with index. /// Binds to function with index.
Function(u32), Function(u32),

View File

@ -50,7 +50,7 @@ pub trait Serialize {
} }
/// Deserialization/serialization error /// Deserialization/serialization error
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum Error { pub enum Error {
/// Unexpected end of input /// Unexpected end of input
UnexpectedEof, UnexpectedEof,

View File

@ -10,7 +10,7 @@ use super::section::{
const WASM_MAGIC_NUMBER: [u8; 4] = [0x00, 0x61, 0x73, 0x6d]; const WASM_MAGIC_NUMBER: [u8; 4] = [0x00, 0x61, 0x73, 0x6d];
/// WebAssembly module /// WebAssembly module
#[derive(Clone)] #[derive(Debug, Clone)]
pub struct Module { pub struct Module {
magic: u32, magic: u32,
version: u32, version: u32,
@ -20,7 +20,7 @@ pub struct Module {
impl Default for Module { impl Default for Module {
fn default() -> Self { fn default() -> Self {
Module { Module {
magic: 0x6d736100, magic: LittleEndian::read_u32(&WASM_MAGIC_NUMBER),
version: 1, version: 1,
sections: Vec::with_capacity(16), sections: Vec::with_capacity(16),
} }
@ -191,6 +191,7 @@ impl Serialize for Module {
} }
} }
#[derive(Debug, Copy, Clone)]
struct PeekSection<'a> { struct PeekSection<'a> {
cursor: usize, cursor: usize,
region: &'a [u8], region: &'a [u8],
@ -389,4 +390,13 @@ mod integration_tests {
assert_eq!(peek_size(&buf), buf.len() - 9); assert_eq!(peek_size(&buf), buf.len() - 9);
} }
#[test]
fn module_default_round_trip() {
let module1 = Module::default();
let buf = serialize(module1).expect("Serialization should succeed");
let module2: Module = deserialize_buffer(&buf).expect("Deserialization should succeed");
assert_eq!(Module::default().magic, module2.magic);
}
} }

View File

@ -266,7 +266,7 @@ pub enum Opcode {
F64Max, F64Max,
F64Copysign, F64Copysign,
I32WarpI64, I32WrapI64,
I32TruncSF32, I32TruncSF32,
I32TruncUF32, I32TruncUF32,
I32TruncSF64, I32TruncSF64,
@ -560,7 +560,7 @@ impl Deserialize for Opcode {
0xa5 => F64Max, 0xa5 => F64Max,
0xa6 => F64Copysign, 0xa6 => F64Copysign,
0xa7 => I32WarpI64, 0xa7 => I32WrapI64,
0xa8 => I32TruncSF32, 0xa8 => I32TruncSF32,
0xa9 => I32TruncUF32, 0xa9 => I32TruncUF32,
0xaa => I32TruncSF64, 0xaa => I32TruncSF64,
@ -877,7 +877,7 @@ impl Serialize for Opcode {
F64Max => op!(writer, 0xa5), F64Max => op!(writer, 0xa5),
F64Copysign => op!(writer, 0xa6), F64Copysign => op!(writer, 0xa6),
I32WarpI64 => op!(writer, 0xa7), I32WrapI64 => op!(writer, 0xa7),
I32TruncSF32 => op!(writer, 0xa8), I32TruncSF32 => op!(writer, 0xa8),
I32TruncUF32 => op!(writer, 0xa9), I32TruncUF32 => op!(writer, 0xa9),
I32TruncSF64 => op!(writer, 0xaa), I32TruncSF64 => op!(writer, 0xaa),
@ -1134,7 +1134,7 @@ impl fmt::Display for Opcode {
F64Max => write!(f, "f64.max"), F64Max => write!(f, "f64.max"),
F64Copysign => write!(f, "f64.copysign"), F64Copysign => write!(f, "f64.copysign"),
I32WarpI64 => write!(f, "i32.wrap/i64"), I32WrapI64 => write!(f, "i32.wrap/i64"),
I32TruncSF32 => write!(f, "i32.trunc_s/f32"), I32TruncSF32 => write!(f, "i32.trunc_s/f32"),
I32TruncUF32 => write!(f, "i32.trunc_u/f32"), I32TruncUF32 => write!(f, "i32.trunc_u/f32"),
I32TruncSF64 => write!(f, "i32.trunc_s/f64"), I32TruncSF64 => write!(f, "i32.trunc_s/f64"),

View File

@ -4,7 +4,7 @@ use super::{Error, Deserialize, Serialize};
/// Unsigned variable-length integer, limited to 32 bits, /// Unsigned variable-length integer, limited to 32 bits,
/// represented by at most 5 bytes that may contain padding 0x80 bytes. /// represented by at most 5 bytes that may contain padding 0x80 bytes.
#[derive(Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct VarUint32(u32); pub struct VarUint32(u32);
impl From<VarUint32> for usize { impl From<VarUint32> for usize {
@ -74,7 +74,7 @@ impl Serialize for VarUint32 {
/// Unsigned variable-length integer, limited to 64 bits, /// Unsigned variable-length integer, limited to 64 bits,
/// represented by at most 9 bytes that may contain padding 0x80 bytes. /// represented by at most 9 bytes that may contain padding 0x80 bytes.
#[derive(Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct VarUint64(u64); pub struct VarUint64(u64);
impl From<VarUint64> for u64 { impl From<VarUint64> for u64 {
@ -130,7 +130,7 @@ impl From<u64> for VarUint64 {
} }
/// 7-bit unsigned integer, encoded in LEB128 (always 1 byte length) /// 7-bit unsigned integer, encoded in LEB128 (always 1 byte length)
#[derive(Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct VarUint7(u8); pub struct VarUint7(u8);
impl From<VarUint7> for u8 { impl From<VarUint7> for u8 {
@ -166,7 +166,7 @@ impl Serialize for VarUint7 {
} }
/// 7-bit signed integer, encoded in LEB128 (always 1 byte length) /// 7-bit signed integer, encoded in LEB128 (always 1 byte length)
#[derive(Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct VarInt7(i8); pub struct VarInt7(i8);
impl From<VarInt7> for i8 { impl From<VarInt7> for i8 {
@ -207,7 +207,7 @@ impl Serialize for VarInt7 {
} }
/// 32-bit signed integer, encoded in LEB128 (can be 1-5 bytes length) /// 32-bit signed integer, encoded in LEB128 (can be 1-5 bytes length)
#[derive(Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct VarInt32(i32); pub struct VarInt32(i32);
impl From<VarInt32> for i32 { impl From<VarInt32> for i32 {
@ -271,7 +271,7 @@ impl Serialize for VarInt32 {
} }
/// 64-bit signed integer, encoded in LEB128 (can be 1-9 bytes length) /// 64-bit signed integer, encoded in LEB128 (can be 1-9 bytes length)
#[derive(Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct VarInt64(i64); pub struct VarInt64(i64);
impl From<VarInt64> for i64 { impl From<VarInt64> for i64 {
@ -335,7 +335,7 @@ impl Serialize for VarInt64 {
} }
/// 32-bit unsigned integer, encoded in little endian /// 32-bit unsigned integer, encoded in little endian
#[derive(Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Uint32(u32); pub struct Uint32(u32);
impl Deserialize for Uint32 { impl Deserialize for Uint32 {
@ -371,7 +371,7 @@ impl From<u32> for Uint32 {
} }
/// 64-bit unsigned integer, encoded in little endian /// 64-bit unsigned integer, encoded in little endian
#[derive(Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Uint64(u64); pub struct Uint64(u64);
impl Deserialize for Uint64 { impl Deserialize for Uint64 {
@ -408,7 +408,7 @@ impl From<Uint64> for u64 {
/// VarUint1, 1-bit value (0/1) /// VarUint1, 1-bit value (0/1)
#[derive(Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct VarUint1(bool); pub struct VarUint1(bool);
impl From<VarUint1> for bool { impl From<VarUint1> for bool {
@ -476,6 +476,7 @@ impl Serialize for String {
/// List for reading sequence of elements typed `T`, given /// List for reading sequence of elements typed `T`, given
/// they are preceded by length (serialized as VarUint32) /// they are preceded by length (serialized as VarUint32)
#[derive(Debug, Clone)]
pub struct CountedList<T: Deserialize>(Vec<T>); pub struct CountedList<T: Deserialize>(Vec<T>);
impl<T: Deserialize> CountedList<T> { impl<T: Deserialize> CountedList<T> {
@ -496,6 +497,7 @@ impl<T: Deserialize> Deserialize for CountedList<T> where T::Error: From<Error>
/// Helper struct to write payload which is preceded by /// Helper struct to write payload which is preceded by
/// it's own length in bytes. /// it's own length in bytes.
#[derive(Debug)]
pub struct CountedWriter<'a, W: 'a + io::Write> { pub struct CountedWriter<'a, W: 'a + io::Write> {
writer: &'a mut W, writer: &'a mut W,
data: Vec<u8>, data: Vec<u8>,
@ -541,6 +543,7 @@ impl<'a, W: 'a + io::Write> io::Write for CountedWriter<'a, W> {
/// Helper struct to write series of `T` preceded by the length of the sequence /// Helper struct to write series of `T` preceded by the length of the sequence
/// serialized as VarUint32 /// serialized as VarUint32
#[derive(Debug, Clone)]
pub struct CountedListWriter<I: Serialize<Error=::elements::Error>, T: IntoIterator<Item=I>>(pub usize, pub T); pub struct CountedListWriter<I: Serialize<Error=::elements::Error>, T: IntoIterator<Item=I>>(pub usize, pub T);
impl<I: Serialize<Error=::elements::Error>, T: IntoIterator<Item=I>> Serialize for CountedListWriter<I, T> { impl<I: Serialize<Error=::elements::Error>, T: IntoIterator<Item=I>> Serialize for CountedListWriter<I, T> {

View File

@ -24,7 +24,7 @@ use super::{
use super::types::Type; use super::types::Type;
/// Section in the WebAssembly module. /// Section in the WebAssembly module.
#[derive(Clone)] #[derive(Debug, Clone)]
pub enum Section { pub enum Section {
/// Section is unparsed. /// Section is unparsed.
Unparsed { Unparsed {
@ -181,7 +181,7 @@ impl Serialize for Section {
} }
/// Custom section /// Custom section
#[derive(Clone)] #[derive(Debug, Clone)]
pub struct CustomSection { pub struct CustomSection {
name: String, name: String,
payload: Vec<u8>, payload: Vec<u8>,
@ -241,7 +241,7 @@ impl Serialize for CustomSection {
} }
/// Section with type declarations /// Section with type declarations
#[derive(Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct TypeSection(Vec<Type>); pub struct TypeSection(Vec<Type>);
impl TypeSection { impl TypeSection {
@ -351,7 +351,7 @@ impl Serialize for ImportSection {
} }
/// Section with function signatures definition. /// Section with function signatures definition.
#[derive(Default, Clone)] #[derive(Default, Debug, Clone)]
pub struct FunctionSection(Vec<Func>); pub struct FunctionSection(Vec<Func>);
impl FunctionSection { impl FunctionSection {
@ -403,7 +403,7 @@ impl Serialize for FunctionSection {
} }
/// Section with table definition (currently only one is allowed). /// Section with table definition (currently only one is allowed).
#[derive(Default, Clone)] #[derive(Default, Debug, Clone)]
pub struct TableSection(Vec<TableType>); pub struct TableSection(Vec<TableType>);
impl TableSection { impl TableSection {
@ -451,7 +451,7 @@ impl Serialize for TableSection {
} }
/// Section with table definition (currently only one entry is allowed). /// Section with table definition (currently only one entry is allowed).
#[derive(Default, Clone)] #[derive(Default, Debug, Clone)]
pub struct MemorySection(Vec<MemoryType>); pub struct MemorySection(Vec<MemoryType>);
impl MemorySection { impl MemorySection {
@ -499,7 +499,7 @@ impl Serialize for MemorySection {
} }
/// Globals definition section. /// Globals definition section.
#[derive(Default, Clone)] #[derive(Default, Debug, Clone)]
pub struct GlobalSection(Vec<GlobalEntry>); pub struct GlobalSection(Vec<GlobalEntry>);
impl GlobalSection { impl GlobalSection {
@ -595,7 +595,7 @@ impl Serialize for ExportSection {
} }
/// Section with function bodies of the module. /// Section with function bodies of the module.
#[derive(Default, Clone)] #[derive(Default, Debug, Clone)]
pub struct CodeSection(Vec<FuncBody>); pub struct CodeSection(Vec<FuncBody>);
impl CodeSection { impl CodeSection {
@ -643,7 +643,7 @@ impl Serialize for CodeSection {
} }
/// Element entries section. /// Element entries section.
#[derive(Default, Clone)] #[derive(Default, Debug, Clone)]
pub struct ElementSection(Vec<ElementSegment>); pub struct ElementSection(Vec<ElementSegment>);
impl ElementSection { impl ElementSection {
@ -691,7 +691,7 @@ impl Serialize for ElementSection {
} }
/// Data entries definitions. /// Data entries definitions.
#[derive(Default, Clone)] #[derive(Default, Debug, Clone)]
pub struct DataSection(Vec<DataSegment>); pub struct DataSection(Vec<DataSegment>);
impl DataSection { impl DataSection {

View File

@ -68,7 +68,7 @@ impl Serialize for ElementSegment {
} }
/// Data segment definition. /// Data segment definition.
#[derive(Clone)] #[derive(Clone, Debug)]
pub struct DataSegment { pub struct DataSegment {
index: u32, index: u32,
offset: InitExpr, offset: InitExpr,

View File

@ -319,7 +319,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
&Opcode::F64Max => self.run_max::<f64>(context), &Opcode::F64Max => self.run_max::<f64>(context),
&Opcode::F64Copysign => self.run_copysign::<f64>(context), &Opcode::F64Copysign => self.run_copysign::<f64>(context),
&Opcode::I32WarpI64 => self.run_wrap::<i64, i32>(context), &Opcode::I32WrapI64 => self.run_wrap::<i64, i32>(context),
&Opcode::I32TruncSF32 => self.run_trunc_to_int::<f32, i32, i32>(context), &Opcode::I32TruncSF32 => self.run_trunc_to_int::<f32, i32, i32>(context),
&Opcode::I32TruncUF32 => self.run_trunc_to_int::<f32, u32, i32>(context), &Opcode::I32TruncUF32 => self.run_trunc_to_int::<f32, u32, i32>(context),
&Opcode::I32TruncSF64 => self.run_trunc_to_int::<f64, i32, i32>(context), &Opcode::I32TruncSF64 => self.run_trunc_to_int::<f64, i32, i32>(context),

View File

@ -281,7 +281,7 @@ impl Validator {
F64Max => Validator::validate_binop(context, ValueType::F64), F64Max => Validator::validate_binop(context, ValueType::F64),
F64Copysign => Validator::validate_binop(context, ValueType::F64), F64Copysign => Validator::validate_binop(context, ValueType::F64),
I32WarpI64 => Validator::validate_cvtop(context, ValueType::I64, ValueType::I32), I32WrapI64 => Validator::validate_cvtop(context, ValueType::I64, ValueType::I32),
I32TruncSF32 => Validator::validate_cvtop(context, ValueType::F32, ValueType::I32), I32TruncSF32 => Validator::validate_cvtop(context, ValueType::F32, ValueType::I32),
I32TruncUF32 => Validator::validate_cvtop(context, ValueType::F32, ValueType::I32), I32TruncUF32 => Validator::validate_cvtop(context, ValueType::F32, ValueType::I32),
I32TruncSF64 => Validator::validate_cvtop(context, ValueType::F64, ValueType::I32), I32TruncSF64 => Validator::validate_cvtop(context, ValueType::F64, ValueType::I32),