feat(wasmer-interface-types) Draft.

This commit is contained in:
Ivan Enderlin 2019-09-11 23:51:20 +02:00
parent 174cc9f0ec
commit b3af77c92d
7 changed files with 293 additions and 18 deletions

43
Cargo.lock generated
View File

@ -708,6 +708,18 @@ name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lexical-core"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.2.62"
@ -810,6 +822,16 @@ dependencies = [
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nom"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lexical-core 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.1.43"
@ -1236,6 +1258,11 @@ name = "stable_deref_trait"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "static_assertions"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "strsim"
version = "0.8.0"
@ -1609,6 +1636,15 @@ dependencies = [
"wasmer-singlepass-backend 0.7.0",
]
[[package]]
name = "wasmer-interface-types"
version = "0.6.0"
dependencies = [
"nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.6.0",
"wasmer-runtime-core 0.6.0",
]
[[package]]
name = "wasmer-kernel-loader"
version = "0.1.0"
@ -1933,7 +1969,12 @@ dependencies = [
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
<<<<<<< HEAD
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
=======
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
"checksum lexical-core 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d11f3928ffd249baadf9f083cdea16d7cf317b2a8be6227e1169102432a36d2"
>>>>>>> feat(wasmer-interface-types) Draft.
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
"checksum llvm-sys 80.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2110cd4daf9cd8e39dd3b933b1a2a2ac7315e91f7c92b3a20beab526c63b5978"
@ -1946,6 +1987,7 @@ dependencies = [
"checksum nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
"checksum nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c618b63422da4401283884e6668d39f819a106ef51f5f59b81add00075da35ca"
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
@ -1999,6 +2041,7 @@ dependencies = [
"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
"checksum static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum structopt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ac9d6e93dd792b217bf89cda5c14566e3043960c6f9da890c2ba5d09d07804c"
"checksum structopt-derive 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ae9e5165d463a0dea76967d021f8d0f9316057bf5163aa2a4843790e842ff37"

View File

@ -40,25 +40,26 @@ wasmer-emscripten-tests = { path = "lib/emscripten-tests", optional = true }
[workspace]
members = [
"examples/plugin-for-example",
"lib/clif-backend",
"lib/singlepass-backend",
"lib/runtime",
# "lib/runtime-abi",
"lib/runtime-core",
"lib/dev-utils",
"lib/emscripten",
"lib/spectests",
"lib/win-exception-handler",
"lib/runtime-c-api",
"lib/llvm-backend",
"lib/wasi",
"lib/middleware-common",
"lib/emscripten-tests",
"lib/interface-types",
"lib/kernel-loader",
"lib/kernel-net",
"lib/dev-utils",
"lib/wasi-tests",
"lib/emscripten-tests",
"lib/llvm-backend",
"lib/middleware-common",
"lib/middleware-common-tests",
"examples/plugin-for-example"
"lib/runtime",
"lib/runtime-c-api",
"lib/runtime-core",
"lib/singlepass-backend",
"lib/spectests",
"lib/wasi",
"lib/wasi-tests",
"lib/win-exception-handler"
# "lib/runtime-abi",
]
[build-dependencies]
@ -100,6 +101,7 @@ backend-singlepass = [
]
wasi = ["wasmer-wasi"]
managed = ["backend-singlepass", "wasmer-runtime-core/managed"]
interface-types = ["wasmer-runtime/interface-types"]
# vfs = ["wasmer-runtime-abi"]
[[example]]

View File

@ -0,0 +1,15 @@
[package]
name = "wasmer-interface-types"
version = "0.6.0"
description = "WebAssembly Interface Types library for Wasmer"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
repository = "https://github.com/wasmerio/wasmer"
edition = "2018"
[dependencies]
nom = "5.0"
[dev-dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0", features = ["backend-cranelift"] }
wasmer-clif-backend = { path = "../clif-backend", version = "0.6.0" }

View File

@ -0,0 +1,213 @@
use nom::{
error::{make_error, ErrorKind, ParseError},
Err, IResult,
};
use std::{convert::TryFrom, str};
macro_rules! d {
($expression:expr) => {
match $expression {
tmp => {
eprintln!(
"[{}:{}] {} = {:?}",
file!(),
line!(),
stringify!($expression),
&tmp
);
tmp
}
}
};
}
#[derive(PartialEq, Debug)]
enum Type {
Int,
Float,
Any,
String,
Seq,
I32,
I64,
F32,
F64,
AnyRef,
}
#[derive(Debug)]
struct Export<'input> {
name: &'input str,
input_types: Vec<Type>,
output_types: Vec<Type>,
}
impl TryFrom<u64> for Type {
type Error = &'static str;
fn try_from(code: u64) -> Result<Self, Self::Error> {
Ok(match code {
0x7fff => Self::Int,
0x7ffe => Self::Float,
0x7ffd => Self::Any,
0x7ffc => Self::String,
0x7ffb => Self::Seq,
0x7f => Self::I32,
0x7e => Self::I64,
0x7d => Self::F32,
0x7c => Self::F64,
0x6f => Self::AnyRef,
_ => return Err("Unknown type code."),
})
}
}
fn leb<'input, E: ParseError<&'input [u8]>>(input: &'input [u8]) -> IResult<&'input [u8], u64, E> {
if input.is_empty() {
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
}
let (output, bytes) = match input.iter().position(|&byte| byte & 0x80 == 0) {
Some(position) => (&input[position + 1..], &input[..position + 1]),
None => (&[] as &[u8], input),
};
Ok((
output,
bytes
.iter()
.rev()
.fold(0, |acc, byte| (acc << 7) | (byte & 0x7f) as u64),
))
}
fn string<'input, E: ParseError<&'input [u8]>>(
input: &'input [u8],
) -> IResult<&'input [u8], &'input str, E> {
if input.is_empty() {
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
}
let length = input[0] as usize;
let input = &input[1..];
if input.len() < length {
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
}
Ok((&input[length..], unsafe {
str::from_utf8_unchecked(&input[..length])
}))
}
fn list<'input, I: ::std::fmt::Debug, E: ParseError<&'input [u8]>>(
input: &'input [u8],
item_parser: fn(&'input [u8]) -> IResult<&'input [u8], I, E>,
) -> IResult<&'input [u8], Vec<I>, E> {
if input.is_empty() {
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
}
let length = input[0] as usize;
let mut input = &input[1..];
if input.len() < length {
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
}
let mut items = vec![];
for _ in 0..length {
let (next_input, item) = item_parser(input)?;
items.push(item);
input = next_input;
}
Ok((input, items))
}
fn ty<'input, E: ParseError<&'input [u8]>>(input: &'input [u8]) -> IResult<&'input [u8], Type, E> {
if input.is_empty() {
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
}
let (input, ty) = leb(input)?;
match Type::try_from(ty) {
Ok(ty) => Ok((input, ty)),
Err(_) => Err(Err::Error(make_error(input, ErrorKind::ParseTo))),
}
}
pub fn parse<'input, E: ParseError<&'input [u8]>>(
bytes: &'input [u8],
) -> IResult<&'input [u8], bool, E> {
let input = bytes;
let (mut input, number_of_exports) = leb(input)?;
d!(number_of_exports);
let mut exports = vec![];
for export_nth in 0..number_of_exports {
let (next_input, export_name) = string(input)?;
input = next_input;
let (next_input, export_input_types) = list(input, ty)?;
input = next_input;
let (next_input, export_output_types) = list(input, ty)?;
input = next_input;
exports.push(Export {
name: export_name,
input_types: export_input_types,
output_types: export_output_types,
});
}
d!(exports);
Ok((&[] as &[u8], true))
}
#[cfg(test)]
mod tests {
use super::parse;
use std::fs;
use wasmer_clif_backend::CraneliftCompiler;
use wasmer_runtime_core as runtime;
fn get_module() -> runtime::Module {
runtime::compile_with(
fs::read("tests/assets/hello_world.wasm")
.expect("Failed to read `tests/assets/hello_world.wasm`.")
.as_slice(),
&CraneliftCompiler::new(),
)
.expect("Failed to parse the `hello_world.wasm` module.")
}
#[test]
fn test_has_custom_section() {
let module = get_module();
let custom_section = module.info().custom_sections.get("interface-types");
assert!(custom_section.is_some());
}
#[test]
fn test_parse() {
let module = get_module();
let custom_section_bytes = module
.info()
.custom_sections
.get("interface-types")
.unwrap()
.as_slice();
parse::<()>(custom_section_bytes);
}
}

Binary file not shown.

View File

@ -55,7 +55,8 @@ cc = "1.0"
debug = []
trace = ["debug"]
# backend flags used in conditional compilation of Backend::variants
"backend-cranelift" = []
"backend-singlepass" = []
"backend-llvm" = []
managed = []
backend-cranelift = []
backend-singlepass = []
backend-llvm = []
managed = []
interface-types = []

View File

@ -41,6 +41,7 @@ singlepass = ["wasmer-singlepass-backend"]
default-backend-singlepass = ["singlepass"]
default-backend-llvm = ["llvm"]
default-backend-cranelift = ["cranelift"]
interface-types = ["wasmer-runtime-core/interface-types"]
[[bench]]
name = "nginx"