split fce_wit_interfaces

This commit is contained in:
vms
2020-06-06 00:13:05 +03:00
parent 2bbbb9323d
commit bb2bbcf35e
21 changed files with 72 additions and 42 deletions

View 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"

View 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)
}
}

View 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(())
}

View 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(())
}

View 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)
}
}

View 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())
}

View 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;