mirror of
https://github.com/fluencelabs/interface-types
synced 2024-12-04 15:20:20 +00:00
Merge #1370
1370: feat(interface-types) Crate reorganization r=Hywan a=Hywan This PR re-organizes the crate: * `interpreter/wasm/values.rs` moves to `values.rs`, * `interpreter/wasm/serde/*` moves to `serde/*`, * `types.rs` is new, and includes `InterfaceType` and `RecordType`, * Update the documentation. Bonus: `InterfaceValue::Record` now takes a `Vec1` rather than a `Vec` to match `InterfaceType::Record`. Co-authored-by: Ivan Enderlin <ivan@mnt.io>
This commit is contained in:
commit
c85541042b
61
src/ast.rs
61
src/ast.rs
@ -1,65 +1,12 @@
|
||||
//! Represents the WIT language as a tree. This is the central
|
||||
//! representation of the language.
|
||||
|
||||
use crate::{interpreter::Instruction, vec1::Vec1};
|
||||
use crate::{
|
||||
interpreter::Instruction,
|
||||
types::{InterfaceType, RecordType},
|
||||
};
|
||||
use std::str;
|
||||
|
||||
/// Represents the types supported by WIT.
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum InterfaceType {
|
||||
/// A 8-bits signed integer.
|
||||
S8,
|
||||
|
||||
/// A 16-bits signed integer.
|
||||
S16,
|
||||
|
||||
/// A 32-bits signed integer.
|
||||
S32,
|
||||
|
||||
/// A 64-bits signed integer.
|
||||
S64,
|
||||
|
||||
/// A 8-bits unsigned integer.
|
||||
U8,
|
||||
|
||||
/// A 16-bits unsigned integer.
|
||||
U16,
|
||||
|
||||
/// A 32-bits unsigned integer.
|
||||
U32,
|
||||
|
||||
/// A 64-bits unsigned integer.
|
||||
U64,
|
||||
|
||||
/// A 32-bits float.
|
||||
F32,
|
||||
|
||||
/// A 64-bits float.
|
||||
F64,
|
||||
|
||||
/// A string.
|
||||
String,
|
||||
|
||||
/// An `any` reference.
|
||||
Anyref,
|
||||
|
||||
/// A 32-bits integer (as defined in WebAssembly core).
|
||||
I32,
|
||||
|
||||
/// A 64-bits integer (as defiend in WebAssembly core).
|
||||
I64,
|
||||
|
||||
/// A record.
|
||||
Record(RecordType),
|
||||
}
|
||||
|
||||
/// Represents a record type.
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct RecordType {
|
||||
/// Types representing the fields.
|
||||
pub fields: Vec1<InterfaceType>,
|
||||
}
|
||||
|
||||
/// Represents the kind of type.
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum TypeKind {
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Parse the WIT binary representation into an [AST](crate::ast).
|
||||
|
||||
use crate::{ast::*, interpreter::Instruction, vec1::Vec1};
|
||||
use crate::{ast::*, interpreter::Instruction, types::*, vec1::Vec1};
|
||||
use nom::{
|
||||
error::{make_error, ErrorKind, ParseError},
|
||||
Err, IResult,
|
||||
@ -445,9 +445,10 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasmer_interface_types::{
|
||||
/// ast::*,
|
||||
/// ast::{Adapter, Export, Implementation, Import, Interfaces, Type},
|
||||
/// decoders::binary::parse,
|
||||
/// interpreter::Instruction,
|
||||
/// types::InterfaceType,
|
||||
/// };
|
||||
///
|
||||
/// let input = &[
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Parse the WIT textual representation into an [AST](crate::ast).
|
||||
|
||||
use crate::{ast::*, interpreter::Instruction, vec1::Vec1};
|
||||
use crate::{ast::*, interpreter::Instruction, types::*, vec1::Vec1};
|
||||
pub use wast::parser::ParseBuffer as Buffer;
|
||||
use wast::parser::{self, Cursor, Parse, Parser, Peek, Result};
|
||||
|
||||
@ -590,9 +590,10 @@ impl<'a> Parse<'a> for Interfaces<'a> {
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasmer_interface_types::{
|
||||
/// ast::*,
|
||||
/// ast::{Adapter, Export, Implementation, Import, Interfaces, Type},
|
||||
/// decoders::wat::{parse, Buffer},
|
||||
/// interpreter::Instruction,
|
||||
/// types::InterfaceType,
|
||||
/// };
|
||||
///
|
||||
/// let input = Buffer::new(
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Writes the AST into bytes representing WIT with its binary format.
|
||||
|
||||
use crate::{ast::*, interpreter::Instruction};
|
||||
use crate::{ast::*, interpreter::Instruction, types::*};
|
||||
use std::io::{self, Write};
|
||||
|
||||
/// A trait for converting a value to bytes.
|
||||
|
@ -4,9 +4,10 @@
|
||||
//!
|
||||
//! ```rust
|
||||
//! use wasmer_interface_types::{
|
||||
//! ast::*,
|
||||
//! ast::{Adapter, Export, Implementation, Import, Interfaces, Type},
|
||||
//! encoders::wat::*,
|
||||
//! interpreter::Instruction,
|
||||
//! types::InterfaceType,
|
||||
//! };
|
||||
//!
|
||||
//! let input: String = (&Interfaces {
|
||||
@ -54,7 +55,7 @@
|
||||
//! assert_eq!(input, output);
|
||||
//! ```
|
||||
|
||||
use crate::{ast::*, interpreter::Instruction};
|
||||
use crate::{ast::*, interpreter::Instruction, types::*};
|
||||
use std::string::ToString;
|
||||
|
||||
/// Encode an `InterfaceType` into a string.
|
||||
@ -346,7 +347,7 @@ impl<'input> ToString for &Interfaces<'input> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{ast::*, interpreter::Instruction};
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_interface_types() {
|
||||
|
@ -1,10 +1,7 @@
|
||||
//! The error module contains all the data structures that represent
|
||||
//! an error.
|
||||
|
||||
use crate::{
|
||||
ast::{InterfaceType, TypeKind},
|
||||
interpreter::Instruction,
|
||||
};
|
||||
use crate::{ast::TypeKind, interpreter::Instruction, types::InterfaceType};
|
||||
use std::{
|
||||
error::Error,
|
||||
fmt::{self, Display, Formatter},
|
||||
|
@ -1,10 +1,8 @@
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::wasm::{
|
||||
structures::{FunctionIndex, TypedIndex},
|
||||
values::InterfaceType,
|
||||
},
|
||||
interpreter::wasm::structures::{FunctionIndex, TypedIndex},
|
||||
interpreter::Instruction,
|
||||
types::InterfaceType,
|
||||
};
|
||||
|
||||
executable_instruction!(
|
||||
|
@ -6,7 +6,7 @@ mod strings;
|
||||
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind, InstructionResult, WasmValueNativeCastError},
|
||||
interpreter::wasm::values::{InterfaceValue, NativeType},
|
||||
values::{InterfaceValue, NativeType},
|
||||
};
|
||||
pub(crate) use argument_get::argument_get;
|
||||
pub(crate) use call_core::call_core;
|
||||
@ -163,13 +163,7 @@ where
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use crate::{
|
||||
ast,
|
||||
interpreter::wasm::{
|
||||
self,
|
||||
values::{InterfaceType, InterfaceValue},
|
||||
},
|
||||
};
|
||||
use crate::{ast::*, interpreter::wasm, types::*, values::*};
|
||||
use std::{cell::Cell, collections::HashMap, convert::TryInto, ops::Deref, rc::Rc};
|
||||
|
||||
pub(crate) struct Export {
|
||||
@ -265,7 +259,7 @@ pub(crate) mod tests {
|
||||
pub(crate) exports: HashMap<String, Export>,
|
||||
pub(crate) locals_or_imports: HashMap<usize, LocalImport>,
|
||||
pub(crate) memory: Memory,
|
||||
pub(crate) wit_types: Vec<ast::Type>,
|
||||
pub(crate) wit_types: Vec<Type>,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
@ -322,10 +316,10 @@ pub(crate) mod tests {
|
||||
hashmap
|
||||
},
|
||||
memory: Memory::new(vec![Cell::new(0); 128]),
|
||||
wit_types: vec![ast::Type::Record(ast::RecordType {
|
||||
wit_types: vec![Type::Record(RecordType {
|
||||
fields: vec1![
|
||||
InterfaceType::I32,
|
||||
InterfaceType::Record(ast::RecordType {
|
||||
InterfaceType::Record(RecordType {
|
||||
fields: vec1![InterfaceType::String, InterfaceType::F32],
|
||||
}),
|
||||
InterfaceType::I64,
|
||||
@ -351,7 +345,7 @@ pub(crate) mod tests {
|
||||
Some(&self.memory)
|
||||
}
|
||||
|
||||
fn wit_type(&self, index: u32) -> Option<&ast::Type> {
|
||||
fn wit_type(&self, index: u32) -> Option<&Type> {
|
||||
self.wit_types.get(index as usize)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::{
|
||||
ast::InterfaceType,
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::{wasm::values::InterfaceValue, Instruction},
|
||||
interpreter::Instruction,
|
||||
types::InterfaceType,
|
||||
values::InterfaceValue,
|
||||
};
|
||||
use std::convert::TryInto;
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
use crate::{
|
||||
ast::{InterfaceType, RecordType, Type, TypeKind},
|
||||
ast::{Type, TypeKind},
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::wasm::values::FlattenInterfaceValueIterator,
|
||||
interpreter::{
|
||||
stack::{Stack, Stackable},
|
||||
wasm::values::InterfaceValue,
|
||||
Instruction,
|
||||
},
|
||||
types::{InterfaceType, RecordType},
|
||||
values::{FlattenInterfaceValueIterator, InterfaceValue},
|
||||
vec1::Vec1,
|
||||
};
|
||||
use std::collections::VecDeque;
|
||||
|
||||
@ -56,7 +57,10 @@ fn record_lift_(
|
||||
}
|
||||
}
|
||||
|
||||
Ok(InterfaceValue::Record(values.into_iter().collect()))
|
||||
Ok(InterfaceValue::Record(
|
||||
Vec1::new(values.into_iter().collect())
|
||||
.expect("Record must have at least one field, zero given"), // normally unreachable because of the type-checking
|
||||
))
|
||||
}
|
||||
|
||||
executable_instruction!(
|
||||
@ -110,7 +114,7 @@ executable_instruction!(
|
||||
};
|
||||
|
||||
match runtime.stack.pop1() {
|
||||
Some(InterfaceValue::Record(record_values)) if record_type == &(&record_values).into() => {
|
||||
Some(InterfaceValue::Record(record_values)) if record_type == &(&*record_values).into() => {
|
||||
let values = FlattenInterfaceValueIterator::new(&record_values);
|
||||
|
||||
for value in values {
|
||||
@ -139,7 +143,7 @@ executable_instruction!(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::ast::{RecordType, Type};
|
||||
use super::*;
|
||||
|
||||
test_executable_instruction!(
|
||||
test_record_lift =
|
||||
@ -157,9 +161,9 @@ mod tests {
|
||||
InterfaceValue::I64(3),
|
||||
],
|
||||
instance: Instance::new(),
|
||||
stack: [InterfaceValue::Record(vec![
|
||||
stack: [InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(1),
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::String("Hello".to_string()),
|
||||
InterfaceValue::F32(2.),
|
||||
]),
|
||||
@ -171,11 +175,14 @@ mod tests {
|
||||
#[test]
|
||||
#[allow(non_snake_case, unused)]
|
||||
fn test_record_lift__to_rust_struct() {
|
||||
use crate::interpreter::{
|
||||
instructions::tests::{Export, Instance, LocalImport, Memory, MemoryView},
|
||||
stack::Stackable,
|
||||
wasm::values::{from_interface_values, InterfaceType, InterfaceValue},
|
||||
Instruction, Interpreter,
|
||||
use crate::{
|
||||
interpreter::{
|
||||
instructions::tests::{Export, Instance, LocalImport, Memory, MemoryView},
|
||||
stack::Stackable,
|
||||
Instruction, Interpreter,
|
||||
},
|
||||
types::InterfaceType,
|
||||
values::{from_interface_values, InterfaceValue},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use std::{cell::Cell, collections::HashMap, convert::TryInto};
|
||||
@ -252,7 +259,7 @@ mod tests {
|
||||
|
||||
instance
|
||||
},
|
||||
stack: [InterfaceValue::Record(vec![
|
||||
stack: [InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(1),
|
||||
InterfaceValue::I32(2),
|
||||
])],
|
||||
@ -295,9 +302,9 @@ mod tests {
|
||||
Instruction::RecordLower { type_index: 0 },
|
||||
],
|
||||
invocation_inputs: [
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(1),
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::String("Hello".to_string()),
|
||||
InterfaceValue::F32(2.),
|
||||
]),
|
||||
@ -321,9 +328,9 @@ mod tests {
|
||||
Instruction::RecordLift { type_index: 0 },
|
||||
],
|
||||
invocation_inputs: [
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(1),
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::String("Hello".to_string()),
|
||||
InterfaceValue::F32(2.),
|
||||
]),
|
||||
@ -332,9 +339,9 @@ mod tests {
|
||||
],
|
||||
instance: Instance::new(),
|
||||
stack: [
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(1),
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::String("Hello".to_string()),
|
||||
InterfaceValue::F32(2.),
|
||||
]),
|
||||
@ -363,9 +370,9 @@ mod tests {
|
||||
Instruction::RecordLower { type_index: 0 },
|
||||
],
|
||||
invocation_inputs: [
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(1),
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::String("Hello".to_string()),
|
||||
]),
|
||||
InterfaceValue::I64(3),
|
||||
|
@ -1,8 +1,9 @@
|
||||
use super::to_native;
|
||||
use crate::{
|
||||
ast::InterfaceType,
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::{wasm::values::InterfaceValue, Instruction},
|
||||
interpreter::Instruction,
|
||||
types::InterfaceType,
|
||||
values::InterfaceValue,
|
||||
};
|
||||
use std::{cell::Cell, convert::TryInto};
|
||||
|
||||
|
@ -4,11 +4,13 @@ mod instructions;
|
||||
pub mod stack;
|
||||
pub mod wasm;
|
||||
|
||||
use crate::errors::{InstructionResult, InterpreterResult};
|
||||
use crate::{
|
||||
errors::{InstructionResult, InterpreterResult},
|
||||
values::InterfaceValue,
|
||||
};
|
||||
pub use instructions::Instruction;
|
||||
use stack::Stack;
|
||||
use std::{convert::TryFrom, marker::PhantomData};
|
||||
use wasm::values::InterfaceValue;
|
||||
|
||||
/// Represents the `Runtime`, which is used by an adapter to execute
|
||||
/// its instructions.
|
||||
@ -59,13 +61,16 @@ pub(crate) type ExecutableInstruction<Instance, Export, LocalImport, Memory, Mem
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use std::{cell::Cell, collections::HashMap, convert::TryInto};
|
||||
/// use wasmer_interface_types::interpreter::{
|
||||
/// instructions::tests::{Export, Instance, LocalImport, Memory, MemoryView},
|
||||
/// // ^^^^^^^^^^^^ This is private and for testing purposes only.
|
||||
/// // It is basically a fake WebAssembly runtime.
|
||||
/// stack::Stackable,
|
||||
/// wasm::values::{InterfaceType, InterfaceValue},
|
||||
/// Instruction, Interpreter,
|
||||
/// use wasmer_interface_types::{
|
||||
/// interpreter::{
|
||||
/// instructions::tests::{Export, Instance, LocalImport, Memory, MemoryView},
|
||||
/// // ^^^^^^^^^^^^ This is private and for testing purposes only.
|
||||
/// // It is basically a fake WebAssembly runtime.
|
||||
/// stack::Stackable,
|
||||
/// Instruction, Interpreter,
|
||||
/// },
|
||||
/// types::InterfaceType,
|
||||
/// values::InterfaceValue,
|
||||
/// };
|
||||
///
|
||||
/// // 1. Creates an interpreter from a set of instructions. They will
|
||||
|
@ -2,8 +2,4 @@
|
||||
//! types, and traits —basically this is the part a runtime should
|
||||
//! take a look to use the `wasmer-interface-types` crate—.
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
mod serde;
|
||||
|
||||
pub mod structures;
|
||||
pub mod values;
|
||||
|
@ -1,9 +1,6 @@
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use crate::{
|
||||
ast,
|
||||
interpreter::wasm::values::{InterfaceType, InterfaceValue},
|
||||
};
|
||||
use crate::{ast, types::InterfaceType, values::InterfaceValue};
|
||||
use std::{cell::Cell, ops::Deref};
|
||||
|
||||
pub trait TypedIndex: Copy + Clone {
|
||||
|
23
src/lib.rs
23
src/lib.rs
@ -1,16 +1,18 @@
|
||||
//! This crate contains an implementation of [WebAssembly Interface
|
||||
//! Types][wit] (abbreviated WIT). It is composed of 4 parts:
|
||||
//! Types][wit] (abbreviated WIT). It is composed of 5 parts:
|
||||
//!
|
||||
//! 1. [AST]: To represent the WIT language as a tree
|
||||
//! 1. [Types] and [Values]: To represent the WIT types and values
|
||||
//! representations,
|
||||
//! 2. [AST]: To represent the WIT language as a tree
|
||||
//! (which is not really abstract). This is the central
|
||||
//! representation of the language.
|
||||
//! 2. [Decoders](decoders): To read the [AST] from a particular data
|
||||
//! representation; for instance, [`decoders::binary`] reads the
|
||||
//! [AST] from a binary.
|
||||
//! 3. [Encoders](encoders): To write the [AST](ast) into a particular
|
||||
//! 3. [Decoders](decoders): To read the [AST] from a particular data
|
||||
//! representation; for instance, [`decoders::binary::parse`] reads
|
||||
//! the [AST] from a binary.
|
||||
//! 4. [Encoders](encoders): To write the [AST](ast) into a particular
|
||||
//! format; for instance, [`encoders::wat`] writes the [AST] into a
|
||||
//! string representing WIT with its textual format.
|
||||
//! 4. [Interpreter](interpreter): WIT defines a concept called
|
||||
//! 5. [Interpreter](interpreter): WIT defines a concept called
|
||||
//! Adapters. An adapter contains a set of [instructions]. So, in
|
||||
//! more details, this module contains:
|
||||
//! * [A very light and generic stack
|
||||
@ -30,8 +32,9 @@
|
||||
//! this is the part a runtime should take a look to use the
|
||||
//! `wasmer-interface-types` crate—.
|
||||
//!
|
||||
//!
|
||||
//! [wit]: https://github.com/WebAssembly/interface-types
|
||||
//! [Types]: types
|
||||
//! [Values]: values
|
||||
//! [AST]: ast
|
||||
//! [instructions]: interpreter::Instruction
|
||||
|
||||
@ -51,10 +54,14 @@
|
||||
#![doc(html_logo_url = "https://github.com/wasmerio.png")]
|
||||
|
||||
pub mod ast;
|
||||
pub mod types;
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
pub mod decoders;
|
||||
pub mod encoders;
|
||||
pub mod errors;
|
||||
pub mod interpreter;
|
||||
#[cfg(feature = "serde")]
|
||||
mod serde;
|
||||
pub mod values;
|
||||
pub mod vec1;
|
||||
|
@ -1,6 +1,8 @@
|
||||
//! Collection of helpful macros.
|
||||
|
||||
/// This macro creates a `Vec1` by checking at compile-time that its
|
||||
/// invariant holds.
|
||||
#[allow(unused)]
|
||||
#[macro_export]
|
||||
macro_rules! vec1 {
|
||||
($item:expr; 0) => {
|
||||
compile_error!("Cannot create an empty `Vec1`, it violates its invariant.")
|
||||
@ -96,11 +98,14 @@ macro_rules! test_executable_instruction {
|
||||
#[test]
|
||||
#[allow(non_snake_case, unused)]
|
||||
fn $test_name() {
|
||||
use crate::interpreter::{
|
||||
instructions::tests::{Export, Instance, LocalImport, Memory, MemoryView},
|
||||
stack::Stackable,
|
||||
wasm::values::{InterfaceType, InterfaceValue},
|
||||
Instruction, Interpreter,
|
||||
use crate::{
|
||||
interpreter::{
|
||||
instructions::tests::{Export, Instance, LocalImport, Memory, MemoryView},
|
||||
stack::Stackable,
|
||||
Instruction, Interpreter,
|
||||
},
|
||||
types::InterfaceType,
|
||||
values::InterfaceValue,
|
||||
};
|
||||
use std::{cell::Cell, collections::HashMap, convert::TryInto};
|
||||
|
||||
@ -135,11 +140,14 @@ macro_rules! test_executable_instruction {
|
||||
#[test]
|
||||
#[allow(non_snake_case, unused)]
|
||||
fn $test_name() {
|
||||
use crate::interpreter::{
|
||||
instructions::tests::{Export, Instance, LocalImport, Memory, MemoryView},
|
||||
stack::Stackable,
|
||||
wasm::values::{InterfaceType, InterfaceValue},
|
||||
Instruction, Interpreter,
|
||||
use crate::{
|
||||
interpreter::{
|
||||
instructions::tests::{Export, Instance, LocalImport, Memory, MemoryView},
|
||||
stack::Stackable,
|
||||
Instruction, Interpreter,
|
||||
},
|
||||
types::InterfaceType,
|
||||
values::InterfaceValue,
|
||||
};
|
||||
use std::{cell::Cell, collections::HashMap, convert::TryInto};
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
//! Provides a deserializer from WIT values to Rust value.
|
||||
|
||||
use crate::{
|
||||
ast::InterfaceType,
|
||||
interpreter::wasm::values::{FlattenInterfaceValueIterator, InterfaceValue},
|
||||
types::InterfaceType,
|
||||
values::{FlattenInterfaceValueIterator, InterfaceValue},
|
||||
};
|
||||
use serde::{de, Deserialize};
|
||||
use std::{
|
||||
@ -20,9 +20,9 @@ use std::{
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasmer_interface_types::interpreter::wasm::values::{
|
||||
/// InterfaceValue,
|
||||
/// from_interface_values,
|
||||
/// use wasmer_interface_types::{
|
||||
/// values::{InterfaceValue, from_interface_values},
|
||||
/// vec1::Vec1,
|
||||
/// };
|
||||
/// use serde::Deserialize;
|
||||
///
|
||||
@ -36,11 +36,11 @@ use std::{
|
||||
/// y: f32,
|
||||
/// };
|
||||
///
|
||||
/// let values = vec![InterfaceValue::Record(vec![
|
||||
/// let values = vec![InterfaceValue::Record(Vec1::new(vec![
|
||||
/// InterfaceValue::String("abc".to_string()),
|
||||
/// InterfaceValue::Record(vec![InterfaceValue::I32(1), InterfaceValue::I64(2)]),
|
||||
/// InterfaceValue::Record(Vec1::new(vec![InterfaceValue::I32(1), InterfaceValue::I64(2)]).unwrap()),
|
||||
/// InterfaceValue::F32(3.),
|
||||
/// ])];
|
||||
/// ]).unwrap())];
|
||||
/// let t = from_interface_values::<T>(&values).unwrap();
|
||||
///
|
||||
/// assert_eq!(
|
||||
@ -513,7 +513,7 @@ mod tests {
|
||||
#[derive(Deserialize, Debug, PartialEq)]
|
||||
struct S(i8);
|
||||
|
||||
let input = vec![InterfaceValue::Record(vec![InterfaceValue::S8(42)])];
|
||||
let input = vec![InterfaceValue::Record(vec1![InterfaceValue::S8(42)])];
|
||||
let output = S(42);
|
||||
|
||||
assert_eq!(from_interface_values::<S>(&input).unwrap(), output);
|
||||
@ -525,7 +525,7 @@ mod tests {
|
||||
#[derive(Deserialize, Debug, PartialEq)]
|
||||
struct S(i8, f32);
|
||||
|
||||
let input = vec![InterfaceValue::Record(vec![
|
||||
let input = vec![InterfaceValue::Record(vec1![
|
||||
InterfaceValue::S8(7),
|
||||
InterfaceValue::F32(42.),
|
||||
])];
|
||||
@ -543,7 +543,7 @@ mod tests {
|
||||
y: f32,
|
||||
}
|
||||
|
||||
let input = vec![InterfaceValue::Record(vec![
|
||||
let input = vec![InterfaceValue::Record(vec1![
|
||||
InterfaceValue::S8(7),
|
||||
InterfaceValue::F32(42.),
|
||||
])];
|
||||
@ -568,13 +568,13 @@ mod tests {
|
||||
p2: Point,
|
||||
}
|
||||
|
||||
let input = vec![InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec![
|
||||
let input = vec![InterfaceValue::Record(vec1![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(1),
|
||||
InterfaceValue::I32(2),
|
||||
InterfaceValue::I32(3),
|
||||
]),
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(4),
|
||||
InterfaceValue::I32(5),
|
||||
InterfaceValue::I32(6),
|
@ -1,6 +1,6 @@
|
||||
//! Provides a serializer from Rust value to WIT values.
|
||||
|
||||
use crate::interpreter::wasm::values::InterfaceValue;
|
||||
use crate::{values::InterfaceValue, vec1::Vec1};
|
||||
use serde::{ser, Serialize};
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
@ -13,9 +13,9 @@ use std::fmt::{self, Display};
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasmer_interface_types::interpreter::wasm::values::{
|
||||
/// InterfaceValue,
|
||||
/// to_interface_value,
|
||||
/// use wasmer_interface_types::{
|
||||
/// values::{InterfaceValue, to_interface_value},
|
||||
/// vec1::Vec1,
|
||||
/// };
|
||||
/// use serde::Serialize;
|
||||
///
|
||||
@ -37,11 +37,11 @@ use std::fmt::{self, Display};
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// to_interface_value(&input).unwrap(),
|
||||
/// InterfaceValue::Record(vec![
|
||||
/// InterfaceValue::Record(Vec1::new(vec![
|
||||
/// InterfaceValue::String("abc".to_string()),
|
||||
/// InterfaceValue::Record(vec![InterfaceValue::I32(1), InterfaceValue::I64(2)]),
|
||||
/// InterfaceValue::Record(Vec1::new(vec![InterfaceValue::I32(1), InterfaceValue::I64(2)]).unwrap()),
|
||||
/// InterfaceValue::F32(3.),
|
||||
/// ]),
|
||||
/// ]).unwrap()),
|
||||
/// );
|
||||
/// ```
|
||||
pub fn to_interface_value<T>(value: &T) -> Result<InterfaceValue, SerializeError>
|
||||
@ -107,6 +107,9 @@ pub enum SerializeError {
|
||||
/// serialization.
|
||||
InternalValuesCorrupted,
|
||||
|
||||
/// A record must contain at least one field.
|
||||
RecordNeedsAtLeastOneField,
|
||||
|
||||
/// Arbitrary message.
|
||||
Message(String),
|
||||
}
|
||||
@ -128,6 +131,10 @@ impl Display for SerializeError {
|
||||
formatter,
|
||||
"the internal values have been corrutped during the serialization"
|
||||
),
|
||||
Self::RecordNeedsAtLeastOneField => write!(
|
||||
formatter,
|
||||
"a record must contain at least one field, zero given"
|
||||
),
|
||||
Self::Message(ref msg) => write!(formatter, "{}", msg),
|
||||
}
|
||||
}
|
||||
@ -374,7 +381,9 @@ impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
let record = InterfaceValue::Record(self.pop()?);
|
||||
let record = InterfaceValue::Record(
|
||||
Vec1::new(self.pop()?).map_err(|_| Self::Error::RecordNeedsAtLeastOneField)?,
|
||||
);
|
||||
self.last().push(record);
|
||||
|
||||
Ok(())
|
||||
@ -432,7 +441,9 @@ impl<'a> ser::SerializeStruct for &'a mut Serializer {
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
let record = InterfaceValue::Record(self.pop()?);
|
||||
let record = InterfaceValue::Record(
|
||||
Vec1::new(self.pop()?).map_err(|_| Self::Error::RecordNeedsAtLeastOneField)?,
|
||||
);
|
||||
self.last().push(record);
|
||||
|
||||
Ok(())
|
||||
@ -512,7 +523,7 @@ mod tests {
|
||||
struct S(i8, f32);
|
||||
|
||||
let input = S(7, 42.);
|
||||
let output = InterfaceValue::Record(vec![InterfaceValue::S8(7), InterfaceValue::F32(42.)]);
|
||||
let output = InterfaceValue::Record(vec1![InterfaceValue::S8(7), InterfaceValue::F32(42.)]);
|
||||
|
||||
assert_eq!(to_interface_value(&input).unwrap(), output);
|
||||
}
|
||||
@ -527,7 +538,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let input = S { x: 7, y: 42. };
|
||||
let output = InterfaceValue::Record(vec![InterfaceValue::S8(7), InterfaceValue::F32(42.)]);
|
||||
let output = InterfaceValue::Record(vec1![InterfaceValue::S8(7), InterfaceValue::F32(42.)]);
|
||||
|
||||
assert_eq!(to_interface_value(&input).unwrap(), output);
|
||||
}
|
||||
@ -552,13 +563,13 @@ mod tests {
|
||||
p1: Point { x: 1, y: 2, z: 3 },
|
||||
p2: Point { x: 4, y: 5, z: 6 },
|
||||
};
|
||||
let output = InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec![
|
||||
let output = InterfaceValue::Record(vec1![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(1),
|
||||
InterfaceValue::I32(2),
|
||||
InterfaceValue::I32(3),
|
||||
]),
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(4),
|
||||
InterfaceValue::I32(5),
|
||||
InterfaceValue::I32(6),
|
61
src/types.rs
Normal file
61
src/types.rs
Normal file
@ -0,0 +1,61 @@
|
||||
//! This module defines the WIT types.
|
||||
|
||||
use crate::vec1::Vec1;
|
||||
|
||||
/// Represents the types supported by WIT.
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum InterfaceType {
|
||||
/// A 8-bits signed integer.
|
||||
S8,
|
||||
|
||||
/// A 16-bits signed integer.
|
||||
S16,
|
||||
|
||||
/// A 32-bits signed integer.
|
||||
S32,
|
||||
|
||||
/// A 64-bits signed integer.
|
||||
S64,
|
||||
|
||||
/// A 8-bits unsigned integer.
|
||||
U8,
|
||||
|
||||
/// A 16-bits unsigned integer.
|
||||
U16,
|
||||
|
||||
/// A 32-bits unsigned integer.
|
||||
U32,
|
||||
|
||||
/// A 64-bits unsigned integer.
|
||||
U64,
|
||||
|
||||
/// A 32-bits float.
|
||||
F32,
|
||||
|
||||
/// A 64-bits float.
|
||||
F64,
|
||||
|
||||
/// A string.
|
||||
String,
|
||||
|
||||
/// An `any` reference.
|
||||
Anyref,
|
||||
|
||||
/// A 32-bits integer (as defined in WebAssembly core).
|
||||
I32,
|
||||
|
||||
/// A 64-bits integer (as defiend in WebAssembly core).
|
||||
I64,
|
||||
|
||||
/// A record.
|
||||
Record(RecordType),
|
||||
}
|
||||
|
||||
/// Represents a record type.
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct RecordType {
|
||||
/// Types representing the fields.
|
||||
/// A record must have at least one field, hence the
|
||||
/// [`Vec1`][crate::vec1::Vec1].
|
||||
pub fields: Vec1<InterfaceType>,
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
//! Defines WIT values and associated operations.
|
||||
|
||||
pub use crate::ast::{InterfaceType, RecordType};
|
||||
use crate::{errors::WasmValueNativeCastError, vec1::Vec1};
|
||||
use crate::{
|
||||
errors::WasmValueNativeCastError,
|
||||
types::{InterfaceType, RecordType},
|
||||
vec1::Vec1,
|
||||
};
|
||||
use std::{convert::TryFrom, slice::Iter};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
pub use crate::interpreter::wasm::serde::{de::*, ser::*};
|
||||
pub use crate::serde::{de::from_interface_values, ser::to_interface_value};
|
||||
|
||||
/// A WIT value.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@ -51,7 +54,7 @@ pub enum InterfaceValue {
|
||||
I64(i64),
|
||||
|
||||
/// A record.
|
||||
Record(Vec<InterfaceValue>),
|
||||
Record(Vec1<InterfaceValue>),
|
||||
}
|
||||
|
||||
impl From<&InterfaceValue> for InterfaceType {
|
||||
@ -71,7 +74,7 @@ impl From<&InterfaceValue> for InterfaceType {
|
||||
//InterfaceValue::Anyref(_) => Self::Anyref,
|
||||
InterfaceValue::I32(_) => Self::I32,
|
||||
InterfaceValue::I64(_) => Self::I64,
|
||||
InterfaceValue::Record(values) => Self::Record(values.into()),
|
||||
InterfaceValue::Record(values) => Self::Record((&**values).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,7 +218,7 @@ mod tests {
|
||||
#[allow(non_snake_case)]
|
||||
fn interface_type_from_interface_value__record() {
|
||||
assert_eq!(
|
||||
InterfaceType::from(&InterfaceValue::Record(vec![
|
||||
InterfaceType::from(&InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(1),
|
||||
InterfaceValue::S8(2)
|
||||
])),
|
||||
@ -225,9 +228,9 @@ mod tests {
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
InterfaceType::from(&InterfaceValue::Record(vec![
|
||||
InterfaceType::from(&InterfaceValue::Record(vec1![
|
||||
InterfaceValue::I32(1),
|
||||
InterfaceValue::Record(vec![
|
||||
InterfaceValue::Record(vec1![
|
||||
InterfaceValue::String("a".to_string()),
|
||||
InterfaceValue::F64(42.)
|
||||
]),
|
@ -1,6 +1,6 @@
|
||||
use wasmer_interface_types::{
|
||||
ast::*, decoders::binary::parse, encoders::binary::ToBytes, interpreter::Instruction,
|
||||
vec1::Vec1,
|
||||
ast::*, decoders::binary::parse, encoders::binary::ToBytes, interpreter::Instruction, types::*,
|
||||
vec1,
|
||||
};
|
||||
|
||||
/// Tests an AST to binary, then binary to AST roundtrip.
|
||||
@ -17,7 +17,7 @@ fn test_binary_encoding_decoding_roundtrip() {
|
||||
outputs: vec![InterfaceType::S32],
|
||||
},
|
||||
Type::Record(RecordType {
|
||||
fields: Vec1::new(vec![InterfaceType::String, InterfaceType::I32]).unwrap(),
|
||||
fields: vec1![InterfaceType::String, InterfaceType::I32],
|
||||
}),
|
||||
],
|
||||
imports: vec![Import {
|
||||
|
Loading…
Reference in New Issue
Block a user