add a --target option to wasm2obj
This commit is contained in:
@@ -28,5 +28,6 @@ serde = "1.0.75"
|
|||||||
serde_derive = "1.0.75"
|
serde_derive = "1.0.75"
|
||||||
tempdir = "*"
|
tempdir = "*"
|
||||||
faerie = "0.5.0"
|
faerie = "0.5.0"
|
||||||
|
target-lexicon = { version = "0.0.3", default-features = false }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
|
|||||||
@@ -40,8 +40,10 @@ extern crate wasmtime_obj;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
extern crate faerie;
|
extern crate faerie;
|
||||||
|
extern crate target_lexicon;
|
||||||
|
|
||||||
use cranelift_codegen::settings;
|
use cranelift_codegen::isa;
|
||||||
|
use cranelift_codegen::settings::{self, Configurable};
|
||||||
use docopt::Docopt;
|
use docopt::Docopt;
|
||||||
use faerie::Artifact;
|
use faerie::Artifact;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
@@ -52,6 +54,8 @@ use std::io::prelude::*;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process;
|
use std::process;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use target_lexicon::{OperatingSystem, Triple};
|
||||||
use wasmtime_environ::{compile_module, Module, ModuleEnvironment};
|
use wasmtime_environ::{compile_module, Module, ModuleEnvironment};
|
||||||
use wasmtime_obj::emit_module;
|
use wasmtime_obj::emit_module;
|
||||||
|
|
||||||
@@ -62,12 +66,13 @@ The translation is dependent on the environment chosen.
|
|||||||
The default is a dummy environment that produces placeholder values.
|
The default is a dummy environment that produces placeholder values.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
wasm2obj <file> -o <output>
|
wasm2obj [--target TARGET] <file> -o <output>
|
||||||
wasm2obj --help | --version
|
wasm2obj --help | --version
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-v, --verbose displays the module and translated functions
|
-v, --verbose displays the module and translated functions
|
||||||
-h, --help print this help message
|
-h, --help print this help message
|
||||||
|
--target <TARGET> build for the target triple; default is the host machine
|
||||||
--version print the Cranelift version
|
--version print the Cranelift version
|
||||||
";
|
";
|
||||||
|
|
||||||
@@ -75,6 +80,7 @@ Options:
|
|||||||
struct Args {
|
struct Args {
|
||||||
arg_file: String,
|
arg_file: String,
|
||||||
arg_output: String,
|
arg_output: String,
|
||||||
|
arg_target: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_wasm_file(path: PathBuf) -> Result<Vec<u8>, io::Error> {
|
fn read_wasm_file(path: PathBuf) -> Result<Vec<u8>, io::Error> {
|
||||||
@@ -93,7 +99,7 @@ fn main() {
|
|||||||
}).unwrap_or_else(|e| e.exit());
|
}).unwrap_or_else(|e| e.exit());
|
||||||
|
|
||||||
let path = Path::new(&args.arg_file);
|
let path = Path::new(&args.arg_file);
|
||||||
match handle_module(path.to_path_buf(), &args.arg_output) {
|
match handle_module(path.to_path_buf(), &args.arg_target, &args.arg_output) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(message) => {
|
Err(message) => {
|
||||||
println!(" error: {}", message);
|
println!(" error: {}", message);
|
||||||
@@ -102,7 +108,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_module(path: PathBuf, output: &str) -> Result<(), String> {
|
fn handle_module(path: PathBuf, target: &Option<String>, output: &str) -> Result<(), String> {
|
||||||
let data = match read_wasm_file(path) {
|
let data = match read_wasm_file(path) {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -110,10 +116,31 @@ fn handle_module(path: PathBuf, output: &str) -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: Make the target a parameter.
|
let (flag_builder, isa_builder) = match *target {
|
||||||
let (flag_builder, isa_builder) = cranelift_native::builders().unwrap_or_else(|_| {
|
Some(ref target) => {
|
||||||
panic!("host machine is not a supported target");
|
let target = Triple::from_str(&target).map_err(|_| "could not parse --target")?;
|
||||||
});
|
let mut flag_builder = settings::builder();
|
||||||
|
match target.operating_system {
|
||||||
|
OperatingSystem::Windows => {
|
||||||
|
flag_builder.set("call_conv", "windows_fastcall").unwrap();
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
flag_builder.set("call_conv", "system_v").unwrap();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let isa_builder = isa::lookup(target).map_err(|err| match err {
|
||||||
|
isa::LookupError::SupportDisabled => {
|
||||||
|
"support for architecture disabled at compile time"
|
||||||
|
}
|
||||||
|
isa::LookupError::Unsupported => "unsupported architecture",
|
||||||
|
})?;
|
||||||
|
(flag_builder, isa_builder)
|
||||||
|
}
|
||||||
|
None => cranelift_native::builders().unwrap_or_else(|_| {
|
||||||
|
panic!("host machine is not a supported target");
|
||||||
|
}),
|
||||||
|
};
|
||||||
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
|
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
|
||||||
|
|
||||||
let mut obj = Artifact::new(isa.triple().clone(), String::from(output));
|
let mut obj = Artifact::new(isa.triple().clone(), String::from(output));
|
||||||
|
|||||||
Reference in New Issue
Block a user