use anyhow::Result;
use dprint_core::plugins::PluginInfo;
use super::create_identity_import_object;
use super::create_wasm_plugin_instance;
use super::instance::WasmHostState;
use super::load_instance::WasmModule;
use super::load_instance::WasmModuleCreator;
use super::load_instance::load_instance;
use super::load_instance::plugin_initializes_on_start;
use crate::plugins::CompilationResult;
pub fn compile(wasm_bytes: &[u8]) -> Result<CompilationResult> {
let wasm_module_creator = WasmModuleCreator::default();
let module = wasm_module_creator.create_from_wasm_bytes(wasm_bytes)?;
let bytes: Vec<u8> = match module.inner().serialize() {
Ok(bytes) => bytes,
Err(err) => anyhow::bail!("Error serializing wasm module: {:#}", err),
};
let plugin_info = match get_plugin_info(&module) {
Ok(plugin_info) => plugin_info,
Err(err) => {
let module = module.clone().with_initializes_on_start(true);
match module.has_initialize_export().then(|| get_plugin_info(&module)) {
Some(Ok(plugin_info)) if plugin_initializes_on_start(&plugin_info) => plugin_info,
_ => return Err(err),
}
}
};
Ok(CompilationResult { bytes, plugin_info })
}
fn get_plugin_info(module: &WasmModule) -> Result<PluginInfo> {
let linker = create_identity_import_object(module.version(), module.engine())?;
let mut store = module.new_store(WasmHostState::Empty);
let instance = load_instance(&mut store, module, linker)?;
create_wasm_plugin_instance(store, instance)?.plugin_info()
}