mirror of
https://github.com/fluencelabs/marine.git
synced 2025-06-25 20:51:35 +00:00
split fce_wit_interfaces
This commit is contained in:
17
crates/wit_parser/Cargo.toml
Normal file
17
crates/wit_parser/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "wit_parser"
|
||||
version = "0.1.0"
|
||||
authors = ["Fluence Labs"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "wit_parser"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
walrus = "0.17.0"
|
||||
wasmer-core = { package = "wasmer-runtime-core", version = "0.17.0"}
|
||||
wasmer-wit = { package = "wasmer-interface-types", git = "https://github.com/fluencelabs/interface-types", branch = "master" }
|
||||
fce_wit_interfaces = { path = "../fce_wit_interfaces" }
|
||||
|
||||
anyhow = "1.0.31"
|
33
crates/wit_parser/src/custom.rs
Normal file
33
crates/wit_parser/src/custom.rs
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use std::borrow::Cow;
|
||||
use walrus::{CustomSection, IdsToIndices};
|
||||
|
||||
pub const WIT_SECTION_NAME: &str = "interface-types";
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(super) struct WITCustom(pub Vec<u8>);
|
||||
|
||||
impl CustomSection for WITCustom {
|
||||
fn name(&self) -> &str {
|
||||
WIT_SECTION_NAME
|
||||
}
|
||||
|
||||
fn data(&self, _ids_to_indices: &IdsToIndices) -> Cow<'_, [u8]> {
|
||||
Cow::Borrowed(&self.0)
|
||||
}
|
||||
}
|
53
crates/wit_parser/src/deleter.rs
Normal file
53
crates/wit_parser/src/deleter.rs
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use super::errors::WITParserError;
|
||||
use super::custom::WIT_SECTION_NAME;
|
||||
|
||||
use walrus::ModuleConfig;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn delete_wit_section(
|
||||
in_wasm_path: PathBuf,
|
||||
out_wasm_path: PathBuf,
|
||||
) -> Result<(), WITParserError> {
|
||||
let mut module = ModuleConfig::new()
|
||||
.parse_file(&in_wasm_path)
|
||||
.map_err(WITParserError::CorruptedWasmFile)?;
|
||||
|
||||
let wit_section_ids = module
|
||||
.customs
|
||||
.iter()
|
||||
.filter_map(|(id, section)| {
|
||||
if section.name() == WIT_SECTION_NAME {
|
||||
Some(id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for id in wit_section_ids {
|
||||
module.customs.delete(id);
|
||||
}
|
||||
|
||||
module
|
||||
.emit_wasm_file(&out_wasm_path)
|
||||
.map_err(WITParserError::WasmEmitError)?;
|
||||
|
||||
Ok(())
|
||||
}
|
50
crates/wit_parser/src/embedder.rs
Normal file
50
crates/wit_parser/src/embedder.rs
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use super::custom::WITCustom;
|
||||
use super::errors::WITParserError;
|
||||
|
||||
use walrus::ModuleConfig;
|
||||
use wasmer_wit::{
|
||||
decoders::wat::{parse, Buffer},
|
||||
encoders::binary::ToBytes,
|
||||
};
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn embed_text_wit(
|
||||
in_wasm_path: PathBuf,
|
||||
out_wasm_path: PathBuf,
|
||||
wit: &str,
|
||||
) -> Result<(), WITParserError> {
|
||||
let mut module = ModuleConfig::new()
|
||||
.parse_file(&in_wasm_path)
|
||||
.map_err(WITParserError::CorruptedWasmFile)?;
|
||||
|
||||
let buffer = Buffer::new(wit)?;
|
||||
let ast = parse(&buffer)?;
|
||||
|
||||
let mut bytes = vec![];
|
||||
ast.to_bytes(&mut bytes)?;
|
||||
|
||||
let custom = WITCustom(bytes);
|
||||
module.customs.add(custom);
|
||||
module
|
||||
.emit_wasm_file(&out_wasm_path)
|
||||
.map_err(WITParserError::WasmEmitError)?;
|
||||
|
||||
Ok(())
|
||||
}
|
87
crates/wit_parser/src/errors.rs
Normal file
87
crates/wit_parser/src/errors.rs
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use wasmer_wit::decoders::wat::Error as WATError;
|
||||
use std::io::Error as StdIOError;
|
||||
use std::error::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum WITParserError {
|
||||
/// WIT section is absent.
|
||||
NoWITSection,
|
||||
|
||||
/// Multiple WIT sections.
|
||||
MultipleWITSections,
|
||||
|
||||
/// WIT section remainder isn't empty.
|
||||
WITRemainderNotEmpty,
|
||||
|
||||
/// An error occurred while parsing WIT section.
|
||||
CorruptedWITSection,
|
||||
|
||||
/// An error occurred while parsing file in Wat format.
|
||||
CorruptedWATFile(WATError),
|
||||
|
||||
/// An error occurred while parsing Wasm file
|
||||
CorruptedWasmFile(anyhow::Error),
|
||||
|
||||
/// An error occurred while manipulating with converting ast to bytes.
|
||||
AstToBytesError(StdIOError),
|
||||
|
||||
// Wasm emittig file error.
|
||||
WasmEmitError(anyhow::Error),
|
||||
}
|
||||
|
||||
impl Error for WITParserError {}
|
||||
|
||||
impl std::fmt::Display for WITParserError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
match self {
|
||||
WITParserError::NoWITSection => write!(f, "Loaded module doesn't contain WIT section"),
|
||||
WITParserError::MultipleWITSections => write!(
|
||||
f,
|
||||
"Loaded module contains multiple WIT sections that is unsupported now"
|
||||
),
|
||||
WITParserError::WITRemainderNotEmpty => write!(
|
||||
f,
|
||||
"WIT section remainder isn't empty - WIT section possibly corrupted"
|
||||
),
|
||||
WITParserError::CorruptedWITSection => write!(f, "WIT section is corrupted"),
|
||||
WITParserError::CorruptedWATFile(err) => {
|
||||
write!(f, "an error occurred while parsing wat file: {}", err)
|
||||
}
|
||||
WITParserError::CorruptedWasmFile(err) => {
|
||||
write!(f, "Failed to parse the Wasm module: {}", err)
|
||||
}
|
||||
WITParserError::AstToBytesError(err) => {
|
||||
write!(f, "Wasm AST converting to bytes failed with: {}", err)
|
||||
}
|
||||
WITParserError::WasmEmitError(err) => write!(f, "Failed to emit Wasm file: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WATError> for WITParserError {
|
||||
fn from(err: WATError) -> Self {
|
||||
WITParserError::CorruptedWATFile(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StdIOError> for WITParserError {
|
||||
fn from(err: StdIOError) -> Self {
|
||||
WITParserError::AstToBytesError(err)
|
||||
}
|
||||
}
|
96
crates/wit_parser/src/extractor.rs
Normal file
96
crates/wit_parser/src/extractor.rs
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use super::custom::WIT_SECTION_NAME;
|
||||
use super::errors::WITParserError;
|
||||
|
||||
use fce_wit_interfaces::FCEWITInterfaces;
|
||||
use walrus::{IdsToIndices, ModuleConfig};
|
||||
use wasmer_wit::ast::Interfaces;
|
||||
use wasmer_core::Module as WasmerModule;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Extracts WIT section of provided Wasm binary and converts it to a string.
|
||||
pub fn extract_text_wit(wasm_file_path: PathBuf) -> Result<String, WITParserError> {
|
||||
let wit_section_bytes = extract_wit_section_bytes(wasm_file_path)?;
|
||||
extract_wit_with_fn(
|
||||
&wit_section_bytes,
|
||||
|wit: Interfaces<'_>| -> Result<String, WITParserError> { Ok((&wit).to_string()) },
|
||||
)
|
||||
}
|
||||
|
||||
/// Extracts WIT section of provided Wasm binary and converts it to a FCEWITInterfaces.
|
||||
pub fn extract_fce_wit(
|
||||
wasmer_module: &WasmerModule,
|
||||
) -> Result<FCEWITInterfaces<'_>, WITParserError> {
|
||||
let wit_sections = wasmer_module
|
||||
.custom_sections(WIT_SECTION_NAME)
|
||||
.ok_or_else(|| WITParserError::NoWITSection)?;
|
||||
|
||||
if wit_sections.len() > 1 {
|
||||
return Err(WITParserError::MultipleWITSections);
|
||||
}
|
||||
|
||||
extract_wit_with_fn(
|
||||
&wit_sections[0],
|
||||
|wit: Interfaces<'_>| -> Result<FCEWITInterfaces<'_>, WITParserError> {
|
||||
Ok(FCEWITInterfaces::new(wit))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn extract_wit_with_fn<'a, F, FResultType: 'a>(
|
||||
wit_section_bytes: &'a [u8],
|
||||
func: F,
|
||||
) -> Result<FResultType, WITParserError>
|
||||
where
|
||||
F: FnOnce(Interfaces<'a>) -> Result<FResultType, WITParserError>,
|
||||
{
|
||||
let raw_wit = match wasmer_wit::decoders::binary::parse::<()>(&wit_section_bytes) {
|
||||
Ok((remainder, wit)) if remainder.is_empty() => wit,
|
||||
Ok(_) => {
|
||||
return Err(WITParserError::WITRemainderNotEmpty);
|
||||
}
|
||||
Err(_) => {
|
||||
return Err(WITParserError::CorruptedWITSection);
|
||||
}
|
||||
};
|
||||
|
||||
func(raw_wit)
|
||||
}
|
||||
|
||||
fn extract_wit_section_bytes(wasm_file_path: PathBuf) -> Result<Vec<u8>, WITParserError> {
|
||||
let module = ModuleConfig::new()
|
||||
.parse_file(wasm_file_path)
|
||||
.map_err(WITParserError::CorruptedWasmFile)?;
|
||||
|
||||
let sections = module
|
||||
.customs
|
||||
.iter()
|
||||
.filter(|(_, section)| section.name() == WIT_SECTION_NAME)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if sections.is_empty() {
|
||||
return Err(WITParserError::NoWITSection);
|
||||
}
|
||||
if sections.len() > 1 {
|
||||
return Err(WITParserError::MultipleWITSections);
|
||||
}
|
||||
|
||||
let default_ids = IdsToIndices::default();
|
||||
Ok(sections[0].1.data(&default_ids).into_owned())
|
||||
}
|
38
crates/wit_parser/src/lib.rs
Normal file
38
crates/wit_parser/src/lib.rs
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![deny(
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
unused_imports,
|
||||
unused_mut,
|
||||
unused_variables,
|
||||
unused_unsafe,
|
||||
unreachable_patterns
|
||||
)]
|
||||
|
||||
mod custom;
|
||||
mod deleter;
|
||||
mod embedder;
|
||||
mod errors;
|
||||
mod extractor;
|
||||
|
||||
pub use errors::WITParserError;
|
||||
|
||||
pub use embedder::embed_text_wit;
|
||||
pub use deleter::delete_wit_section;
|
||||
pub use extractor::extract_fce_wit;
|
||||
pub use extractor::extract_text_wit;
|
Reference in New Issue
Block a user