mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-14 21:31:05 +00:00
94ec34c4d5
Separate between compilation and linker phases to allow deploy time linking and back-porting era compiler changes to fix #91. Unlinked contract binaries (caused by missing libraries or missing factory dependencies in turn) are emitted as raw ELF object. Few drive by fixes: - #98 - A compiler panic on missing libraries definitions. - Fixes some incosistent type forwarding in JSON output (empty string vs. null object). - Remove the unused fallback for size optimization setting. - Remove the broken `--lvm-ir` mode. - CI workflow fixes. --------- Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com> Signed-off-by: xermicus <bigcyrill@hotmail.com> Signed-off-by: xermicus <cyrill@parity.io>
99 lines
3.1 KiB
Rust
99 lines
3.1 KiB
Rust
//! Process for compiling a single compilation unit using Web Workers.
|
|
|
|
use std::ffi::{c_char, c_void, CStr, CString};
|
|
|
|
use serde::de::DeserializeOwned;
|
|
use serde::Deserialize;
|
|
use serde::Serialize;
|
|
|
|
use revive_common::deserialize_from_slice;
|
|
use revive_solc_json_interface::standard_json::output::error::source_location::SourceLocation;
|
|
use revive_solc_json_interface::SolcStandardJsonOutputError;
|
|
|
|
use super::Input;
|
|
use super::Output;
|
|
use super::Process;
|
|
|
|
#[derive(Deserialize)]
|
|
struct Error {
|
|
message: String,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct Success {
|
|
data: String,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
#[serde(tag = "type", rename_all = "snake_case")]
|
|
enum Response {
|
|
Success(Success),
|
|
Error(Error),
|
|
}
|
|
|
|
pub struct WorkerProcess;
|
|
|
|
impl Process for WorkerProcess {
|
|
fn run(input: Input) -> anyhow::Result<()> {
|
|
let source_location = SourceLocation::new(input.contract.identifier.path.to_owned());
|
|
|
|
let result = input
|
|
.contract
|
|
.compile(
|
|
None,
|
|
input.optimizer_settings,
|
|
input.metadata_hash,
|
|
input.debug_config,
|
|
&input.llvm_arguments,
|
|
input.memory_config,
|
|
input.missing_libraries,
|
|
input.factory_dependencies,
|
|
input.identifier_paths,
|
|
)
|
|
.map(Output::new)
|
|
.map_err(|error| {
|
|
SolcStandardJsonOutputError::new_error(error, Some(source_location), None)
|
|
});
|
|
|
|
serde_json::to_writer(std::io::stdout(), &result)
|
|
.map_err(|error| anyhow::anyhow!("Stdout writing error: {error}"))?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn call<I, O>(_path: &str, input: I) -> Result<O, SolcStandardJsonOutputError>
|
|
where
|
|
I: Serialize,
|
|
O: DeserializeOwned,
|
|
{
|
|
let input_json = serde_json::to_vec(&input).expect("Always valid");
|
|
let input_str = String::from_utf8(input_json).expect("Input shall be valid");
|
|
let input_cstring = CString::new(input_str).expect("CString allocation failed");
|
|
|
|
// Call the Emscripten function
|
|
let output_ptr =
|
|
unsafe { resolc_compile(input_cstring.as_ptr(), input_cstring.as_bytes().len()) };
|
|
|
|
// Convert the output pointer back to a Rust string
|
|
let output_str = unsafe { CStr::from_ptr(output_ptr).to_str().map(str::to_owned) };
|
|
unsafe { libc::free(output_ptr as *mut c_void) };
|
|
|
|
let output_str = output_str.unwrap_or_else(|error| panic!("resolc.js output: {error:?}"));
|
|
let response = serde_json::from_str(&output_str)
|
|
.unwrap_or_else(|error| panic!("Worker output parsing error: {error}"));
|
|
match response {
|
|
Response::Success(out) => match deserialize_from_slice(out.data.as_bytes()) {
|
|
Ok(output) => output,
|
|
Err(error) => {
|
|
panic!("resolc.js subprocess output parsing error: {error}")
|
|
}
|
|
},
|
|
Response::Error(err) => panic!("Worker error: {}", err.message),
|
|
}
|
|
}
|
|
}
|
|
|
|
extern "C" {
|
|
fn resolc_compile(input_ptr: *const c_char, input_len: usize) -> *const c_char;
|
|
}
|