diff --git a/cranelift/src/compile.rs b/cranelift/src/compile.rs index 2db5d21f85..f9f718685d 100644 --- a/cranelift/src/compile.rs +++ b/cranelift/src/compile.rs @@ -2,18 +2,12 @@ //! //! Reads IR files into Cretonne IL and compiles it. -use cton_reader::{parse_options, Location, parse_functions}; +use cton_reader::parse_functions; use std::path::PathBuf; use cretonne::Context; -use cretonne::settings::{self, FlagsOrIsa}; -use cretonne::isa::{self, TargetIsa}; +use cretonne::settings::FlagsOrIsa; use std::path::Path; -use utils::{pretty_error, read_to_string}; - -enum OwnedFlagsOrIsa { - Flags(settings::Flags), - Isa(Box), -} +use utils::{pretty_error, read_to_string, parse_sets_and_isa}; pub fn run( files: Vec, @@ -21,33 +15,12 @@ pub fn run( flag_set: Vec, flag_isa: String, ) -> Result<(), String> { - let mut flag_builder = settings::builder(); - parse_options( - flag_set.iter().map(|x| x.as_str()), - &mut flag_builder, - &Location { line_number: 0 }, - ).map_err(|err| err.to_string())?; - - let mut words = flag_isa.trim().split_whitespace(); - // Look for `isa foo`. - let owned_fisa = if let Some(isa_name) = words.next() { - let isa_builder = isa::lookup(isa_name).map_err(|err| match err { - isa::LookupError::Unknown => format!("unknown ISA '{}'", isa_name), - isa::LookupError::Unsupported => format!("support for ISA '{}' not enabled", isa_name), - })?; - OwnedFlagsOrIsa::Isa(isa_builder.finish(settings::Flags::new(&flag_builder))) - } else { - OwnedFlagsOrIsa::Flags(settings::Flags::new(&flag_builder)) - }; - let fisa = match owned_fisa { - OwnedFlagsOrIsa::Flags(ref flags) => FlagsOrIsa::from(flags), - OwnedFlagsOrIsa::Isa(ref isa) => FlagsOrIsa::from(&**isa), - }; + let parsed = parse_sets_and_isa(flag_set, flag_isa)?; for filename in files { let path = Path::new(&filename); let name = String::from(path.as_os_str().to_string_lossy()); - handle_module(flag_print, path.to_path_buf(), name, &fisa)?; + handle_module(flag_print, path.to_path_buf(), name, parsed.as_fisa())?; } Ok(()) } @@ -56,7 +29,7 @@ fn handle_module( flag_print: bool, path: PathBuf, name: String, - fisa: &FlagsOrIsa, + fisa: FlagsOrIsa, ) -> Result<(), String> { let buffer = read_to_string(&path).map_err( |e| format!("{}: {}", name, e), diff --git a/cranelift/src/utils.rs b/cranelift/src/utils.rs index a5f9940eb4..6a962d04f7 100644 --- a/cranelift/src/utils.rs +++ b/cranelift/src/utils.rs @@ -4,13 +4,16 @@ use cretonne::ir::entities::AnyEntity; use cretonne::{ir, verifier}; use cretonne::result::CtonError; use cretonne::isa::TargetIsa; +use cretonne::settings::{self, FlagsOrIsa}; +use cretonne::isa; +use cton_reader::{parse_options, Location}; use std::fmt::Write; use std::fs::File; -use std::io::{Result, Read}; +use std::io::{self, Read}; use std::path::Path; /// Read an entire file into a string. -pub fn read_to_string>(path: P) -> Result { +pub fn read_to_string>(path: P) -> io::Result { let mut file = File::open(path)?; let mut buffer = String::new(); file.read_to_string(&mut buffer)?; @@ -62,6 +65,49 @@ pub fn pretty_error(func: &ir::Function, isa: Option<&TargetIsa>, err: CtonError } } +/// Like FlagsOrIsa, but holds ownership. +pub enum OwnedFlagsOrIsa { + Flags(settings::Flags), + Isa(Box), +} + +impl OwnedFlagsOrIsa { + /// Produce a FlagsOrIsa reference. + pub fn as_fisa(&self) -> FlagsOrIsa { + match *self { + OwnedFlagsOrIsa::Flags(ref flags) => FlagsOrIsa::from(flags), + OwnedFlagsOrIsa::Isa(ref isa) => FlagsOrIsa::from(&**isa), + } + } +} + +/// Parse "set" and "isa" commands. +pub fn parse_sets_and_isa( + flag_set: Vec, + flag_isa: String, +) -> Result { + let mut flag_builder = settings::builder(); + parse_options( + flag_set.iter().map(|x| x.as_str()), + &mut flag_builder, + &Location { line_number: 0 }, + ).map_err(|err| err.to_string())?; + + let mut words = flag_isa.trim().split_whitespace(); + // Look for `isa foo`. + if let Some(isa_name) = words.next() { + let isa_builder = isa::lookup(isa_name).map_err(|err| match err { + isa::LookupError::Unknown => format!("unknown ISA '{}'", isa_name), + isa::LookupError::Unsupported => format!("support for ISA '{}' not enabled", isa_name), + })?; + Ok(OwnedFlagsOrIsa::Isa( + isa_builder.finish(settings::Flags::new(&flag_builder)), + )) + } else { + Ok(OwnedFlagsOrIsa::Flags(settings::Flags::new(&flag_builder))) + } +} + #[test] fn test_match_directive() { assert_eq!(match_directive("; foo: bar ", "foo:"), Some("bar")); diff --git a/cranelift/src/wasm.rs b/cranelift/src/wasm.rs index 81331faa40..460d4280f5 100644 --- a/cranelift/src/wasm.rs +++ b/cranelift/src/wasm.rs @@ -5,11 +5,9 @@ //! and tables, then emitting the translated code with hardcoded addresses to memory. use cton_wasm::{translate_module, DummyRuntime, WasmRuntime}; -use cton_reader::{parse_options, Location}; use std::path::PathBuf; use cretonne::Context; -use cretonne::settings::{self, FlagsOrIsa}; -use cretonne::isa::{self, TargetIsa}; +use cretonne::settings::FlagsOrIsa; use std::fs::File; use std::error::Error; use std::io; @@ -18,7 +16,7 @@ use std::path::Path; use std::process::Command; use tempdir::TempDir; use term; -use utils::{pretty_verifier_error, pretty_error}; +use utils::{pretty_verifier_error, pretty_error, parse_sets_and_isa}; macro_rules! vprintln { ($x: expr, $($tts:tt)*) => { @@ -43,11 +41,6 @@ fn read_wasm_file(path: PathBuf) -> Result, io::Error> { Ok(buf) } -enum OwnedFlagsOrIsa { - Flags(settings::Flags), - Isa(Box), -} - pub fn run( files: Vec, flag_verbose: bool, @@ -57,28 +50,7 @@ pub fn run( flag_set: Vec, flag_isa: String, ) -> Result<(), String> { - let mut flag_builder = settings::builder(); - parse_options( - flag_set.iter().map(|x| x.as_str()), - &mut flag_builder, - &Location { line_number: 0 }, - ).map_err(|err| err.to_string())?; - - let mut words = flag_isa.trim().split_whitespace(); - // Look for `isa foo`. - let owned_fisa = if let Some(isa_name) = words.next() { - let isa_builder = isa::lookup(isa_name).map_err(|err| match err { - isa::LookupError::Unknown => format!("unknown ISA '{}'", isa_name), - isa::LookupError::Unsupported => format!("support for ISA '{}' not enabled", isa_name), - })?; - OwnedFlagsOrIsa::Isa(isa_builder.finish(settings::Flags::new(&flag_builder))) - } else { - OwnedFlagsOrIsa::Flags(settings::Flags::new(&flag_builder)) - }; - let fisa = match owned_fisa { - OwnedFlagsOrIsa::Flags(ref flags) => FlagsOrIsa::from(flags), - OwnedFlagsOrIsa::Isa(ref isa) => FlagsOrIsa::from(&**isa), - }; + let parsed = parse_sets_and_isa(flag_set, flag_isa)?; for filename in files { let path = Path::new(&filename); @@ -90,7 +62,7 @@ pub fn run( flag_print, path.to_path_buf(), name, - &fisa, + parsed.as_fisa(), )?; } Ok(()) @@ -103,7 +75,7 @@ fn handle_module( flag_print: bool, path: PathBuf, name: String, - fisa: &FlagsOrIsa, + fisa: FlagsOrIsa, ) -> Result<(), String> { let mut terminal = term::stdout().unwrap(); terminal.fg(term::color::YELLOW).unwrap(); @@ -170,7 +142,7 @@ fn handle_module( let mut context = Context::new(); context.func = func.clone(); if flag_check_translation { - context.verify(*fisa).map_err(|err| { + context.verify(fisa).map_err(|err| { pretty_verifier_error(&context.func, fisa.isa, err) })?; continue;