mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-05-08 06:38:01 +00:00
70 lines
2.1 KiB
Rust
70 lines
2.1 KiB
Rust
//! Process for compiling a single compilation unit using Web Workers.
|
|
|
|
use std::ffi::{c_char, c_void, CStr, CString};
|
|
|
|
use super::Input;
|
|
use super::Output;
|
|
use super::Process;
|
|
|
|
use anyhow::Context;
|
|
use serde::Deserialize;
|
|
|
|
#[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 call(input: Input) -> anyhow::Result<Output> {
|
|
let input_json = serde_json::to_vec(&input).expect("Always valid");
|
|
let input_str = String::from_utf8(input_json).expect("Input shall be valid");
|
|
// Prepare the input string for the Emscripten function
|
|
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()
|
|
.with_context(|| "Failed to convert C string to Rust string")
|
|
.map(str::to_owned)
|
|
};
|
|
unsafe { libc::free(output_ptr as *mut c_void) };
|
|
let output_str = output_str?;
|
|
let response: Response = serde_json::from_str(&output_str)
|
|
.map_err(|error| anyhow::anyhow!("Worker output parsing error: {}", error,))?;
|
|
match response {
|
|
Response::Success(out) => {
|
|
let output: Output = revive_common::deserialize_from_slice(out.data.as_bytes())
|
|
.map_err(|error| {
|
|
anyhow::anyhow!("resolc.js subprocess output parsing error: {}", error,)
|
|
})?;
|
|
|
|
Ok(output)
|
|
}
|
|
Response::Error(err) => anyhow::bail!("Worker error: {}", err.message,),
|
|
}
|
|
}
|
|
}
|
|
|
|
extern "C" {
|
|
fn resolc_compile(input_ptr: *const c_char, input_len: usize) -> *const c_char;
|
|
}
|