From be0451accb93a6b6c1dea1c2b43012182afd1ddb Mon Sep 17 00:00:00 2001 From: vms Date: Tue, 7 Jul 2020 23:10:45 +0300 Subject: [PATCH] refactor wit generation --- crates/wit-support/src/fce_ast_types.rs | 1 + .../wit-support/src/token_stream_generator.rs | 2 +- .../token_stream_generator/fn_generator.rs | 9 +- .../foreign_mod_generator.rs | 6 +- crates/wit/Cargo.toml | 3 + crates/wit/src/lib.rs | 107 +++++++++++++++++- crates/wit/src/wasm_ast_extractor.rs | 27 +++-- crates/wit/src/wit_generator.rs | 2 +- .../foreign_mod_wit_generator.rs | 4 +- src/lib.rs | 1 - 10 files changed, 141 insertions(+), 21 deletions(-) diff --git a/crates/wit-support/src/fce_ast_types.rs b/crates/wit-support/src/fce_ast_types.rs index 769eec0..06a4de8 100644 --- a/crates/wit-support/src/fce_ast_types.rs +++ b/crates/wit-support/src/fce_ast_types.rs @@ -58,6 +58,7 @@ pub struct AstFunctionItem { } #[derive(Clone, Serialize, Deserialize)] +#[serde(tag = "ast_type")] pub enum FCEAst { Function(AstFunctionItem), ExternMod(AstExternModItem), diff --git a/crates/wit-support/src/token_stream_generator.rs b/crates/wit-support/src/token_stream_generator.rs index 462fd6e..345a55b 100644 --- a/crates/wit-support/src/token_stream_generator.rs +++ b/crates/wit-support/src/token_stream_generator.rs @@ -23,7 +23,7 @@ use crate::fce_ast_types::FCEAst; use proc_macro2::TokenStream; const GENERATED_FUNCS_PREFIX: &str = "__fce_generated_func_"; -pub const GENERATED_SECTION_NAME: &str = "__fce_generated_section"; +pub const GENERATED_SECTION_NAME: &str = "__fce_generated_section__"; const GENERATED_SECTION_PREFIX: &str = "__fce_generated_static_global_"; pub(crate) trait TokenStreamGenerator { diff --git a/crates/wit-support/src/token_stream_generator/fn_generator.rs b/crates/wit-support/src/token_stream_generator/fn_generator.rs index 8be6282..d085281 100644 --- a/crates/wit-support/src/token_stream_generator/fn_generator.rs +++ b/crates/wit-support/src/token_stream_generator/fn_generator.rs @@ -27,7 +27,9 @@ use crate::wasm_type::WasmType; impl TokenStreamGenerator for fce_ast_types::AstFunctionItem { fn generate_token_stream(self) -> syn::Result { - let data = serde_json::to_vec(&self).unwrap(); + // TODO: change serialization protocol + let fce_type = fce_ast_types::FCEAst::Function(self.clone()); + let data = serde_json::to_vec(&fce_type).unwrap(); let data_size = data.len(); let data = syn::LitByteStr::new(&data, proc_macro2::Span::call_site()); @@ -36,10 +38,11 @@ impl TokenStreamGenerator for fce_ast_types::AstFunctionItem { let func_name = syn::parse_str::(&(GENERATED_FUNCS_PREFIX.to_string() + &signature.name))?; let original_func_ident = syn::parse_str::(&signature.name)?; - let export_func_name = signature.name; //let func_name = syn::parse_str::(&(GENERATED_FUNCS_PREFIX.to_string() + &self.name))?; - let section_name = GENERATED_SECTION_NAME; + let section_name = GENERATED_SECTION_NAME.to_string() + &signature.name.replace("-", "_"); + let export_func_name = signature.name; + //let section_prefix = syn::parse_str::(GENERATED_SECTION_PREFIX)?; let global_static_name = syn::parse_str::( &(GENERATED_SECTION_PREFIX.to_string() + &export_func_name), diff --git a/crates/wit-support/src/token_stream_generator/foreign_mod_generator.rs b/crates/wit-support/src/token_stream_generator/foreign_mod_generator.rs index 47d09c3..678c890 100644 --- a/crates/wit-support/src/token_stream_generator/foreign_mod_generator.rs +++ b/crates/wit-support/src/token_stream_generator/foreign_mod_generator.rs @@ -27,7 +27,9 @@ use crate::parsed_type::ForeignModeGlueCodeGenerator; impl TokenStreamGenerator for fce_ast_types::AstExternModItem { fn generate_token_stream(self) -> syn::Result { - let data = serde_json::to_vec(&self).unwrap(); + // TODO: change serialization protocol + let fce_type = fce_ast_types::FCEAst::ExternMod(self.clone()); + let data = serde_json::to_vec(&fce_type).unwrap(); let data_size = data.len(); let data = syn::LitByteStr::new(&data, proc_macro2::Span::call_site()); @@ -36,7 +38,7 @@ impl TokenStreamGenerator for fce_ast_types::AstExternModItem { proc_macro2::Span::call_site(), ); - let section_name = GENERATED_SECTION_NAME; + let section_name = GENERATED_SECTION_NAME.to_string() + &self.namespace.replace(".", "_"); let wasm_import_module_name = &self.namespace; let generated_imports = generate_extern_section_items(&self); diff --git a/crates/wit/Cargo.toml b/crates/wit/Cargo.toml index d8f1035..1113c32 100644 --- a/crates/wit/Cargo.toml +++ b/crates/wit/Cargo.toml @@ -5,6 +5,9 @@ authors = ["Fluence Labs"] edition = "2018" [dependencies] +wit_parser = { path = "/Users/mike/dev/work/fluence/wasm/fce/crates/wit_parser" } 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"] } +serde = { version = "1.0.110", features = ["derive"] } +serde_json = "1.0.56" diff --git a/crates/wit/src/lib.rs b/crates/wit/src/lib.rs index 3cdb12b..7c2cd79 100644 --- a/crates/wit/src/lib.rs +++ b/crates/wit/src/lib.rs @@ -1,6 +1,109 @@ mod wit_generator; mod wasm_ast_extractor; -pub use wit_support::FCEAst; +use wit_generator::WITGenerator; -pub fn generate_export(path: std::path::PathBuf) {} +pub use wit_support::FCEAst; +use wasmer_wit::ast::Interfaces; + +pub fn embed_wit(path: std::path::PathBuf) { + let ast_set = wasm_ast_extractor::wasm_ast_extractor(path.clone()).unwrap(); + let interfaces = generate_interfaces(&ast_set); + wit_parser::embed_wit(path.clone(), path.clone(), &interfaces).unwrap(); +} + +fn generate_interfaces(ast_set: &[FCEAst]) -> Interfaces<'_> { + let mut interfaces = Interfaces::default(); + generate_default_api(&mut interfaces); + + for ast in ast_set { + ast.generate_wit(&mut interfaces); + } + + interfaces +} + +fn generate_default_api(interfaces: &mut Interfaces) { + use wasmer_wit::ast::Type; + use wasmer_wit::ast::Export; + use wasmer_wit::types::InterfaceType as IType; + + let allocate_inputs = vec![IType::I32]; + let allocate_outputs = vec![IType::I32]; + let allocate_func_type = Type::Function { + inputs: allocate_inputs, + outputs: allocate_outputs, + }; + + let deallocate_inputs = vec![IType::I32, IType::I32]; + let deallocate_outputs = vec![]; + let deallocate_func_type = Type::Function { + inputs: deallocate_inputs, + outputs: deallocate_outputs, + }; + + let get_result_inputs = vec![]; + let get_result_outputs = vec![IType::I32]; + let get_result_size_func_type = Type::Function { + inputs: get_result_inputs.clone(), + outputs: get_result_outputs.clone(), + }; + let get_result_ptr_func_type = Type::Function { + inputs: get_result_inputs, + outputs: get_result_outputs, + }; + + let set_result_inputs = vec![IType::I32]; + let set_result_outputs = vec![]; + let set_result_size_func_type = Type::Function { + inputs: set_result_inputs.clone(), + outputs: set_result_outputs.clone(), + }; + let set_result_ptr_func_type = Type::Function { + inputs: set_result_inputs, + outputs: set_result_outputs, + }; + + interfaces.types.push(allocate_func_type); + interfaces.types.push(deallocate_func_type); + interfaces.types.push(get_result_size_func_type); + interfaces.types.push(get_result_ptr_func_type); + interfaces.types.push(set_result_size_func_type); + interfaces.types.push(set_result_ptr_func_type); + + let allocate_export = Export { + name: "allocate", + function_type: 0, + }; + interfaces.exports.push(allocate_export); + + let deallocate_export = Export { + name: "deallocate", + function_type: 1, + }; + interfaces.exports.push(deallocate_export); + + let get_result_size_export = Export { + name: "get_result_size", + function_type: 2, + }; + interfaces.exports.push(get_result_size_export); + + let get_result_ptr_export = Export { + name: "get_result_ptr", + function_type: 3, + }; + interfaces.exports.push(get_result_ptr_export); + + let set_result_size_export = Export { + name: "set_result_size", + function_type: 4, + }; + interfaces.exports.push(set_result_size_export); + + let set_result_ptr_export = Export { + name: "set_result_ptr", + function_type: 5, + }; + interfaces.exports.push(set_result_ptr_export); +} diff --git a/crates/wit/src/wasm_ast_extractor.rs b/crates/wit/src/wasm_ast_extractor.rs index 118168f..b4c495c 100644 --- a/crates/wit/src/wasm_ast_extractor.rs +++ b/crates/wit/src/wasm_ast_extractor.rs @@ -1,19 +1,28 @@ -use walrus::{IdsToIndices, ModuleConfig}; +use walrus::ModuleConfig; +#[derive(Default, Clone)] struct WasmAst { exports: Vec, imports: Vec, records: Vec, } -pub(crate) fn wasm_ast_extractor(wasm_path: std::path::PathBuf) -> Result { - let module = ModuleConfig::new().parse_file(wasm_path)?; +pub(crate) fn wasm_ast_extractor( + wasm_path: std::path::PathBuf, +) -> Result, std::io::Error> { + let module = ModuleConfig::new().parse_file(wasm_path).unwrap(); + let mut decoded_ast = Vec::new(); - let sections = module - .customs - .iter() - .filter(|(_, section)| section.name().starts_with(wit_support::GENERATED_SECTION_NAME)) - .map(|section|) - .collect::>(); + for custom_module in module.customs.iter().filter(|(_, section)| { + section + .name() + .starts_with(wit_support::GENERATED_SECTION_NAME) + }) { + let default_ids = walrus::IdsToIndices::default(); + let raw_data = custom_module.1.data(&default_ids); + let decoded_json: wit_support::FCEAst = serde_json::from_slice(&raw_data).unwrap(); + decoded_ast.push(decoded_json); + } + Ok(decoded_ast) } diff --git a/crates/wit/src/wit_generator.rs b/crates/wit/src/wit_generator.rs index f9782c2..c2a559c 100644 --- a/crates/wit/src/wit_generator.rs +++ b/crates/wit/src/wit_generator.rs @@ -9,7 +9,7 @@ use wasmer_wit::types::InterfaceType as IType; use wasmer_wit::ast::Interfaces; use wasmer_wit::interpreter::Instruction; -trait WITGenerator { +pub trait WITGenerator { fn generate_wit<'a>(&'a self, interfaces: &mut Interfaces<'a>); } diff --git a/crates/wit/src/wit_generator/foreign_mod_wit_generator.rs b/crates/wit/src/wit_generator/foreign_mod_wit_generator.rs index 69981ca..9121009 100644 --- a/crates/wit/src/wit_generator/foreign_mod_wit_generator.rs +++ b/crates/wit/src/wit_generator/foreign_mod_wit_generator.rs @@ -128,8 +128,8 @@ impl ForeignModInstructionGenerator for ParsedType { Instruction::CallCore { function_index: 0 }, Instruction::Swap2, Instruction::StringLowerMemory, + Instruction::CallCore { function_index: 4 }, Instruction::CallCore { function_index: 5 }, - Instruction::CallCore { function_index: 6 }, ], ParsedType::ByteVector => vec![ Instruction::Dup, @@ -137,8 +137,8 @@ impl ForeignModInstructionGenerator for ParsedType { Instruction::CallCore { function_index: 0 }, Instruction::Swap2, Instruction::StringLowerMemory, + Instruction::CallCore { function_index: 4 }, Instruction::CallCore { function_index: 5 }, - Instruction::CallCore { function_index: 6 }, ], _ => unimplemented!(), } diff --git a/src/lib.rs b/src/lib.rs index aacfc99..31ea00b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,4 +42,3 @@ 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