mirror of
https://github.com/fluencelabs/marine-rs-sdk-test
synced 2024-12-04 15:20:18 +00:00
move logic to a separate crate
This commit is contained in:
parent
68cea490d9
commit
8b2c6145fd
11
Cargo.toml
11
Cargo.toml
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fluence"
|
||||
version = "0.1.11" # remember to update html_root_url
|
||||
version = "0.2.0" # remember to update html_root_url
|
||||
description = "Fluence backend SDK for developing backend applications for the Fluence network"
|
||||
documentation = "https://docs.rs/fluence/"
|
||||
repository = "https://github.com/fluencelabs/rust-sdk"
|
||||
@ -9,7 +9,6 @@ readme = "Readme.md"
|
||||
keywords = ["fluence", "sdk", "webassembly"]
|
||||
categories = ["api-bindings", "wasm"]
|
||||
license = "Apache-2.0"
|
||||
maintenance = { status = "actively-developed" }
|
||||
|
||||
[package.metadata.docs.rs] # https://docs.rs/about
|
||||
all-features = true
|
||||
@ -18,8 +17,8 @@ all-features = true
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence-sdk-macro = { path = "crates/macro", version = "=0.1.11" }
|
||||
fluence-sdk-main = { path = "crates/main", version = "=0.1.11" }
|
||||
fluence-sdk-macro = { path = "crates/macro", version = "=0.2.0" }
|
||||
fluence-sdk-main = { path = "crates/main", version = "=0.2.0" }
|
||||
|
||||
[features]
|
||||
# Print some internal logs by log_utf8_string
|
||||
@ -27,7 +26,9 @@ print_logs = ["fluence-sdk-main/print_logs"]
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"crates/greeting",
|
||||
"crates/main",
|
||||
"crates/macro",
|
||||
"crates/greeting"
|
||||
"crates/wit-support",
|
||||
"crates/wit"
|
||||
]
|
||||
|
@ -5,4 +5,4 @@ authors = ["vms <michail.vms@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
fluence = { path = "../../", version = "=0.1.11" }
|
||||
fluence = { path = "../../", version = "=0.2.0" }
|
||||
|
@ -1,13 +1,12 @@
|
||||
use fluence::fce;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
fn main() {}
|
||||
|
||||
#[fce]
|
||||
pub fn greeting(arg: String, arg2: String, arg3: i32) -> i64 {
|
||||
let res = format!("Hi {} {}", arg, arg2);
|
||||
ipfs(res, arg2);
|
||||
ipfs1(arg);
|
||||
arg3 as _
|
||||
}
|
||||
|
||||
@ -15,4 +14,5 @@ pub fn greeting(arg: String, arg2: String, arg3: i32) -> i64 {
|
||||
#[link(wasm_import_module = "ipfs_node.wasm")]
|
||||
extern "C" {
|
||||
pub fn ipfs(cmd: String, aa: String) -> String;
|
||||
pub fn ipfs1(cmd: String) -> String;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fluence-sdk-macro"
|
||||
version = "0.1.11" # remember to update html_root_url
|
||||
version = "0.2.0" # remember to update html_root_url
|
||||
edition = "2018"
|
||||
description = "Definition of `#[invoke_handler]` attribute"
|
||||
documentation = "https://docs.rs/fluence/fluence-sdk-macro"
|
||||
@ -9,7 +9,6 @@ authors = ["Fluence Labs"]
|
||||
keywords = ["fluence", "sdk", "webassembly", "procedural_macros"]
|
||||
categories = ["api-bindings", "wasm"]
|
||||
license = "Apache-2.0"
|
||||
maintenance = { status = "actively-developed" }
|
||||
|
||||
[package.metadata.docs.rs] # https://docs.rs/about
|
||||
all-features = true
|
||||
@ -18,11 +17,4 @@ all-features = true
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = { version = '1.0.33', features = ['full'] }
|
||||
quote = "1.0.7"
|
||||
proc-macro2 = "1.0.18"
|
||||
serde = { version = "1.0.110", features = ["derive"] }
|
||||
serde_json = "1.0.56"
|
||||
uuid = { version = "0.8.1", features = ["v4"] }
|
||||
|
||||
fluence-sdk-main = { path = "../main", version = "=0.1.11" }
|
||||
wit-support = { path = "../wit-support" }
|
||||
|
@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/fluence-sdk-macro/0.1.11")]
|
||||
#![doc(html_root_url = "https://docs.rs/fluence-sdk-macro/0.2.0")]
|
||||
#![deny(
|
||||
// dead_code,
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
unused_imports,
|
||||
unused_mut,
|
||||
@ -26,14 +26,7 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![recursion_limit = "1024"]
|
||||
|
||||
mod fce_ast_types;
|
||||
mod parsed_type;
|
||||
mod macro_impl;
|
||||
mod parse_macro_input;
|
||||
mod token_stream_generator;
|
||||
mod wasm_type;
|
||||
|
||||
use macro_impl::fce_impl;
|
||||
use wit_support::fce as fce_impl;
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fluence-sdk-main"
|
||||
version = "0.1.11" # remember to update html_root_url
|
||||
version = "0.2.0" # remember to update html_root_url
|
||||
edition = "2018"
|
||||
description = "Rust SDK for writing applications for Fluence"
|
||||
documentation = "https://docs.rs/fluence/fluence-sdk-macro"
|
||||
@ -9,7 +9,6 @@ authors = ["Fluence Labs"]
|
||||
keywords = ["fluence", "sdk", "webassembly"]
|
||||
categories = ["api-bindings", "wasm"]
|
||||
license = "Apache-2.0"
|
||||
maintenance = { status = "actively-developed" }
|
||||
|
||||
[package.metadata.docs.rs] # https://docs.rs/about
|
||||
all-features = true
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
#![allow(clippy::needless_doctest_main)]
|
||||
#![doc(html_root_url = "https://docs.rs/fluence-sdk-main/0.1.11")]
|
||||
#![doc(html_root_url = "https://docs.rs/fluence-sdk-main/0.2.0")]
|
||||
#![deny(
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
|
22
crates/wit-support/Cargo.toml
Normal file
22
crates/wit-support/Cargo.toml
Normal file
@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "wit-support"
|
||||
version = "0.2.0" # remember to update html_root_url
|
||||
edition = "2018"
|
||||
description = "Webassembly interface-types generator"
|
||||
documentation = "https://docs.rs/fluence/fluence-sdk-macro"
|
||||
repository = "https://github.com/fluencelabs/rust-sdk/crates/macro"
|
||||
authors = ["Fluence Labs"]
|
||||
keywords = ["fluence", "sdk", "webassembly", "wit", "interface-types"]
|
||||
categories = ["api-bindings", "wasm"]
|
||||
license = "Apache-2.0"
|
||||
|
||||
[package.metadata.docs.rs] # https://docs.rs/about
|
||||
all-features = true
|
||||
|
||||
[dependencies]
|
||||
syn = { version = '1.0.33', features = ['full'] }
|
||||
quote = "1.0.7"
|
||||
proc-macro2 = "1.0.18"
|
||||
serde = { version = "1.0.110", features = ["derive"] }
|
||||
serde_json = "1.0.56"
|
||||
uuid = { version = "0.8.1", features = ["v4"] }
|
@ -20,45 +20,45 @@ use serde::Serialize;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub(crate) struct AstFunctionSignature {
|
||||
pub(crate) name: String,
|
||||
pub(crate) input_types: Vec<ParsedType>,
|
||||
pub struct AstFunctionSignature {
|
||||
pub name: String,
|
||||
pub input_types: Vec<ParsedType>,
|
||||
// fce supports only one return value now,
|
||||
// waiting for adding multi-value support in Wasmer.
|
||||
pub(crate) output_type: ParsedType,
|
||||
pub output_type: ParsedType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub(crate) struct AstRecordItem {
|
||||
pub(crate) fields: Vec<ParsedType>,
|
||||
pub struct AstRecordItem {
|
||||
pub fields: Vec<ParsedType>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub(crate) struct AstExternFnItem {
|
||||
pub(crate) link_name: Option<String>,
|
||||
pub struct AstExternFnItem {
|
||||
pub link_name: Option<String>,
|
||||
// only imports are possible here
|
||||
pub(crate) signature: AstFunctionSignature,
|
||||
pub signature: AstFunctionSignature,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub(crate) struct AstExternModItem {
|
||||
pub(crate) namespace: String,
|
||||
pub struct AstExternModItem {
|
||||
pub namespace: String,
|
||||
|
||||
// only imports are possible here
|
||||
pub(crate) imports: Vec<AstExternFnItem>,
|
||||
pub imports: Vec<AstExternFnItem>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub(crate) struct AstFunctionItem {
|
||||
pub(crate) signature: AstFunctionSignature,
|
||||
pub struct AstFunctionItem {
|
||||
pub signature: AstFunctionSignature,
|
||||
|
||||
// Option is needed only for skipping serialization/deserialization of syn::ItemFn
|
||||
#[serde(skip)]
|
||||
pub(crate) original: Option<syn::ItemFn>,
|
||||
pub original: Option<syn::ItemFn>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub(crate) enum FCEAst {
|
||||
pub enum FCEAst {
|
||||
Function(AstFunctionItem),
|
||||
ExternMod(AstExternModItem),
|
||||
Record(AstRecordItem),
|
@ -20,10 +20,8 @@ use crate::token_stream_generator::TokenStreamGenerator;
|
||||
use proc_macro2::TokenStream;
|
||||
use syn::Result;
|
||||
|
||||
pub(super) fn fce_impl(tokens: TokenStream) -> Result<TokenStream> {
|
||||
pub fn fce(tokens: TokenStream) -> Result<TokenStream> {
|
||||
let item = syn::parse2::<syn::Item>(tokens)?;
|
||||
let fce_ast_item = item.parse_macro_input()?;
|
||||
let tokens = fce_ast_item.generate_token_stream()?;
|
||||
|
||||
Ok(tokens)
|
||||
fce_ast_item.generate_token_stream()
|
||||
}
|
39
crates/wit-support/src/lib.rs
Normal file
39
crates/wit-support/src/lib.rs
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/wit-support/0.2.0")]
|
||||
#![deny(
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
unused_imports,
|
||||
unused_mut,
|
||||
unused_unsafe,
|
||||
unreachable_patterns
|
||||
)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![recursion_limit = "1024"]
|
||||
|
||||
mod fce_ast_types;
|
||||
mod fce_macro_impl;
|
||||
mod parsed_type;
|
||||
mod parse_macro_input;
|
||||
mod token_stream_generator;
|
||||
mod wasm_type;
|
||||
|
||||
pub use fce_ast_types::*;
|
||||
pub use fce_macro_impl::fce;
|
||||
pub use parsed_type::ParsedType;
|
||||
pub use token_stream_generator::GENERATED_SECTION_NAME;
|
@ -26,7 +26,7 @@ use syn::parse::Error;
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub(crate) enum ParsedType {
|
||||
pub enum ParsedType {
|
||||
Empty,
|
||||
I8,
|
||||
I16,
|
@ -23,8 +23,8 @@ use crate::fce_ast_types::FCEAst;
|
||||
use proc_macro2::TokenStream;
|
||||
|
||||
const GENERATED_FUNCS_PREFIX: &str = "__fce_generated_func_";
|
||||
const GENERATED_SECTION_NAME: &str = "fce_generated_section";
|
||||
const GENERATED_SECTION_PREFIX: &str = "fce_generated_static_global_";
|
||||
pub const GENERATED_SECTION_NAME: &str = "__fce_generated_section";
|
||||
const GENERATED_SECTION_PREFIX: &str = "__fce_generated_static_global_";
|
||||
|
||||
pub(crate) trait TokenStreamGenerator {
|
||||
fn generate_token_stream(self) -> syn::Result<TokenStream>;
|
@ -96,7 +96,7 @@ impl TokenStreamGenerator for fce_ast_types::AstFunctionItem {
|
||||
#epilog
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
// #[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = #section_name]
|
@ -51,7 +51,7 @@ impl TokenStreamGenerator for fce_ast_types::AstExternModItem {
|
||||
|
||||
#wrapper_functions
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
// #[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = #section_name]
|
||||
@ -114,10 +114,6 @@ fn generate_wrapper_functions(extern_item: &fce_ast_types::AstExternModItem) ->
|
||||
for import in &extern_item.imports {
|
||||
let visibility = syn::Ident::new("pub", proc_macro2::Span::call_site());
|
||||
let func_name = syn::Ident::new(&import.signature.name, proc_macro2::Span::call_site());
|
||||
let return_type = import
|
||||
.signature
|
||||
.output_type
|
||||
.generate_fn_sig_return_expression();
|
||||
let arg_types: Vec<proc_macro2::TokenStream> = import
|
||||
.signature
|
||||
.input_types
|
10
crates/wit/Cargo.toml
Normal file
10
crates/wit/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "wit"
|
||||
version = "0.1.0"
|
||||
authors = ["Fluence Labs"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
walrus = "0.17.0"
|
||||
wit-support = { path = "../wit-support" }
|
||||
wasmer-wit = { package = "wasmer-interface-types", git = "http://github.com/fluencelabs/interface-types", branch = "master", features = ["serde"] }
|
6
crates/wit/src/lib.rs
Normal file
6
crates/wit/src/lib.rs
Normal file
@ -0,0 +1,6 @@
|
||||
mod wit_generator;
|
||||
mod wasm_ast_extractor;
|
||||
|
||||
pub use wit_support::FCEAst;
|
||||
|
||||
pub fn generate_export(path: std::path::PathBuf) {}
|
19
crates/wit/src/wasm_ast_extractor.rs
Normal file
19
crates/wit/src/wasm_ast_extractor.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use walrus::{IdsToIndices, ModuleConfig};
|
||||
|
||||
struct WasmAst {
|
||||
exports: Vec<wit_support::AstFunctionItem>,
|
||||
imports: Vec<wit_support::AstExternModItem>,
|
||||
records: Vec<wit_support::AstRecordItem>,
|
||||
}
|
||||
|
||||
pub(crate) fn wasm_ast_extractor(wasm_path: std::path::PathBuf) -> Result<WasmAst, std::io::Error> {
|
||||
let module = ModuleConfig::new().parse_file(wasm_path)?;
|
||||
|
||||
let sections = module
|
||||
.customs
|
||||
.iter()
|
||||
.filter(|(_, section)| section.name().starts_with(wit_support::GENERATED_SECTION_NAME))
|
||||
.map(|section|)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
}
|
36
crates/wit/src/wit_generator.rs
Normal file
36
crates/wit/src/wit_generator.rs
Normal file
@ -0,0 +1,36 @@
|
||||
mod fn_wit_generator;
|
||||
mod foreign_mod_wit_generator;
|
||||
mod record_wit_generator;
|
||||
mod utils;
|
||||
|
||||
use super::FCEAst;
|
||||
|
||||
use wasmer_wit::types::InterfaceType as IType;
|
||||
use wasmer_wit::ast::Interfaces;
|
||||
use wasmer_wit::interpreter::Instruction;
|
||||
|
||||
trait WITGenerator {
|
||||
fn generate_wit<'a>(&'a self, interfaces: &mut Interfaces<'a>);
|
||||
}
|
||||
|
||||
trait FnInstructionGenerator {
|
||||
fn generate_instructions_for_input_type(&self, arg_id: u32) -> Vec<Instruction>;
|
||||
|
||||
fn generate_instructions_for_output_type(&self) -> Vec<Instruction>;
|
||||
}
|
||||
|
||||
trait ForeignModInstructionGenerator {
|
||||
fn generate_instructions_for_input_type(&self, arg_id: u32) -> Vec<Instruction>;
|
||||
|
||||
fn generate_instructions_for_output_type(&self) -> Vec<Instruction>;
|
||||
}
|
||||
|
||||
impl WITGenerator for FCEAst {
|
||||
fn generate_wit<'a>(&'a self, interfaces: &mut Interfaces<'a>) {
|
||||
match self {
|
||||
FCEAst::Function(func) => func.generate_wit(interfaces),
|
||||
FCEAst::ExternMod(extern_mod) => extern_mod.generate_wit(interfaces),
|
||||
FCEAst::Record(record) => record.generate_wit(interfaces),
|
||||
}
|
||||
}
|
||||
}
|
136
crates/wit/src/wit_generator/fn_wit_generator.rs
Normal file
136
crates/wit/src/wit_generator/fn_wit_generator.rs
Normal file
@ -0,0 +1,136 @@
|
||||
use super::WITGenerator;
|
||||
use super::Interfaces;
|
||||
use super::utils::ptype_to_itype;
|
||||
use super::FnInstructionGenerator;
|
||||
|
||||
use wit_support::AstFunctionItem;
|
||||
use wit_support::ParsedType;
|
||||
use wasmer_wit::interpreter::Instruction;
|
||||
|
||||
impl WITGenerator for AstFunctionItem {
|
||||
fn generate_wit<'a>(&'a self, interfaces: &mut Interfaces<'a>) {
|
||||
use wasmer_wit::ast::Type;
|
||||
use wasmer_wit::ast::Adapter;
|
||||
|
||||
let inputs = self
|
||||
.signature
|
||||
.input_types
|
||||
.iter()
|
||||
.map(ptype_to_itype)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let outputs = vec![ptype_to_itype(&self.signature.output_type)];
|
||||
interfaces.types.push(Type::Function {
|
||||
inputs: inputs.clone(),
|
||||
outputs: outputs.clone(),
|
||||
});
|
||||
|
||||
// TODO: replace with Wasm types
|
||||
interfaces.types.push(Type::Function { inputs, outputs });
|
||||
|
||||
let adapter_idx = (interfaces.types.len() - 2) as u32;
|
||||
let export_idx = (interfaces.types.len() - 1) as u32;
|
||||
|
||||
interfaces.exports.push(wasmer_wit::ast::Export {
|
||||
name: &self.signature.name,
|
||||
function_type: export_idx,
|
||||
});
|
||||
|
||||
let mut instructions: Vec<Instruction> = self
|
||||
.signature
|
||||
.input_types
|
||||
.iter()
|
||||
.rev()
|
||||
.enumerate()
|
||||
.map(|(id, input_type)| input_type.generate_instructions_for_input_type(id as _))
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
instructions.push(Instruction::CallCore {
|
||||
function_index: export_idx,
|
||||
});
|
||||
|
||||
instructions.extend(
|
||||
self.signature
|
||||
.output_type
|
||||
.generate_instructions_for_output_type(),
|
||||
);
|
||||
|
||||
let adapter = Adapter {
|
||||
function_type: adapter_idx,
|
||||
instructions,
|
||||
};
|
||||
|
||||
interfaces.adapters.push(adapter);
|
||||
|
||||
let implementation = wasmer_wit::ast::Implementation {
|
||||
core_function_type: export_idx,
|
||||
adapter_function_type: adapter_idx,
|
||||
};
|
||||
interfaces.implementations.push(implementation);
|
||||
}
|
||||
}
|
||||
|
||||
impl FnInstructionGenerator for ParsedType {
|
||||
fn generate_instructions_for_input_type(&self, index: u32) -> Vec<Instruction> {
|
||||
match self {
|
||||
ParsedType::I8 => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS8],
|
||||
ParsedType::I16 => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS16],
|
||||
ParsedType::I32 => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::I64 => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::U8 => vec![Instruction::ArgumentGet { index }, Instruction::I32FromU8],
|
||||
ParsedType::U16 => vec![Instruction::ArgumentGet { index }, Instruction::I32FromU16],
|
||||
ParsedType::U32 => vec![Instruction::ArgumentGet { index }, Instruction::I32FromU32],
|
||||
ParsedType::U64 => vec![Instruction::ArgumentGet { index }, Instruction::I64FromU64],
|
||||
ParsedType::F32 => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::F64 => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::Utf8String => vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::StringSize,
|
||||
Instruction::CallCore { function_index: 0 },
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::StringLowerMemory,
|
||||
],
|
||||
ParsedType::ByteVector => vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::StringSize,
|
||||
Instruction::CallCore { function_index: 0 },
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::StringLowerMemory,
|
||||
],
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_instructions_for_output_type(&self) -> Vec<Instruction> {
|
||||
match self {
|
||||
ParsedType::I8 => vec![Instruction::S8FromI32],
|
||||
ParsedType::I16 => vec![Instruction::S16FromI32],
|
||||
ParsedType::I32 => vec![],
|
||||
ParsedType::I64 => vec![],
|
||||
ParsedType::U8 => vec![Instruction::U8FromI32],
|
||||
ParsedType::U16 => vec![Instruction::U16FromI32],
|
||||
ParsedType::U32 => vec![Instruction::U32FromI32],
|
||||
ParsedType::U64 => vec![Instruction::U64FromI64],
|
||||
ParsedType::F32 => vec![],
|
||||
ParsedType::F64 => vec![],
|
||||
ParsedType::Utf8String => vec![
|
||||
Instruction::CallCore { function_index: 3 },
|
||||
Instruction::CallCore { function_index: 2 },
|
||||
Instruction::StringLiftMemory,
|
||||
Instruction::CallCore { function_index: 3 },
|
||||
Instruction::CallCore { function_index: 2 },
|
||||
Instruction::CallCore { function_index: 1 },
|
||||
],
|
||||
ParsedType::ByteVector => vec![
|
||||
Instruction::CallCore { function_index: 3 },
|
||||
Instruction::CallCore { function_index: 2 },
|
||||
Instruction::StringLiftMemory,
|
||||
Instruction::CallCore { function_index: 3 },
|
||||
Instruction::CallCore { function_index: 2 },
|
||||
Instruction::CallCore { function_index: 1 },
|
||||
],
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
146
crates/wit/src/wit_generator/foreign_mod_wit_generator.rs
Normal file
146
crates/wit/src/wit_generator/foreign_mod_wit_generator.rs
Normal file
@ -0,0 +1,146 @@
|
||||
use super::WITGenerator;
|
||||
use super::Interfaces;
|
||||
use super::utils::ptype_to_itype;
|
||||
use super::ForeignModInstructionGenerator;
|
||||
|
||||
use wit_support::AstExternModItem;
|
||||
use wit_support::AstExternFnItem;
|
||||
use wit_support::ParsedType;
|
||||
use wasmer_wit::interpreter::Instruction;
|
||||
|
||||
impl WITGenerator for AstExternModItem {
|
||||
fn generate_wit<'a>(&'a self, interfaces: &mut Interfaces<'a>) {
|
||||
for import in &self.imports {
|
||||
generate_wit_for_import(import, &self.namespace, interfaces);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_wit_for_import<'a>(
|
||||
import: &'a AstExternFnItem,
|
||||
namespace: &'a String,
|
||||
interfaces: &mut Interfaces<'a>,
|
||||
) {
|
||||
use wasmer_wit::ast::Type;
|
||||
use wasmer_wit::ast::Adapter;
|
||||
|
||||
let inputs = import
|
||||
.signature
|
||||
.input_types
|
||||
.iter()
|
||||
.map(ptype_to_itype)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let outputs = vec![ptype_to_itype(&import.signature.output_type)];
|
||||
interfaces.types.push(Type::Function {
|
||||
inputs: inputs.clone(),
|
||||
outputs: outputs.clone(),
|
||||
});
|
||||
|
||||
// TODO: replace with Wasm types
|
||||
interfaces.types.push(Type::Function { inputs, outputs });
|
||||
|
||||
let adapter_idx = (interfaces.types.len() - 2) as u32;
|
||||
let import_idx = (interfaces.types.len() - 1) as u32;
|
||||
|
||||
interfaces.imports.push(wasmer_wit::ast::Import {
|
||||
namespace: &namespace,
|
||||
name: &import.signature.name,
|
||||
function_type: import_idx,
|
||||
});
|
||||
|
||||
let mut instructions: Vec<Instruction> = import
|
||||
.signature
|
||||
.input_types
|
||||
.iter()
|
||||
.rev()
|
||||
.enumerate()
|
||||
.map(|(id, input_type)| input_type.generate_instructions_for_input_type(id as _))
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
instructions.push(Instruction::CallCore {
|
||||
function_index: import_idx,
|
||||
});
|
||||
|
||||
instructions.extend(
|
||||
import
|
||||
.signature
|
||||
.output_type
|
||||
.generate_instructions_for_output_type(),
|
||||
);
|
||||
|
||||
let adapter = Adapter {
|
||||
function_type: adapter_idx,
|
||||
instructions,
|
||||
};
|
||||
interfaces.adapters.push(adapter);
|
||||
|
||||
let implementation = wasmer_wit::ast::Implementation {
|
||||
core_function_type: import_idx,
|
||||
adapter_function_type: adapter_idx,
|
||||
};
|
||||
interfaces.implementations.push(implementation);
|
||||
}
|
||||
|
||||
impl ForeignModInstructionGenerator for ParsedType {
|
||||
fn generate_instructions_for_input_type(&self, index: u32) -> Vec<Instruction> {
|
||||
match self {
|
||||
ParsedType::I8 => vec![Instruction::ArgumentGet { index }, Instruction::S8FromI32],
|
||||
ParsedType::I16 => vec![Instruction::ArgumentGet { index }, Instruction::S16FromI32],
|
||||
ParsedType::I32 => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::I64 => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::U8 => vec![Instruction::ArgumentGet { index }, Instruction::U8FromI32],
|
||||
ParsedType::U16 => vec![Instruction::ArgumentGet { index }, Instruction::U16FromI32],
|
||||
ParsedType::U32 => vec![Instruction::ArgumentGet { index }, Instruction::U32FromI32],
|
||||
ParsedType::U64 => vec![Instruction::ArgumentGet { index }, Instruction::U64FromI64],
|
||||
ParsedType::F32 => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::F64 => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::Utf8String => vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::ArgumentGet { index: index + 1 },
|
||||
Instruction::StringLiftMemory,
|
||||
],
|
||||
ParsedType::ByteVector => vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::ArgumentGet { index: index + 1 },
|
||||
Instruction::StringLiftMemory,
|
||||
],
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_instructions_for_output_type(&self) -> Vec<Instruction> {
|
||||
match self {
|
||||
ParsedType::I8 => vec![Instruction::I32FromS8],
|
||||
ParsedType::I16 => vec![Instruction::I32FromS16],
|
||||
ParsedType::I32 => vec![],
|
||||
ParsedType::I64 => vec![],
|
||||
ParsedType::U8 => vec![Instruction::I32FromU8],
|
||||
ParsedType::U16 => vec![Instruction::I32FromU16],
|
||||
ParsedType::U32 => vec![Instruction::I32FromU32],
|
||||
ParsedType::U64 => vec![Instruction::I64FromU64],
|
||||
ParsedType::F32 => vec![],
|
||||
ParsedType::F64 => vec![],
|
||||
ParsedType::Utf8String => vec![
|
||||
Instruction::Dup,
|
||||
Instruction::StringSize,
|
||||
Instruction::CallCore { function_index: 0 },
|
||||
Instruction::Swap2,
|
||||
Instruction::StringLowerMemory,
|
||||
Instruction::CallCore { function_index: 5 },
|
||||
Instruction::CallCore { function_index: 6 },
|
||||
],
|
||||
ParsedType::ByteVector => vec![
|
||||
Instruction::Dup,
|
||||
Instruction::StringSize,
|
||||
Instruction::CallCore { function_index: 0 },
|
||||
Instruction::Swap2,
|
||||
Instruction::StringLowerMemory,
|
||||
Instruction::CallCore { function_index: 5 },
|
||||
Instruction::CallCore { function_index: 6 },
|
||||
],
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
10
crates/wit/src/wit_generator/record_wit_generator.rs
Normal file
10
crates/wit/src/wit_generator/record_wit_generator.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use super::WITGenerator;
|
||||
use super::Interfaces;
|
||||
|
||||
use wit_support::AstRecordItem;
|
||||
|
||||
impl WITGenerator for AstRecordItem {
|
||||
fn generate_wit<'a>(&'a self, _interfaces: &mut Interfaces<'a>) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
22
crates/wit/src/wit_generator/utils.rs
Normal file
22
crates/wit/src/wit_generator/utils.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use super::IType;
|
||||
use wit_support::ParsedType;
|
||||
|
||||
pub(crate) fn ptype_to_itype(pty: &ParsedType) -> IType {
|
||||
match pty {
|
||||
ParsedType::I8 => IType::S8,
|
||||
ParsedType::I16 => IType::S16,
|
||||
ParsedType::I32 => IType::S32,
|
||||
ParsedType::I64 => IType::S64,
|
||||
ParsedType::U8 => IType::U8,
|
||||
ParsedType::U16 => IType::U16,
|
||||
ParsedType::U32 => IType::U32,
|
||||
ParsedType::U64 => IType::U64,
|
||||
ParsedType::F32 => IType::F32,
|
||||
ParsedType::F64 => IType::F64,
|
||||
ParsedType::Boolean => IType::I32,
|
||||
ParsedType::Utf8String => IType::String,
|
||||
ParsedType::ByteVector => IType::String,
|
||||
ParsedType::Empty => panic!("this shouldn't happen"),
|
||||
ParsedType::Record(_) => unimplemented!(),
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@
|
||||
//! By default this crate turns on export-allocator feature of the `main` crate, to disable it
|
||||
//! please import this crate with `default-features = false`.
|
||||
//!
|
||||
#![doc(html_root_url = "https://docs.rs/fluence/0.1.11")]
|
||||
#![doc(html_root_url = "https://docs.rs/fluence/0.2.0")]
|
||||
#![deny(
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
@ -42,3 +42,4 @@ pub use fluence_sdk_main::get_result_ptr;
|
||||
pub use fluence_sdk_main::get_result_size;
|
||||
pub use fluence_sdk_main::set_result_ptr;
|
||||
pub use fluence_sdk_main::set_result_size;
|
||||
pub use fluence_sdk_macro
|
||||
|
Loading…
Reference in New Issue
Block a user