Fix make lint

This commit is contained in:
Felix Schütt
2022-12-23 14:03:02 +01:00
parent 75a7e68f9b
commit b873f0fe1a
8 changed files with 145 additions and 156 deletions

View File

@@ -326,7 +326,7 @@ fn test_run() {
if !config.wasmer_dir.is_empty() { if !config.wasmer_dir.is_empty() {
command.arg("-L"); command.arg("-L");
command.arg(&format!("{}/lib/", config.wasmer_dir)); command.arg(&format!("{}/lib/", config.wasmer_dir));
command.arg(&"-lwasmer".to_string()); command.arg("-lwasmer");
command.arg(&format!("-Wl,-rpath,{}/lib/", config.wasmer_dir)); command.arg(&format!("-Wl,-rpath,{}/lib/", config.wasmer_dir));
} }
command.arg("-o"); command.arg("-o");

View File

@@ -203,7 +203,7 @@ fn test_ok() {
let libwasmer_so_path = format!("{}/lib/libwasmer.so", config.wasmer_dir); let libwasmer_so_path = format!("{}/lib/libwasmer.so", config.wasmer_dir);
let exe_dir = format!("{manifest_dir}/../wasm-c-api/example"); let exe_dir = format!("{manifest_dir}/../wasm-c-api/example");
let path = std::env::var("PATH").unwrap_or_default(); let path = std::env::var("PATH").unwrap_or_default();
let newpath = format!("{};{path}", wasmer_dll_dir.to_string().replace('/', "\\")); let newpath = format!("{};{path}", wasmer_dll_dir.replace('/', "\\"));
if target.contains("msvc") { if target.contains("msvc") {
for test in CAPI_BASE_TESTS.iter() { for test in CAPI_BASE_TESTS.iter() {
@@ -347,7 +347,7 @@ fn test_ok() {
if !config.wasmer_dir.is_empty() { if !config.wasmer_dir.is_empty() {
command.arg("-L"); command.arg("-L");
command.arg(&format!("{}/lib/", config.wasmer_dir)); command.arg(&format!("{}/lib/", config.wasmer_dir));
command.arg(&"-lwasmer".to_string()); command.arg("-lwasmer");
command.arg(&format!("-Wl,-rpath,{}/lib/", config.wasmer_dir)); command.arg(&format!("-Wl,-rpath,{}/lib/", config.wasmer_dir));
} }
command.arg("-o"); command.arg("-o");

View File

@@ -5,71 +5,75 @@ use wasmer_types::ModuleInfo;
use wasmer_types::{Symbol, SymbolRegistry}; use wasmer_types::{Symbol, SymbolRegistry};
/// Helper functions to simplify the usage of the static artifact. /// Helper functions to simplify the usage of the static artifact.
const HELPER_FUNCTIONS: &str = r#" fn gen_helper_functions(atom_name: &str, module_name: &str) -> String {
wasm_byte_vec_t generate_serialized_data() { format!("
wasm_byte_vec_t generate_serialized_data_{atom_name}() {{
// We need to pass all the bytes as one big buffer so we have to do all this logic to memcpy // We need to pass all the bytes as one big buffer so we have to do all this logic to memcpy
// the various pieces together from the generated header file. // the various pieces together from the generated header file.
// //
// We should provide a `deseralize_vectored` function to avoid requiring this extra work. // We should provide a `deseralize_vectored` function to avoid requiring this extra work.
char* byte_ptr = (char*)&WASMER_METADATA[0]; char* byte_ptr = (char*)&{module_name}[0];
size_t num_function_pointers size_t num_function_pointers
= sizeof(function_pointers) / sizeof(void*); = sizeof(function_pointers_{atom_name}) / sizeof(void*);
size_t num_function_trampolines size_t num_function_trampolines
= sizeof(function_trampolines) / sizeof(void*); = sizeof(function_trampolines_{atom_name}) / sizeof(void*);
size_t num_dynamic_function_trampoline_pointers size_t num_dynamic_function_trampoline_pointers
= sizeof(dynamic_function_trampoline_pointers) / sizeof(void*); = sizeof(dynamic_function_trampoline_pointers_{atom_name}) / sizeof(void*);
size_t buffer_size = module_bytes_len size_t buffer_size = module_bytes_len_{atom_name}
+ sizeof(size_t) + sizeof(function_pointers) + sizeof(size_t) + sizeof(function_pointers_{atom_name})
+ sizeof(size_t) + sizeof(function_trampolines) + sizeof(size_t) + sizeof(function_trampolines_{atom_name})
+ sizeof(size_t) + sizeof(dynamic_function_trampoline_pointers); + sizeof(size_t) + sizeof(dynamic_function_trampoline_pointers_{atom_name});
char* memory_buffer = (char*) malloc(buffer_size); char* memory_buffer = (char*) malloc(buffer_size);
size_t current_offset = 0; size_t current_offset = 0;
memcpy(memory_buffer + current_offset, byte_ptr, module_bytes_len); memcpy(memory_buffer + current_offset, byte_ptr, module_bytes_len_{atom_name});
current_offset += module_bytes_len; current_offset += module_bytes_len_{atom_name};
memcpy(memory_buffer + current_offset, (void*)&num_function_pointers, sizeof(size_t)); memcpy(memory_buffer + current_offset, (void*)&num_function_pointers, sizeof(size_t));
current_offset += sizeof(size_t); current_offset += sizeof(size_t);
memcpy(memory_buffer + current_offset, (void*)&function_pointers[0], sizeof(function_pointers)); memcpy(memory_buffer + current_offset, (void*)&function_pointers_{atom_name}[0], sizeof(function_pointers_{atom_name}));
current_offset += sizeof(function_pointers); current_offset += sizeof(function_pointers_{atom_name});
memcpy(memory_buffer + current_offset, (void*)&num_function_trampolines, sizeof(size_t)); memcpy(memory_buffer + current_offset, (void*)&num_function_trampolines, sizeof(size_t));
current_offset += sizeof(size_t); current_offset += sizeof(size_t);
memcpy(memory_buffer + current_offset, (void*)&function_trampolines[0], sizeof(function_trampolines)); memcpy(memory_buffer + current_offset, (void*)&function_trampolines_{atom_name}[0], sizeof(function_trampolines_{atom_name}));
current_offset += sizeof(function_trampolines); current_offset += sizeof(function_trampolines_{atom_name});
memcpy(memory_buffer + current_offset, (void*)&num_dynamic_function_trampoline_pointers, sizeof(size_t)); memcpy(memory_buffer + current_offset, (void*)&num_dynamic_function_trampoline_pointers, sizeof(size_t));
current_offset += sizeof(size_t); current_offset += sizeof(size_t);
memcpy(memory_buffer + current_offset, (void*)&dynamic_function_trampoline_pointers[0], sizeof(dynamic_function_trampoline_pointers)); memcpy(memory_buffer + current_offset, (void*)&dynamic_function_trampoline_pointers_{atom_name}[0], sizeof(dynamic_function_trampoline_pointers_{atom_name}));
current_offset += sizeof(dynamic_function_trampoline_pointers); current_offset += sizeof(dynamic_function_trampoline_pointers_{atom_name});
wasm_byte_vec_t module_byte_vec = { wasm_byte_vec_t module_byte_vec = {{
.size = buffer_size, .size = buffer_size,
.data = memory_buffer, .data = memory_buffer,
}; }};
return module_byte_vec; return module_byte_vec;
} }}
wasm_module_t* wasmer_object_module_new(wasm_store_t* store, const char* wasm_name) { wasm_module_t* wasmer_object_module_new_{atom_name}(wasm_store_t* store, const char* wasm_name) {{
// wasm_name intentionally unused for now: will be used in the future. // wasm_name intentionally unused for now: will be used in the future.
wasm_byte_vec_t module_byte_vec = generate_serialized_data(); wasm_byte_vec_t module_byte_vec = generate_serialized_data_{atom_name}();
wasm_module_t* module = wasm_module_deserialize(store, &module_byte_vec); wasm_module_t* module = wasm_module_deserialize(store, &module_byte_vec);
free(module_byte_vec.data); free(module_byte_vec.data);
return module; return module;
}}
")
} }
"#;
/// Generate the header file that goes with the generated object file. /// Generate the header file that goes with the generated object file.
pub fn generate_header_file( pub fn generate_header_file(
atom_name: &str,
module_name: &str,
module_info: &ModuleInfo, module_info: &ModuleInfo,
symbol_registry: &dyn SymbolRegistry, symbol_registry: &dyn SymbolRegistry,
metadata_length: usize, metadata_length: usize,
@@ -83,7 +87,7 @@ pub fn generate_header_file(
value: "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n".to_string(), value: "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n".to_string(),
}, },
CStatement::Declaration { CStatement::Declaration {
name: "module_bytes_len".to_string(), name: format!("module_bytes_len_{atom_name}"),
is_extern: false, is_extern: false,
is_const: true, is_const: true,
ctype: CType::U32, ctype: CType::U32,
@@ -92,10 +96,7 @@ pub fn generate_header_file(
})), })),
}, },
CStatement::Declaration { CStatement::Declaration {
name: match module_info.name.as_deref() { name: module_name.to_string(),
Some(s) => format!("WASMER_METADATA_{}", s.to_uppercase()),
None => "WASMER_METADATA".to_string(),
},
is_extern: true, is_extern: true,
is_const: true, is_const: true,
ctype: CType::Array { ctype: CType::Array {
@@ -157,7 +158,7 @@ pub fn generate_header_file(
.collect::<Vec<_>>(); .collect::<Vec<_>>();
c_statements.push(CStatement::Declaration { c_statements.push(CStatement::Declaration {
name: "function_pointers".to_string(), name: format!("function_pointers_{atom_name}"),
is_extern: false, is_extern: false,
is_const: true, is_const: true,
ctype: CType::Array { ctype: CType::Array {
@@ -213,7 +214,7 @@ pub fn generate_header_file(
.collect::<Vec<_>>(); .collect::<Vec<_>>();
c_statements.push(CStatement::Declaration { c_statements.push(CStatement::Declaration {
name: "function_trampolines".to_string(), name: format!("function_trampolines_{atom_name}"),
is_extern: false, is_extern: false,
is_const: true, is_const: true,
ctype: CType::Array { ctype: CType::Array {
@@ -277,7 +278,7 @@ pub fn generate_header_file(
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
c_statements.push(CStatement::Declaration { c_statements.push(CStatement::Declaration {
name: "dynamic_function_trampoline_pointers".to_string(), name: format!("dynamic_function_trampoline_pointers_{atom_name}"),
is_extern: false, is_extern: false,
is_const: true, is_const: true,
ctype: CType::Array { ctype: CType::Array {
@@ -290,7 +291,7 @@ pub fn generate_header_file(
} }
c_statements.push(CStatement::LiteralConstant { c_statements.push(CStatement::LiteralConstant {
value: HELPER_FUNCTIONS.to_string(), value: gen_helper_functions(atom_name, module_name),
}); });
c_statements.push(CStatement::LiteralConstant { c_statements.push(CStatement::LiteralConstant {

View File

@@ -6,12 +6,11 @@ use anyhow::{Context, Result};
use clap::Parser; use clap::Parser;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::env; use std::env;
use std::fmt::Write as _;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use wasmer::*; use wasmer::*;
use wasmer_object::{emit_serialized, get_object_for_target}; use wasmer_object::{emit_serialized, get_object_for_target};
use wasmer_types::compilation::target;
use webc::{ParseOptions, WebCMmap}; use webc::{ParseOptions, WebCMmap};
/// The `prefixer` returns the a String to prefix each of the /// The `prefixer` returns the a String to prefix each of the
@@ -130,7 +129,7 @@ pub struct Volume {
impl CreateExe { impl CreateExe {
/// Runs logic for the `compile` subcommand /// Runs logic for the `compile` subcommand
pub fn execute(&self) -> Result<()> { pub fn execute(&self) -> Result<()> {
let target_triple = self.target_triple.clone().unwrap_or_else(|| Triple::host()); let target_triple = self.target_triple.clone().unwrap_or_else(Triple::host);
let mut cc = CrossCompile { let mut cc = CrossCompile {
library_path: self.cross_compile.library_path.clone(), library_path: self.cross_compile.library_path.clone(),
zig_binary_path: self.cross_compile.zig_binary_path.clone(), zig_binary_path: self.cross_compile.zig_binary_path.clone(),
@@ -146,7 +145,7 @@ impl CreateExe {
if input_path.is_dir() { if input_path.is_dir() {
// assumes that the input directory has been created with create-obj // assumes that the input directory has been created with create-obj
link_exe_from_dir(&input_path, output_path, &cross_compilation)?; link_exe_from_dir(&input_path, output_path, &cross_compilation, true)?;
} else if let Ok(pirita) = WebCMmap::parse(input_path.clone(), &ParseOptions::default()) { } else if let Ok(pirita) = WebCMmap::parse(input_path.clone(), &ParseOptions::default()) {
// pirita file // pirita file
let temp = tempdir::TempDir::new("pirita-compile")?; let temp = tempdir::TempDir::new("pirita-compile")?;
@@ -163,7 +162,12 @@ impl CreateExe {
&cross_compilation.target, &cross_compilation.target,
self.object_format.unwrap_or_default(), self.object_format.unwrap_or_default(),
)?; )?;
link_exe_from_dir(&tempdir, output_path, &cross_compilation)?; link_exe_from_dir(
&tempdir,
output_path,
&cross_compilation,
self.debug_dir.is_some(),
)?;
} else { } else {
// wasm file // wasm file
let temp = tempdir::TempDir::new("pirita-compile")?; let temp = tempdir::TempDir::new("pirita-compile")?;
@@ -180,7 +184,12 @@ impl CreateExe {
&self.cpu_features, &self.cpu_features,
self.object_format.unwrap_or_default(), self.object_format.unwrap_or_default(),
)?; )?;
link_exe_from_dir(&tempdir, output_path, &cross_compilation)?; link_exe_from_dir(
&tempdir,
output_path,
&cross_compilation,
self.debug_dir.is_some(),
)?;
} }
if self.target_triple.is_some() { if self.target_triple.is_some() {
@@ -213,7 +222,7 @@ pub(super) fn compile_pirita_into_directory(
.map_err(|e| anyhow::anyhow!("cannot create / dir in {}: {e}", target_dir.display()))?; .map_err(|e| anyhow::anyhow!("cannot create / dir in {}: {e}", target_dir.display()))?;
let target_dir = target_dir.canonicalize()?; let target_dir = target_dir.canonicalize()?;
let target = &utils::target_triple_to_target(&triple, cpu_features); let target = &utils::target_triple_to_target(triple, cpu_features);
std::fs::create_dir_all(target_dir.join("volumes")).map_err(|e| { std::fs::create_dir_all(target_dir.join("volumes")).map_err(|e| {
anyhow::anyhow!( anyhow::anyhow!(
@@ -225,7 +234,7 @@ pub(super) fn compile_pirita_into_directory(
let volume_bytes = pirita.get_volumes_as_fileblock(); let volume_bytes = pirita.get_volumes_as_fileblock();
let volume_name = "VOLUMES"; let volume_name = "VOLUMES";
let volume_path = target_dir.join("volumes").join("volume.o"); let volume_path = target_dir.join("volumes").join("volume.o");
write_volume_obj(&volume_bytes, &volume_name, &volume_path, &target)?; write_volume_obj(&volume_bytes, volume_name, &volume_path, target)?;
let volume_path = volume_path.canonicalize()?; let volume_path = volume_path.canonicalize()?;
let volume_path = pathdiff::diff_paths(&volume_path, &target_dir).unwrap(); let volume_path = pathdiff::diff_paths(&volume_path, &target_dir).unwrap();
@@ -237,8 +246,10 @@ pub(super) fn compile_pirita_into_directory(
let mut target_paths = Vec::new(); let mut target_paths = Vec::new();
for (atom_name, atom_bytes) in pirita.get_all_atoms() { for (atom_name, atom_bytes) in pirita.get_all_atoms() {
atoms_from_file.push((atom_name.clone(), atom_bytes.to_vec())); atoms_from_file.push((utils::normalize_atom_name(&atom_name), atom_bytes.to_vec()));
let atom_path = target_dir.join("atoms").join(format!("{atom_name}.o")); let atom_path = target_dir
.join("atoms")
.join(format!("{}.o", utils::normalize_atom_name(&atom_name)));
let header_path = match object_format { let header_path = match object_format {
ObjectFormat::Symbols => { ObjectFormat::Symbols => {
std::fs::create_dir_all(target_dir.join("include")).map_err(|e| { std::fs::create_dir_all(target_dir.join("include")).map_err(|e| {
@@ -248,15 +259,19 @@ pub(super) fn compile_pirita_into_directory(
) )
})?; })?;
Some( Some(target_dir.join("include").join(format!(
target_dir "static_defs_{}.h",
.join("include") utils::normalize_atom_name(&atom_name)
.join(format!("static_defs_{atom_name}.h")), )))
)
} }
ObjectFormat::Serialized => None, ObjectFormat::Serialized => None,
}; };
target_paths.push((atom_name, atom_path, header_path)); target_paths.push((
atom_name.clone(),
utils::normalize_atom_name(&atom_name),
atom_path,
header_path,
));
} }
conpile_atoms( conpile_atoms(
@@ -270,20 +285,21 @@ pub(super) fn compile_pirita_into_directory(
// target_dir // target_dir
let mut atoms = Vec::new(); let mut atoms = Vec::new();
for (atom_name, atom_path, opt_header_path) in target_paths { for (command_name, atom_name, a, opt_header_path) in target_paths {
if let Ok(atom_path) = atom_path.canonicalize() { let mut atom_path = a;
let header_path = opt_header_path.and_then(|p| p.canonicalize().ok()); let mut header_path = opt_header_path;
let atom_path = if let Ok(a) = atom_path.canonicalize() {
pathdiff::diff_paths(&atom_path, &target_dir).unwrap_or_else(|| atom_path.clone()); let opt_header_path = header_path.and_then(|p| p.canonicalize().ok());
let header_path = header_path.and_then(|h| pathdiff::diff_paths(&h, &target_dir)); atom_path = pathdiff::diff_paths(&a, &target_dir).unwrap_or_else(|| a.clone());
atoms.push(CommandEntrypoint { header_path = opt_header_path.and_then(|h| pathdiff::diff_paths(&h, &target_dir));
// TODO: improve, "--command pip" should be able to invoke atom "python" with args "-m pip"
command: atom_name.clone(),
atom: atom_name.clone(),
path: atom_path,
header: header_path,
});
} }
atoms.push(CommandEntrypoint {
// TODO: improve, "--command pip" should be able to invoke atom "python" with args "-m pip"
command: command_name,
atom: atom_name,
path: atom_path,
header: header_path,
});
} }
let entrypoint = Entrypoint { let entrypoint = Entrypoint {
@@ -324,6 +340,7 @@ fn conpile_atoms(
for (a, data) in atoms { for (a, data) in atoms {
let (store, _) = compiler.get_store_for_target(target.clone())?; let (store, _) = compiler.get_store_for_target(target.clone())?;
let atom_name = utils::normalize_atom_name(a); let atom_name = utils::normalize_atom_name(a);
let atom_name_uppercase = atom_name.to_uppercase();
let output_object_path = output_dir.join(format!("{atom_name}.o")); let output_object_path = output_dir.join(format!("{atom_name}.o"));
let module_name = format!( let module_name = format!(
"WASMER_MODULE_{}", "WASMER_MODULE_{}",
@@ -341,19 +358,20 @@ fn conpile_atoms(
let prefixer: Option<PrefixerFn> = Some(Box::new(move |_| { let prefixer: Option<PrefixerFn> = Some(Box::new(move |_| {
utils::normalize_atom_name(&atom_name_copy) utils::normalize_atom_name(&atom_name_copy)
})); }));
println!("generating object file {module_name}");
let (module_info, obj, metadata_length, symbol_registry) = let (module_info, obj, metadata_length, symbol_registry) =
Artifact::generate_object( Artifact::generate_object(
compiler, compiler,
&data, data,
&module_name, &module_name,
prefixer, prefixer,
&target, target,
tunables, tunables,
features, features,
)?; )?;
let header_file_src = crate::c_gen::staticlib_header::generate_header_file( let header_file_src = crate::c_gen::staticlib_header::generate_header_file(
&atom_name,
&format!("WASMER_MODULE_{atom_name_uppercase}"),
&module_info, &module_info,
&*symbol_registry, &*symbol_registry,
metadata_length, metadata_length,
@@ -370,8 +388,7 @@ fn conpile_atoms(
writer.flush()?; writer.flush()?;
} }
ObjectFormat::Serialized => { ObjectFormat::Serialized => {
let module = let module = Module::from_binary(&store, data).context("failed to compile Wasm")?;
Module::from_binary(&store, &data).context("failed to compile Wasm")?;
let bytes = module.serialize()?; let bytes = module.serialize()?;
let mut obj = get_object_for_target(target.triple())?; let mut obj = get_object_for_target(target.triple())?;
emit_serialized(&mut obj, &bytes, target.triple(), &module_name)?; emit_serialized(&mut obj, &bytes, target.triple(), &module_name)?;
@@ -468,7 +485,7 @@ pub(super) fn prepare_directory_from_single_wasm_file(
object_format: ObjectFormat, object_format: ObjectFormat,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let bytes = std::fs::read(wasm_file)?; let bytes = std::fs::read(wasm_file)?;
let target = &utils::target_triple_to_target(&triple, cpu_features); let target = &utils::target_triple_to_target(triple, cpu_features);
std::fs::create_dir_all(target_dir) std::fs::create_dir_all(target_dir)
.map_err(|e| anyhow::anyhow!("cannot create / dir in {}: {e}", target_dir.display()))?; .map_err(|e| anyhow::anyhow!("cannot create / dir in {}: {e}", target_dir.display()))?;
@@ -557,6 +574,7 @@ fn link_exe_from_dir(
directory: &Path, directory: &Path,
output_path: PathBuf, output_path: PathBuf,
cross_compilation: &CrossCompileSetup, cross_compilation: &CrossCompileSetup,
debug: bool,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let entrypoint_json = let entrypoint_json =
std::fs::read_to_string(directory.join("entrypoint.json")).map_err(|e| { std::fs::read_to_string(directory.join("entrypoint.json")).map_err(|e| {
@@ -609,10 +627,6 @@ fn link_exe_from_dir(
.filter_map(|v| directory.join(&v.obj_file).canonicalize().ok()), .filter_map(|v| directory.join(&v.obj_file).canonicalize().ok()),
); );
println!("linking volume objects: {:#?}", entrypoint.volumes);
println!("object_paths: {:#?}", object_paths);
println!("object_paths: {:#?}", entrypoint.atoms);
let zig_triple = utils::triple_to_zig_triple(&cross_compilation.target); let zig_triple = utils::triple_to_zig_triple(&cross_compilation.target);
let include_dirs = entrypoint let include_dirs = entrypoint
.atoms .atoms
@@ -715,8 +729,12 @@ fn link_exe_from_dir(
cmd.args(files_winsdk); cmd.args(files_winsdk);
} }
println!("{cmd:?}"); if debug {
let compilation = cmd.output().context("Could not execute `zig`")?; println!("{cmd:?}");
}
let compilation = cmd
.output()
.context(anyhow!("Could not execute `zig`: {cmd:?}"))?;
if !compilation.status.success() { if !compilation.status.success() {
return Err(anyhow::anyhow!(String::from_utf8_lossy( return Err(anyhow::anyhow!(String::from_utf8_lossy(
@@ -725,6 +743,8 @@ fn link_exe_from_dir(
.to_string())); .to_string()));
} }
// remove file if it exists - if not done, can lead to errors on copy
let _ = std::fs::remove_file(&output_path);
std::fs::copy(&out_path, &output_path).map_err(|e| { std::fs::copy(&out_path, &output_path).map_err(|e| {
anyhow::anyhow!( anyhow::anyhow!(
"could not copy from {} to {}: {e}", "could not copy from {} to {}: {e}",
@@ -744,21 +764,11 @@ fn link_c_compilation() -> Result<(), anyhow::Error> {
Ok(()) Ok(())
} }
#[allow(dead_code)]
fn generate_wasmer_main_c_static(entrypoint: &Entrypoint) -> Result<String, anyhow::Error> {
generate_wasmer_main_c_inner(entrypoint, true)
}
fn generate_wasmer_main_c(entrypoint: &Entrypoint) -> Result<String, anyhow::Error> {
generate_wasmer_main_c_inner(entrypoint, false)
}
/// Generate the wasmer_main.c that links all object files together /// Generate the wasmer_main.c that links all object files together
/// (depending on the object format / atoms number) /// (depending on the object format / atoms number)
fn generate_wasmer_main_c_inner( fn generate_wasmer_main_c(entrypoint: &Entrypoint) -> Result<String, anyhow::Error> {
entrypoint: &Entrypoint, use std::fmt::Write;
compile_static: bool,
) -> Result<String, anyhow::Error> {
const WASMER_MAIN_C_SOURCE: &str = include_str!("wasmer_create_exe_main.c"); const WASMER_MAIN_C_SOURCE: &str = include_str!("wasmer_create_exe_main.c");
const WASMER_STATIC_MAIN_C_SOURCE: &str = include_str!("wasmer_static_create_exe_main.c"); const WASMER_STATIC_MAIN_C_SOURCE: &str = include_str!("wasmer_static_create_exe_main.c");
@@ -767,6 +777,8 @@ fn generate_wasmer_main_c_inner(
Ok(WASMER_MAIN_C_SOURCE.replace("// WASI_DEFINES", "#define WASI")) Ok(WASMER_MAIN_C_SOURCE.replace("// WASI_DEFINES", "#define WASI"))
} }
ObjectFormat::Symbols => { ObjectFormat::Symbols => {
let compile_static = true;
// always with compile zig + static_defs.h
let atom_names = entrypoint let atom_names = entrypoint
.atoms .atoms
.iter() .iter()
@@ -776,30 +788,34 @@ fn generate_wasmer_main_c_inner(
let mut c_code_to_add = String::new(); let mut c_code_to_add = String::new();
let mut c_code_to_instantiate = String::new(); let mut c_code_to_instantiate = String::new();
let mut deallocate_module = String::new(); let mut deallocate_module = String::new();
let mut extra_headers = Vec::new();
for a in atom_names.iter() { for a in atom_names.iter() {
let atom_name = utils::normalize_atom_name(&a); let atom_name = utils::normalize_atom_name(a);
let atom_name_uppercase = atom_name.to_uppercase(); let atom_name_uppercase = atom_name.to_uppercase();
let module_name = format!("WASMER_MODULE_{atom_name_uppercase}"); let module_name = format!("WASMER_MODULE_{atom_name_uppercase}");
c_code_to_add.push_str(&format!( extra_headers.push(format!("#include \"static_defs_{atom_name}.h\""));
write!(
c_code_to_add,
" "
extern size_t {module_name}_LENGTH asm(\"{module_name}_LENGTH\"); extern size_t {module_name}_LENGTH asm(\"{module_name}_LENGTH\");
extern char {module_name}_DATA asm(\"{module_name}_DATA\"); extern char {module_name}_DATA asm(\"{module_name}_DATA\");
" "
)); )?;
if compile_static { if compile_static {
c_code_to_instantiate.push_str(&format!(" write!(c_code_to_instantiate, "
wasm_module_t *atom_{atom_name} = wasmer_object_module_new(store, \"{atom_name}\"); wasm_module_t *atom_{atom_name} = wasmer_object_module_new_{atom_name}(store, \"{atom_name}\");
if (!atom_{atom_name}) {{ if (!atom_{atom_name}) {{
fprintf(stderr, \"Failed to create module from atom \\\"{atom_name}\\\"\\n\"); fprintf(stderr, \"Failed to create module from atom \\\"{atom_name}\\\"\\n\");
print_wasmer_error(); print_wasmer_error();
return -1; return -1;
}} }}
")); ")?;
} else { } else {
c_code_to_instantiate.push_str(&format!(" write!(c_code_to_instantiate, "
wasm_byte_vec_t atom_{atom_name}_byte_vec = {{ wasm_byte_vec_t atom_{atom_name}_byte_vec = {{
.size = {module_name}_LENGTH, .size = {module_name}_LENGTH,
.data = &{module_name}_DATA, .data = &{module_name}_DATA,
@@ -810,13 +826,12 @@ fn generate_wasmer_main_c_inner(
print_wasmer_error(); print_wasmer_error();
return -1; return -1;
}} }}
")); ")?;
} }
deallocate_module.push_str(&format!("wasm_module_delete(atom_{atom_name});")); write!(deallocate_module, "wasm_module_delete(atom_{atom_name});")?;
} }
println!("entrypoint volumes: {:?}", entrypoint.volumes);
let volumes_str = entrypoint let volumes_str = entrypoint
.volumes .volumes
.iter() .iter()
@@ -848,36 +863,39 @@ fn generate_wasmer_main_c_inner(
) )
.replace("// DECLARE_MODULES", &c_code_to_add) .replace("// DECLARE_MODULES", &c_code_to_add)
.replace("// DECLARE_VOLUMES", &volumes_str) .replace("// DECLARE_VOLUMES", &volumes_str)
.replace("// EXTRA_HEADERS", &extra_headers.join("\r\n"))
.replace("wasm_module_delete(module);", &deallocate_module); .replace("wasm_module_delete(module);", &deallocate_module);
if atom_names.len() == 1 { if atom_names.len() == 1 {
let atom_to_run = &atom_names[0]; let atom_to_run = &atom_names[0];
c_code_to_instantiate.push_str(&format!("module = atom_{atom_to_run};")); write!(c_code_to_instantiate, "module = atom_{atom_to_run};")?;
} else { } else {
for a in atom_names.iter() { for a in atom_names.iter() {
c_code_to_instantiate.push_str(&format!( writeln!(
"if (strcmp(selected_atom, \"{a}\") == 0) {{ module = atom_{}; }}\n", c_code_to_instantiate,
"if (strcmp(selected_atom, \"{a}\") == 0) {{ module = atom_{}; }}",
utils::normalize_atom_name(a) utils::normalize_atom_name(a)
)); )?;
} }
} }
c_code_to_instantiate.push_str(&format!( write!(
c_code_to_instantiate,
" "
if (!module) {{ if (!module) {{
fprintf(stderr, \"No --command given, available commands are:\\n\"); fprintf(stderr, \"No --command given, available commands are:\\n\");
fprintf(stderr, \"\\n\"); fprintf(stderr, \"\\n\");
{commands} {commands}
print_wasmer_error(); fprintf(stderr, \"\\n\");
return -1; return -1;
}} }}
", ",
commands = atom_names commands = atom_names
.iter() .iter()
.map(|a| format!("fprintf(stderr, \"{a}\\n\");")) .map(|a| format!("fprintf(stderr, \" {a}\\n\");"))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join("\n") .join("\n")
)); )?;
Ok(return_str.replace("// INSTANTIATE_MODULES", &c_code_to_instantiate)) Ok(return_str.replace("// INSTANTIATE_MODULES", &c_code_to_instantiate))
} }
@@ -898,10 +916,7 @@ pub(super) mod utils {
target_triple: &Triple, target_triple: &Triple,
cpu_features: &[CpuFeature], cpu_features: &[CpuFeature],
) -> Target { ) -> Target {
let mut features = cpu_features let mut features = cpu_features.iter().fold(CpuFeature::set(), |a, b| a | *b);
.clone()
.into_iter()
.fold(CpuFeature::set(), |a, b| a | *b);
// Cranelift requires SSE2, so we have this "hack" for now to facilitate // Cranelift requires SSE2, so we have this "hack" for now to facilitate
// usage // usage
if target_triple.architecture == Architecture::X86_64 { if target_triple.architecture == Architecture::X86_64 {
@@ -947,7 +962,7 @@ pub(super) mod utils {
Some(v.canonicalize().unwrap_or(v)) Some(v.canonicalize().unwrap_or(v))
} else { } else {
if let Some(local_tarball) = cross_subc.tarball.as_ref() { if let Some(local_tarball) = cross_subc.tarball.as_ref() {
find_filename(local_tarball, &target) find_filename(local_tarball, target)
} else { } else {
// check if the tarball for the target already exists locally // check if the tarball for the target already exists locally
let local_tarball = std::fs::read_dir(get_libwasmer_cache_path()?)? let local_tarball = std::fs::read_dir(get_libwasmer_cache_path()?)?
@@ -960,15 +975,15 @@ pub(super) mod utils {
None None
} }
}) })
.filter_map(|p| filter_tarballs(&p, &target)) .filter_map(|p| filter_tarballs(&p, target))
.next(); .next();
if let Some(local_tarball) = local_tarball.as_ref() { if let Some(local_tarball) = local_tarball.as_ref() {
find_filename(local_tarball, &target) find_filename(local_tarball, target)
} else { } else {
let release = super::http_fetch::get_latest_release()?; let release = super::http_fetch::get_latest_release()?;
let tarball = super::http_fetch::download_release(release, target.clone())?; let tarball = super::http_fetch::download_release(release, target.clone())?;
find_filename(&tarball, &target) find_filename(&tarball, target)
} }
} }
.ok() .ok()
@@ -1054,7 +1069,7 @@ pub(super) mod utils {
.filter_map(|c| { .filter_map(|c| {
if char::is_alphabetic(c) { if char::is_alphabetic(c) {
Some(c) Some(c)
} else if c == '-' { } else if c == '-' || c == '_' {
Some('_') Some('_')
} else { } else {
None None

View File

@@ -2,18 +2,15 @@
//! Create a standalone native executable for a given Wasm file. //! Create a standalone native executable for a given Wasm file.
use super::ObjectFormat; use super::ObjectFormat;
use crate::{commands::PrefixerFn, store::CompilerOptions}; use crate::store::CompilerOptions;
use anyhow::{Context, Result}; use anyhow::Result;
use clap::Parser; use clap::Parser;
use std::env; use std::env;
use std::fs;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufWriter;
use std::path::PathBuf; use std::path::PathBuf;
use std::process::Command;
use wasmer::*; use wasmer::*;
use wasmer_object::{emit_serialized, get_object_for_target};
#[cfg(feature = "webc_runner")] #[cfg(feature = "webc_runner")]
use webc::{ParseOptions, WebCMmap}; use webc::{ParseOptions, WebCMmap};
@@ -61,7 +58,7 @@ pub struct CreateObj {
impl CreateObj { impl CreateObj {
/// Runs logic for the `create-obj` subcommand /// Runs logic for the `create-obj` subcommand
pub fn execute(&self) -> Result<()> { pub fn execute(&self) -> Result<()> {
let target_triple = self.target_triple.clone().unwrap_or_else(|| Triple::host()); let target_triple = self.target_triple.clone().unwrap_or_else(Triple::host);
let starting_cd = env::current_dir()?; let starting_cd = env::current_dir()?;
let input_path = starting_cd.join(&self.path); let input_path = starting_cd.join(&self.path);
let output_path = starting_cd.join(&self.output); let output_path = starting_cd.join(&self.output);

View File

@@ -1,25 +0,0 @@
#include "wasmer.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
extern size_t WASMER_MODULE_LENGTH asm("WASMER_MODULE_LENGTH");
extern char WASMER_MODULE_DATA asm("WASMER_MODULE_DATA");
wasm_module_t* wasmer_object_module_new(wasm_store_t* store, const char* wasm_name) {
wasm_byte_vec_t module_byte_vec = {
.size = WASMER_MODULE_LENGTH,
.data = (const char*)&WASMER_MODULE_DATA,
};
wasm_module_t* module = wasm_module_deserialize(store, &module_byte_vec);
return module;
}
#ifdef __cplusplus
}
#endif

View File

@@ -93,6 +93,7 @@ int main(int argc, char *argv[]) {
wasm_config_t *config = wasm_config_new(); wasm_config_t *config = wasm_config_new();
wasm_engine_t *engine = wasm_engine_new_with_config(config); wasm_engine_t *engine = wasm_engine_new_with_config(config);
wasm_store_t *store = wasm_store_new(engine); wasm_store_t *store = wasm_store_new(engine);
wasm_module_t *module = NULL;
const char* selected_atom = "main"; const char* selected_atom = "main";
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {

View File

@@ -189,7 +189,7 @@ fn create_exe_works_multi_command() -> anyhow::Result<()> {
.run() .run()
.context("Failed to create-exe wasm with Wasmer")?; .context("Failed to create-exe wasm with Wasmer")?;
let result = run_code( let _result = run_code(
&operating_dir, &operating_dir,
&executable_path, &executable_path,
&["--command".to_string(), "wabt".to_string()], &["--command".to_string(), "wabt".to_string()],