mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-26 15:11:37 +00:00
feat(interface-types) Encode Interfaces
to WAT.
This commit is contained in:
@ -1,4 +1,6 @@
|
|||||||
use crate::ast::{Adapter, Export, Forward, ImportedFunction, Instruction, InterfaceType, Type};
|
use crate::ast::{
|
||||||
|
Adapter, Export, Forward, ImportedFunction, Instruction, InterfaceType, Interfaces, Type,
|
||||||
|
};
|
||||||
|
|
||||||
impl From<&InterfaceType> for String {
|
impl From<&InterfaceType> for String {
|
||||||
fn from(interface_type: &InterfaceType) -> Self {
|
fn from(interface_type: &InterfaceType) -> Self {
|
||||||
@ -186,6 +188,83 @@ impl<'input> From<&Forward<'input>> for String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'input> From<&Interfaces<'input>> for String {
|
||||||
|
fn from(interfaces: &Interfaces) -> Self {
|
||||||
|
let mut output = String::from(";; Interfaces");
|
||||||
|
|
||||||
|
let exports = interfaces
|
||||||
|
.exports
|
||||||
|
.iter()
|
||||||
|
.fold(String::new(), |mut accumulator, export| {
|
||||||
|
accumulator.push_str(&format!("\n\n;; Interface, Export {}\n", export.name));
|
||||||
|
accumulator.push_str(&String::from(export));
|
||||||
|
accumulator
|
||||||
|
});
|
||||||
|
|
||||||
|
let types = interfaces
|
||||||
|
.types
|
||||||
|
.iter()
|
||||||
|
.fold(String::new(), |mut accumulator, ty| {
|
||||||
|
accumulator.push_str(&format!("\n\n;; Interface, Ty {}\n", ty.name));
|
||||||
|
accumulator.push_str(&String::from(ty));
|
||||||
|
accumulator
|
||||||
|
});
|
||||||
|
|
||||||
|
let imported_functions = interfaces.imported_functions.iter().fold(
|
||||||
|
String::new(),
|
||||||
|
|mut accumulator, imported_function| {
|
||||||
|
accumulator.push_str(&format!(
|
||||||
|
"\n\n;; Interface, Imported function {}.{}\n",
|
||||||
|
imported_function.namespace, imported_function.name
|
||||||
|
));
|
||||||
|
accumulator.push_str(&String::from(imported_function));
|
||||||
|
accumulator
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let adapters =
|
||||||
|
interfaces
|
||||||
|
.adapters
|
||||||
|
.iter()
|
||||||
|
.fold(String::new(), |mut accumulator, adapter| {
|
||||||
|
match adapter {
|
||||||
|
Adapter::Import {
|
||||||
|
namespace, name, ..
|
||||||
|
} => accumulator.push_str(&format!(
|
||||||
|
"\n\n;; Interface, Adapter {}.{}\n",
|
||||||
|
namespace, name
|
||||||
|
)),
|
||||||
|
|
||||||
|
Adapter::Export { name, .. } => {
|
||||||
|
accumulator.push_str(&format!("\n\n;; Interface, Adapter {}\n", name))
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
accumulator.push_str(&String::from(adapter));
|
||||||
|
accumulator
|
||||||
|
});
|
||||||
|
|
||||||
|
let forwards =
|
||||||
|
interfaces
|
||||||
|
.forwards
|
||||||
|
.iter()
|
||||||
|
.fold(String::new(), |mut accumulator, forward| {
|
||||||
|
accumulator.push_str(&format!("\n\n;; Interface, Forward {}\n", forward.name));
|
||||||
|
accumulator.push_str(&String::from(forward));
|
||||||
|
accumulator
|
||||||
|
});
|
||||||
|
|
||||||
|
output.push_str(&exports);
|
||||||
|
output.push_str(&types);
|
||||||
|
output.push_str(&imported_functions);
|
||||||
|
output.push_str(&adapters);
|
||||||
|
output.push_str(&forwards);
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
@ -443,4 +522,83 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_interfaces() {
|
||||||
|
let input: String = (&Interfaces {
|
||||||
|
exports: vec![
|
||||||
|
Export {
|
||||||
|
name: "foo",
|
||||||
|
input_types: vec![InterfaceType::I32],
|
||||||
|
output_types: vec![],
|
||||||
|
},
|
||||||
|
Export {
|
||||||
|
name: "bar",
|
||||||
|
input_types: vec![],
|
||||||
|
output_types: vec![],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
types: vec![],
|
||||||
|
imported_functions: vec![
|
||||||
|
ImportedFunction {
|
||||||
|
namespace: "ns",
|
||||||
|
name: "foo",
|
||||||
|
input_types: vec![],
|
||||||
|
output_types: vec![InterfaceType::I32],
|
||||||
|
},
|
||||||
|
ImportedFunction {
|
||||||
|
namespace: "ns",
|
||||||
|
name: "bar",
|
||||||
|
input_types: vec![],
|
||||||
|
output_types: vec![],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
adapters: vec![
|
||||||
|
Adapter::Import {
|
||||||
|
namespace: "ns",
|
||||||
|
name: "foo",
|
||||||
|
input_types: vec![InterfaceType::I32],
|
||||||
|
output_types: vec![],
|
||||||
|
instructions: vec![Instruction::ArgumentGet(42)],
|
||||||
|
},
|
||||||
|
Adapter::Export {
|
||||||
|
name: "bar",
|
||||||
|
input_types: vec![],
|
||||||
|
output_types: vec![],
|
||||||
|
instructions: vec![Instruction::ArgumentGet(42)],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
forwards: vec![Forward { name: "main" }],
|
||||||
|
})
|
||||||
|
.into();
|
||||||
|
let output = r#";; Interfaces
|
||||||
|
|
||||||
|
;; Interface, Export foo
|
||||||
|
(@interface export "foo"
|
||||||
|
(param i32))
|
||||||
|
|
||||||
|
;; Interface, Export bar
|
||||||
|
(@interface export "bar")
|
||||||
|
|
||||||
|
;; Interface, Imported function ns.foo
|
||||||
|
(@interface func $ns_foo (import "ns" "foo")
|
||||||
|
(result i32))
|
||||||
|
|
||||||
|
;; Interface, Imported function ns.bar
|
||||||
|
(@interface func $ns_bar (import "ns" "bar"))
|
||||||
|
|
||||||
|
;; Interface, Adapter ns.foo
|
||||||
|
(@interface adapt (import "ns" "foo")
|
||||||
|
(param i32)
|
||||||
|
arg.get 42)
|
||||||
|
|
||||||
|
;; Interface, Adapter bar
|
||||||
|
(@interface adapt (export "bar")
|
||||||
|
arg.get 42)
|
||||||
|
|
||||||
|
;; Interface, Forward main
|
||||||
|
(@interface forward (export "main"))"#;
|
||||||
|
|
||||||
|
assert_eq!(input, output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ pub use decoders::binary::parse as parse_binary;
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{ast::*, parse_binary};
|
use crate::{ast::*, encoders::wat::*, parse_binary};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use wasmer_clif_backend::CraneliftCompiler;
|
use wasmer_clif_backend::CraneliftCompiler;
|
||||||
use wasmer_runtime_core as runtime;
|
use wasmer_runtime_core as runtime;
|
||||||
@ -103,6 +103,50 @@ mod tests {
|
|||||||
forwards: vec![Forward { name: "main" }]
|
forwards: vec![Forward { name: "main" }]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let wat = String::from(&interfaces);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wat,
|
||||||
|
r#";; Interfaces
|
||||||
|
|
||||||
|
;; Interface, Export strlen
|
||||||
|
(@interface export "strlen"
|
||||||
|
(param i32)
|
||||||
|
(result i32))
|
||||||
|
|
||||||
|
;; Interface, Export write_null_byte
|
||||||
|
(@interface export "write_null_byte"
|
||||||
|
(param i32 i32)
|
||||||
|
(result i32))
|
||||||
|
|
||||||
|
;; Interface, Imported function host.console_log
|
||||||
|
(@interface func $host_console_log (import "host" "console_log")
|
||||||
|
(param String))
|
||||||
|
|
||||||
|
;; Interface, Imported function host.document_title
|
||||||
|
(@interface func $host_document_title (import "host" "document_title")
|
||||||
|
(result String))
|
||||||
|
|
||||||
|
;; Interface, Adapter host.console_log
|
||||||
|
(@interface adapt (import "host" "console_log")
|
||||||
|
(param i32)
|
||||||
|
arg.get 0
|
||||||
|
arg.get 0
|
||||||
|
call-export "strlen"
|
||||||
|
read-utf8
|
||||||
|
call 0)
|
||||||
|
|
||||||
|
;; Interface, Adapter host.document_title
|
||||||
|
(@interface adapt (import "host" "document_title")
|
||||||
|
(result i32)
|
||||||
|
call 1
|
||||||
|
write-utf8 "alloc"
|
||||||
|
call-export "write_null_byte")
|
||||||
|
|
||||||
|
;; Interface, Forward main
|
||||||
|
(@interface forward (export "main"))"#,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(_) => assert!(false),
|
Err(_) => assert!(false),
|
||||||
|
Reference in New Issue
Block a user