From 5f11f444823a92eb78f26321ee5b3bde79c04b2b Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Tue, 9 Oct 2018 14:36:53 -0400 Subject: [PATCH] add a --target option to wasm2obj --- Cargo.toml | 1 + src/wasm2obj.rs | 43 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ef5c09adea..6acd090d42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,5 +28,6 @@ serde = "1.0.75" serde_derive = "1.0.75" tempdir = "*" faerie = "0.5.0" +target-lexicon = { version = "0.0.3", default-features = false } [workspace] diff --git a/src/wasm2obj.rs b/src/wasm2obj.rs index feac42302f..1c419f0076 100644 --- a/src/wasm2obj.rs +++ b/src/wasm2obj.rs @@ -40,8 +40,10 @@ extern crate wasmtime_obj; #[macro_use] extern crate serde_derive; 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 faerie::Artifact; use std::error::Error; @@ -52,6 +54,8 @@ use std::io::prelude::*; use std::path::Path; use std::path::PathBuf; use std::process; +use std::str::FromStr; +use target_lexicon::{OperatingSystem, Triple}; use wasmtime_environ::{compile_module, Module, ModuleEnvironment}; 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. Usage: - wasm2obj -o + wasm2obj [--target TARGET] -o wasm2obj --help | --version Options: -v, --verbose displays the module and translated functions -h, --help print this help message + --target build for the target triple; default is the host machine --version print the Cranelift version "; @@ -75,6 +80,7 @@ Options: struct Args { arg_file: String, arg_output: String, + arg_target: Option, } fn read_wasm_file(path: PathBuf) -> Result, io::Error> { @@ -93,7 +99,7 @@ fn main() { }).unwrap_or_else(|e| e.exit()); 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(()) => {} Err(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, output: &str) -> Result<(), String> { let data = match read_wasm_file(path) { Ok(data) => data, 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) = cranelift_native::builders().unwrap_or_else(|_| { - panic!("host machine is not a supported target"); - }); + let (flag_builder, isa_builder) = match *target { + Some(ref 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 mut obj = Artifact::new(isa.triple().clone(), String::from(output));