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]
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>"]
license = "MIT/Apache-2.0"
readme = "README.md"

View File

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

View File

@ -2,23 +2,27 @@ use elements;
use super::invoke::{Invoke, Identity};
use super::misc::{ValueTypeBuilder, ValueTypesBuilder, OptionalValueTypeBuilder};
/// Signature template description
pub enum Signature {
TypeReference(u32),
Inline(elements::FunctionType),
}
/// Signature builder
pub struct SignatureBuilder<F=Identity> {
callback: F,
signature: elements::FunctionType,
}
impl SignatureBuilder {
/// New signature builder
pub fn new() -> Self {
SignatureBuilder::with_callback(Identity)
}
}
impl<F> SignatureBuilder<F> where F: Invoke<elements::FunctionType> {
/// New builder with callback function specified
pub fn with_callback(callback: F) -> Self {
SignatureBuilder {
callback: callback,
@ -26,37 +30,45 @@ impl<F> SignatureBuilder<F> where F: Invoke<elements::FunctionType> {
}
}
/// Add argument to signature builder
pub fn with_param(mut self, value_type: elements::ValueType) -> Self {
self.signature.params_mut().push(value_type);
self
}
/// Add multiple arguments to signature builder
pub fn with_params(mut self, value_types: Vec<elements::ValueType>) -> Self {
self.signature.params_mut().extend(value_types);
self
}
/// Override signature return type
pub fn with_return_type(mut self, return_type: Option<elements::ValueType>) -> Self {
*self.signature.return_type_mut() = return_type;
self
}
/// Start build new argument
pub fn param(self) -> ValueTypeBuilder<Self> {
ValueTypeBuilder::with_callback(self)
}
/// Start build multiple arguments
pub fn params(self) -> ValueTypesBuilder<Self> {
ValueTypesBuilder::with_callback(self)
}
/// Start building return type
pub fn return_type(self) -> OptionalValueTypeBuilder<Self> {
OptionalValueTypeBuilder::with_callback(self)
}
/// Finish current builder
pub fn build(self) -> F::Result {
self.callback.invoke(self.signature)
}
/// Finish current builder returning intermediate `Signature` struct
pub fn build_sig(self) -> Signature {
Signature::Inline(self.signature)
}
@ -92,12 +104,14 @@ impl<F> Invoke<elements::ValueType> for SignatureBuilder<F>
}
}
/// Type (signature) reference builder (for function/import/indirect call)
pub struct TypeRefBuilder<F=Identity> {
callback: F,
type_ref: u32,
}
impl<F> TypeRefBuilder<F> where F: Invoke<u32> {
/// New builder chained with specified callback
pub fn with_callback(callback: F) -> Self {
TypeRefBuilder {
callback: callback,
@ -105,14 +119,17 @@ impl<F> TypeRefBuilder<F> where F: Invoke<u32> {
}
}
/// Set/override of type reference
pub fn val(mut self, val: u32) -> Self {
self.type_ref = val;
self
}
/// Finish current builder
pub fn build(self) -> F::Result { self.callback.invoke(self.type_ref) }
}
/// Multiple signatures builder
pub struct SignaturesBuilder<F=Identity> {
callback: F,
section: Vec<Signature>,
@ -126,6 +143,7 @@ impl SignaturesBuilder {
}
impl<F> SignaturesBuilder<F> {
/// New builder chained with specified callback
pub fn with_callback(callback: F) -> Self {
SignaturesBuilder {
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 {
self.section.push(signature);
self
}
/// Start building new signature with `TypeRefBuilder`
pub fn type_ref(self) -> TypeRefBuilder<Self> {
TypeRefBuilder::with_callback(self)
}
}
impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> {
/// Start building new signature with dedicated builder
pub fn signature(self) -> SignatureBuilder<Self> {
SignatureBuilder::with_callback(self)
}
@ -166,6 +187,8 @@ impl<F> Invoke<u32> for SignaturesBuilder<F> {
}
impl<F> SignaturesBuilder<F> where F: Invoke<elements::FunctionSection> {
/// Finalize builder spawning element
pub fn build(self) -> F::Result {
let mut result = elements::FunctionSection::default();
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>;
impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> {
/// Bind signature list
pub fn bind(self) -> F::Result {
self.callback.invoke(self.section)
}
}
/// Function body (code) builder
pub struct FuncBodyBuilder<F=Identity> {
callback: F,
body: elements::FuncBody,
}
impl<F> FuncBodyBuilder<F> {
/// New body (code) builder given the chain callback
pub fn with_callback(callback: F) -> Self {
FuncBodyBuilder {
callback: callback,
@ -202,29 +229,37 @@ impl<F> FuncBodyBuilder<F> {
}
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 {
self.body = func;
self
}
/// Extend function local list with new entries
pub fn with_locals(mut self, locals: Vec<elements::Local>) -> Self {
self.body.locals_mut().extend(locals);
self
}
/// Set code of the function
pub fn with_opcodes(mut self, opcodes: elements::Opcodes) -> Self {
*self.body.code_mut() = opcodes;
self
}
/// Finish current builder spawning resulting struct
pub fn build(self) -> F::Result {
self.callback.invoke(self.body)
}
}
/// Function definition (extended structure to specify function entirely, incl. signature, mainness and code)
pub struct FunctionDefinition {
/// Is this function is start function
pub is_main: bool,
/// Signature description
pub signature: Signature,
/// Body (code) of the function
pub code: elements::FuncBody,
}
@ -238,18 +273,21 @@ impl Default for FunctionDefinition {
}
}
/// Function definition builder
pub struct FunctionBuilder<F=Identity> {
callback: F,
func: FunctionDefinition,
}
impl FunctionBuilder {
/// New function builder
pub fn new() -> Self {
FunctionBuilder::with_callback(Identity)
}
}
impl<F> FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
/// New function builder with chained callback
pub fn with_callback(callback: F) -> Self {
FunctionBuilder {
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 {
self.func.is_main = true;
self
}
/// Start signature builder of the function
pub fn signature(self) -> SignatureBuilder<Self> {
SignatureBuilder::with_callback(self)
}
/// Override current signature entirely with new one from known struct
pub fn with_signature(mut self, signature: Signature) -> Self {
self.func.signature = signature;
self
}
/// Start code (body) builder
pub fn body(self) -> FuncBodyBuilder<Self> {
FuncBodyBuilder::with_callback(self)
}
/// Set body (code) for this function
pub fn with_body(mut self, body: elements::FuncBody) -> Self {
self.func.code = body;
self
}
/// Finalize current builder spawning resulting struct in the callback
pub fn build(self) -> F::Result {
self.callback.invoke(self.func)
}

View File

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

View File

@ -1,6 +1,7 @@
use super::invoke::{Invoke, Identity};
use elements;
/// Export entry builder
pub struct ExportBuilder<F=Identity> {
callback: F,
field: String,
@ -8,6 +9,7 @@ pub struct ExportBuilder<F=Identity> {
}
impl ExportBuilder {
/// New export builder
pub fn new() -> Self {
ExportBuilder::with_callback(Identity)
}
@ -15,6 +17,7 @@ impl ExportBuilder {
impl<F> ExportBuilder<F> {
/// New export entry builder in the specified chained context
pub fn with_callback(callback: F) -> Self {
ExportBuilder {
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 {
self.field = field.to_owned();
self
}
/// Specify the internal module mapping for this entry
pub fn with_internal(mut self, external: elements::Internal) -> Self {
self.binding = external;
self
}
/// Start the internal builder for this export entry
pub fn internal(self) -> ExportInternalBuilder<Self> {
ExportInternalBuilder::with_callback(self)
}
}
impl<F> ExportBuilder<F> where F: Invoke<elements::ExportEntry> {
/// Finalize export entry builder spawning the resulting struct
pub fn build(self) -> F::Result {
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> {
callback: F,
binding: 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 {
ExportInternalBuilder{
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 {
self.binding = elements::Internal::Function(index);
self.callback.invoke(self.binding)
}
/// Map to memory
pub fn memory(mut self, index: u32) -> F::Result {
self.binding = elements::Internal::Memory(index);
self.callback.invoke(self.binding)
}
/// Map to table
pub fn table(mut self, index: u32) -> F::Result {
self.binding = elements::Internal::Table(index);
self.callback.invoke(self.binding)
}
/// Map to global
pub fn global(mut self, index: u32) -> F::Result {
self.binding = elements::Internal::Global(index);
self.callback.invoke(self.binding)

View File

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

View File

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

View File

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

View File

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

View File

@ -11,8 +11,15 @@ mod export;
mod global;
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::code::{signatures, signature, function};
pub use self::import::import;
pub use self::export::export;
pub use self::global::global;
pub use self::table::{TableBuilder, TableDefinition, TableEntryDefinition};

View File

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

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@ use super::section::{
const WASM_MAGIC_NUMBER: [u8; 4] = [0x00, 0x61, 0x73, 0x6d];
/// WebAssembly module
#[derive(Clone)]
#[derive(Debug, Clone)]
pub struct Module {
magic: u32,
version: u32,
@ -20,7 +20,7 @@ pub struct Module {
impl Default for Module {
fn default() -> Self {
Module {
magic: 0x6d736100,
magic: LittleEndian::read_u32(&WASM_MAGIC_NUMBER),
version: 1,
sections: Vec::with_capacity(16),
}
@ -191,6 +191,7 @@ impl Serialize for Module {
}
}
#[derive(Debug, Copy, Clone)]
struct PeekSection<'a> {
cursor: usize,
region: &'a [u8],
@ -389,4 +390,13 @@ mod integration_tests {
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,
F64Copysign,
I32WarpI64,
I32WrapI64,
I32TruncSF32,
I32TruncUF32,
I32TruncSF64,
@ -560,7 +560,7 @@ impl Deserialize for Opcode {
0xa5 => F64Max,
0xa6 => F64Copysign,
0xa7 => I32WarpI64,
0xa7 => I32WrapI64,
0xa8 => I32TruncSF32,
0xa9 => I32TruncUF32,
0xaa => I32TruncSF64,
@ -877,7 +877,7 @@ impl Serialize for Opcode {
F64Max => op!(writer, 0xa5),
F64Copysign => op!(writer, 0xa6),
I32WarpI64 => op!(writer, 0xa7),
I32WrapI64 => op!(writer, 0xa7),
I32TruncSF32 => op!(writer, 0xa8),
I32TruncUF32 => op!(writer, 0xa9),
I32TruncSF64 => op!(writer, 0xaa),
@ -1134,7 +1134,7 @@ impl fmt::Display for Opcode {
F64Max => write!(f, "f64.max"),
F64Copysign => write!(f, "f64.copysign"),
I32WarpI64 => write!(f, "i32.wrap/i64"),
I32WrapI64 => write!(f, "i32.wrap/i64"),
I32TruncSF32 => write!(f, "i32.trunc_s/f32"),
I32TruncUF32 => write!(f, "i32.trunc_u/f32"),
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,
/// represented by at most 5 bytes that may contain padding 0x80 bytes.
#[derive(Copy, Clone)]
#[derive(Debug, Copy, Clone)]
pub struct VarUint32(u32);
impl From<VarUint32> for usize {
@ -74,7 +74,7 @@ impl Serialize for VarUint32 {
/// Unsigned variable-length integer, limited to 64 bits,
/// represented by at most 9 bytes that may contain padding 0x80 bytes.
#[derive(Copy, Clone)]
#[derive(Debug, Copy, Clone)]
pub struct VarUint64(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)
#[derive(Copy, Clone)]
#[derive(Debug, Copy, Clone)]
pub struct VarUint7(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)
#[derive(Copy, Clone)]
#[derive(Debug, Copy, Clone)]
pub struct VarInt7(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)
#[derive(Copy, Clone)]
#[derive(Debug, Copy, Clone)]
pub struct VarInt32(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)
#[derive(Copy, Clone)]
#[derive(Debug, Copy, Clone)]
pub struct VarInt64(i64);
impl From<VarInt64> for i64 {
@ -335,7 +335,7 @@ impl Serialize for VarInt64 {
}
/// 32-bit unsigned integer, encoded in little endian
#[derive(Copy, Clone)]
#[derive(Debug, Copy, Clone)]
pub struct Uint32(u32);
impl Deserialize for Uint32 {
@ -371,7 +371,7 @@ impl From<u32> for Uint32 {
}
/// 64-bit unsigned integer, encoded in little endian
#[derive(Copy, Clone)]
#[derive(Debug, Copy, Clone)]
pub struct Uint64(u64);
impl Deserialize for Uint64 {
@ -408,7 +408,7 @@ impl From<Uint64> for u64 {
/// VarUint1, 1-bit value (0/1)
#[derive(Copy, Clone)]
#[derive(Debug, Copy, Clone)]
pub struct VarUint1(bool);
impl From<VarUint1> for bool {
@ -476,6 +476,7 @@ impl Serialize for String {
/// List for reading sequence of elements typed `T`, given
/// they are preceded by length (serialized as VarUint32)
#[derive(Debug, Clone)]
pub struct CountedList<T: Deserialize>(Vec<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
/// it's own length in bytes.
#[derive(Debug)]
pub struct CountedWriter<'a, W: 'a + io::Write> {
writer: &'a mut W,
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
/// serialized as VarUint32
#[derive(Debug, Clone)]
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> {

View File

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

View File

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

View File

@ -319,7 +319,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
&Opcode::F64Max => self.run_max::<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::I32TruncUF32 => self.run_trunc_to_int::<f32, u32, 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),
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),
I32TruncUF32 => Validator::validate_cvtop(context, ValueType::F32, ValueType::I32),
I32TruncSF64 => Validator::validate_cvtop(context, ValueType::F64, ValueType::I32),