Rename more Error and Result types.

This commit is contained in:
Dan Gohman
2018-06-12 04:43:02 -07:00
parent 43bd3cb2a3
commit 1b55a2d005
12 changed files with 157 additions and 150 deletions

View File

@@ -36,7 +36,7 @@ def gen_to_and_from_str(ty, values, fmt):
with fmt.indented('impl str::FromStr for {} {{'.format(ty), '}'): with fmt.indented('impl str::FromStr for {} {{'.format(ty), '}'):
fmt.line('type Err = ();') fmt.line('type Err = ();')
with fmt.indented( with fmt.indented(
'fn from_str(s: &str) -> result::Result<Self, Self::Err> {', 'fn from_str(s: &str) -> Result<Self, Self::Err> {',
'}'): '}'):
with fmt.indented('match s {', '}'): with fmt.indented('match s {', '}'):
for v in values: for v in values:

View File

@@ -58,7 +58,7 @@ use isa::enc_tables::Encodings;
use regalloc; use regalloc;
use result::CodegenResult; use result::CodegenResult;
use settings; use settings;
use settings::CallConv; use settings::{CallConv, SetResult};
use std::boxed::Box; use std::boxed::Box;
use std::fmt; use std::fmt;
use target_lexicon::{Architecture, Triple}; use target_lexicon::{Architecture, Triple};
@@ -146,11 +146,11 @@ impl Builder {
} }
impl settings::Configurable for Builder { impl settings::Configurable for Builder {
fn set(&mut self, name: &str, value: &str) -> settings::Result<()> { fn set(&mut self, name: &str, value: &str) -> SetResult<()> {
self.setup.set(name, value) self.setup.set(name, value)
} }
fn enable(&mut self, name: &str) -> settings::Result<()> { fn enable(&mut self, name: &str) -> SetResult<()> {
self.setup.enable(name) self.setup.enable(name)
} }
} }

View File

@@ -24,7 +24,6 @@ use constant_hash::{probe, simple_hash};
use isa::TargetIsa; use isa::TargetIsa;
use std::boxed::Box; use std::boxed::Box;
use std::fmt; use std::fmt;
use std::result;
use std::str; use std::str;
/// A string-based configurator for settings groups. /// A string-based configurator for settings groups.
@@ -35,12 +34,12 @@ pub trait Configurable {
/// Set the string value of any setting by name. /// Set the string value of any setting by name.
/// ///
/// This can set any type of setting whether it is numeric, boolean, or enumerated. /// This can set any type of setting whether it is numeric, boolean, or enumerated.
fn set(&mut self, name: &str, value: &str) -> Result<()>; fn set(&mut self, name: &str, value: &str) -> SetResult<()>;
/// Enable a boolean setting or apply a preset. /// Enable a boolean setting or apply a preset.
/// ///
/// If the identified setting isn't a boolean or a preset, a `BadType` error is returned. /// If the identified setting isn't a boolean or a preset, a `BadType` error is returned.
fn enable(&mut self, name: &str) -> Result<()>; fn enable(&mut self, name: &str) -> SetResult<()>;
} }
/// Collect settings values based on a template. /// Collect settings values based on a template.
@@ -84,9 +83,9 @@ impl Builder {
} }
/// Look up a descriptor by name. /// Look up a descriptor by name.
fn lookup(&self, name: &str) -> Result<(usize, detail::Detail)> { fn lookup(&self, name: &str) -> SetResult<(usize, detail::Detail)> {
match probe(self.template, name, simple_hash(name)) { match probe(self.template, name, simple_hash(name)) {
Err(_) => Err(Error::BadName), Err(_) => Err(SetError::BadName),
Ok(entry) => { Ok(entry) => {
let d = &self.template.descriptors[self.template.hash_table[entry] as usize]; let d = &self.template.descriptors[self.template.hash_table[entry] as usize];
Ok((d.offset as usize, d.detail)) Ok((d.offset as usize, d.detail))
@@ -95,23 +94,23 @@ impl Builder {
} }
} }
fn parse_bool_value(value: &str) -> Result<bool> { fn parse_bool_value(value: &str) -> SetResult<bool> {
match value { match value {
"true" | "on" | "yes" | "1" => Ok(true), "true" | "on" | "yes" | "1" => Ok(true),
"false" | "off" | "no" | "0" => Ok(false), "false" | "off" | "no" | "0" => Ok(false),
_ => Err(Error::BadValue), _ => Err(SetError::BadValue),
} }
} }
fn parse_enum_value(value: &str, choices: &[&str]) -> Result<u8> { fn parse_enum_value(value: &str, choices: &[&str]) -> SetResult<u8> {
match choices.iter().position(|&tag| tag == value) { match choices.iter().position(|&tag| tag == value) {
Some(idx) => Ok(idx as u8), Some(idx) => Ok(idx as u8),
None => Err(Error::BadValue), None => Err(SetError::BadValue),
} }
} }
impl Configurable for Builder { impl Configurable for Builder {
fn enable(&mut self, name: &str) -> Result<()> { fn enable(&mut self, name: &str) -> SetResult<()> {
use self::detail::Detail; use self::detail::Detail;
let (offset, detail) = self.lookup(name)?; let (offset, detail) = self.lookup(name)?;
match detail { match detail {
@@ -123,27 +122,27 @@ impl Configurable for Builder {
self.apply_preset(&self.template.presets[offset..]); self.apply_preset(&self.template.presets[offset..]);
Ok(()) Ok(())
} }
_ => Err(Error::BadType), _ => Err(SetError::BadType),
} }
} }
fn set(&mut self, name: &str, value: &str) -> Result<()> { fn set(&mut self, name: &str, value: &str) -> SetResult<()> {
use self::detail::Detail; use self::detail::Detail;
let (offset, detail) = self.lookup(name)?; let (offset, detail) = self.lookup(name)?;
match detail { match detail {
Detail::Bool { bit } => { Detail::Bool { bit } => {
// Cannot currently propagate Result<()> up on functions returning () // Cannot currently propagate SetResult<()> up on functions returning ()
// with the `?` operator // with the `?` operator
self.set_bit(offset, bit, parse_bool_value(value)?); self.set_bit(offset, bit, parse_bool_value(value)?);
} }
Detail::Num => { Detail::Num => {
self.bytes[offset] = value.parse().map_err(|_| Error::BadValue)?; self.bytes[offset] = value.parse().map_err(|_| SetError::BadValue)?;
} }
Detail::Enum { last, enumerators } => { Detail::Enum { last, enumerators } => {
self.bytes[offset] = self.bytes[offset] =
parse_enum_value(value, self.template.enums(last, enumerators))?; parse_enum_value(value, self.template.enums(last, enumerators))?;
} }
Detail::Preset => return Err(Error::BadName), Detail::Preset => return Err(SetError::BadName),
} }
Ok(()) Ok(())
} }
@@ -151,7 +150,7 @@ impl Configurable for Builder {
/// An error produced when changing a setting. /// An error produced when changing a setting.
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum Error { pub enum SetError {
/// No setting by this name exists. /// No setting by this name exists.
BadName, BadName,
@@ -163,7 +162,7 @@ pub enum Error {
} }
/// A result returned when changing a setting. /// A result returned when changing a setting.
pub type Result<T> = result::Result<T, Error>; pub type SetResult<T> = Result<T, SetError>;
/// A reference to just the boolean predicates of a settings object. /// A reference to just the boolean predicates of a settings object.
/// ///
@@ -348,7 +347,7 @@ impl<'a> From<&'a TargetIsa> for FlagsOrIsa<'a> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::Configurable; use super::Configurable;
use super::Error::*; use super::SetError::*;
use super::{builder, Flags}; use super::{builder, Flags};
use std::string::ToString; use std::string::ToString;

View File

@@ -6,13 +6,12 @@
use ir::{DataFlowGraph, Ebb, Function, Inst, SigRef, Type, Value, ValueDef}; use ir::{DataFlowGraph, Ebb, Function, Inst, SigRef, Type, Value, ValueDef};
use isa::{RegInfo, TargetIsa}; use isa::{RegInfo, TargetIsa};
use packed_option::ReservedValue; use packed_option::ReservedValue;
use std::fmt::{self, Error, Result, Write}; use std::fmt::{self, Write};
use std::result;
use std::string::String; use std::string::String;
/// Write `func` to `w` as equivalent text. /// Write `func` to `w` as equivalent text.
/// Use `isa` to emit ISA-dependent annotations. /// Use `isa` to emit ISA-dependent annotations.
pub fn write_function(w: &mut Write, func: &Function, isa: Option<&TargetIsa>) -> Result { pub fn write_function(w: &mut Write, func: &Function, isa: Option<&TargetIsa>) -> fmt::Result {
let regs = isa.map(TargetIsa::register_info); let regs = isa.map(TargetIsa::register_info);
let regs = regs.as_ref(); let regs = regs.as_ref();
@@ -34,7 +33,7 @@ pub fn write_function(w: &mut Write, func: &Function, isa: Option<&TargetIsa>) -
// //
// Function spec. // Function spec.
fn write_spec(w: &mut Write, func: &Function, regs: Option<&RegInfo>) -> Result { fn write_spec(w: &mut Write, func: &Function, regs: Option<&RegInfo>) -> fmt::Result {
write!(w, "{}{}", func.name, func.signature.display(regs)) write!(w, "{}{}", func.name, func.signature.display(regs))
} }
@@ -42,7 +41,7 @@ fn write_preamble(
w: &mut Write, w: &mut Write,
func: &Function, func: &Function,
regs: Option<&RegInfo>, regs: Option<&RegInfo>,
) -> result::Result<bool, Error> { ) -> Result<bool, fmt::Error> {
let mut any = false; let mut any = false;
for (ss, slot) in func.stack_slots.iter() { for (ss, slot) in func.stack_slots.iter() {
@@ -91,7 +90,12 @@ fn write_preamble(
// //
// Basic blocks // Basic blocks
pub fn write_arg(w: &mut Write, func: &Function, regs: Option<&RegInfo>, arg: Value) -> Result { pub fn write_arg(
w: &mut Write,
func: &Function,
regs: Option<&RegInfo>,
arg: Value,
) -> fmt::Result {
write!(w, "{}: {}", arg, func.dfg.value_type(arg))?; write!(w, "{}: {}", arg, func.dfg.value_type(arg))?;
let loc = func.locations[arg]; let loc = func.locations[arg];
if loc.is_assigned() { if loc.is_assigned() {
@@ -107,7 +111,7 @@ pub fn write_ebb_header(
isa: Option<&TargetIsa>, isa: Option<&TargetIsa>,
ebb: Ebb, ebb: Ebb,
indent: usize, indent: usize,
) -> Result { ) -> fmt::Result {
// Write out the basic block header, outdented: // Write out the basic block header, outdented:
// //
// ebb1: // ebb1:
@@ -137,7 +141,7 @@ pub fn write_ebb_header(
writeln!(w, "):") writeln!(w, "):")
} }
pub fn write_ebb(w: &mut Write, func: &Function, isa: Option<&TargetIsa>, ebb: Ebb) -> Result { pub fn write_ebb(w: &mut Write, func: &Function, isa: Option<&TargetIsa>, ebb: Ebb) -> fmt::Result {
// Indent all instructions if any encodings are present. // Indent all instructions if any encodings are present.
let indent = if func.encodings.is_empty() && func.srclocs.is_empty() { let indent = if func.encodings.is_empty() && func.srclocs.is_empty() {
4 4
@@ -191,7 +195,7 @@ fn type_suffix(func: &Function, inst: Inst) -> Option<Type> {
} }
// Write out any value aliases appearing in `inst`. // Write out any value aliases appearing in `inst`.
fn write_value_aliases(w: &mut Write, func: &Function, inst: Inst, indent: usize) -> Result { fn write_value_aliases(w: &mut Write, func: &Function, inst: Inst, indent: usize) -> fmt::Result {
for &arg in func.dfg.inst_args(inst) { for &arg in func.dfg.inst_args(inst) {
let resolved = func.dfg.resolve_aliases(arg); let resolved = func.dfg.resolve_aliases(arg);
if resolved != arg { if resolved != arg {
@@ -207,7 +211,7 @@ fn write_instruction(
isa: Option<&TargetIsa>, isa: Option<&TargetIsa>,
inst: Inst, inst: Inst,
indent: usize, indent: usize,
) -> Result { ) -> fmt::Result {
// Value aliases come out on lines before the instruction using them. // Value aliases come out on lines before the instruction using them.
write_value_aliases(w, func, inst, indent)?; write_value_aliases(w, func, inst, indent)?;
@@ -272,7 +276,7 @@ pub fn write_operands(
dfg: &DataFlowGraph, dfg: &DataFlowGraph,
isa: Option<&TargetIsa>, isa: Option<&TargetIsa>,
inst: Inst, inst: Inst,
) -> Result { ) -> fmt::Result {
let pool = &dfg.value_lists; let pool = &dfg.value_lists;
use ir::instructions::InstructionData::*; use ir::instructions::InstructionData::*;
match dfg[inst] { match dfg[inst] {
@@ -472,7 +476,7 @@ pub fn write_operands(
} }
/// Write EBB args using optional parantheses. /// Write EBB args using optional parantheses.
fn write_ebb_args(w: &mut Write, args: &[Value]) -> Result { fn write_ebb_args(w: &mut Write, args: &[Value]) -> fmt::Result {
if args.is_empty() { if args.is_empty() {
Ok(()) Ok(())
} else { } else {
@@ -484,7 +488,7 @@ fn write_ebb_args(w: &mut Write, args: &[Value]) -> Result {
struct DisplayValues<'a>(&'a [Value]); struct DisplayValues<'a>(&'a [Value]);
impl<'a> fmt::Display for DisplayValues<'a> { impl<'a> fmt::Display for DisplayValues<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (i, val) in self.0.iter().enumerate() { for (i, val) in self.0.iter().enumerate() {
if i == 0 { if i == 0 {
write!(f, "{}", val)?; write!(f, "{}", val)?;
@@ -499,7 +503,7 @@ impl<'a> fmt::Display for DisplayValues<'a> {
struct DisplayValuesWithDelimiter<'a>(&'a [Value], char); struct DisplayValuesWithDelimiter<'a>(&'a [Value], char);
impl<'a> fmt::Display for DisplayValuesWithDelimiter<'a> { impl<'a> fmt::Display for DisplayValuesWithDelimiter<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (i, val) in self.0.iter().enumerate() { for (i, val) in self.0.iter().enumerate() {
if i == 0 { if i == 0 {
write!(f, "{}", val)?; write!(f, "{}", val)?;

View File

@@ -6,7 +6,6 @@ use cretonne_codegen::{binemit, ir};
use std::marker; use std::marker;
use DataContext; use DataContext;
use Linkage; use Linkage;
use ModuleError;
use ModuleNamespace; use ModuleNamespace;
use ModuleResult; use ModuleResult;

View File

@@ -1,9 +1,8 @@
//! Define the `Location`, `Error`, and `Result` types. //! Define the `Location`, `ParseError`, and `ParseResult` types.
#![macro_use] #![macro_use]
use std::fmt; use std::fmt;
use std::result;
/// The location of a `Token` or `Error`. /// The location of a `Token` or `Error`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
@@ -15,14 +14,14 @@ pub struct Location {
/// A parse error is returned when the parse failed. /// A parse error is returned when the parse failed.
#[derive(Debug)] #[derive(Debug)]
pub struct Error { pub struct ParseError {
/// Location of the error. /// Location of the error.
pub location: Location, pub location: Location,
/// Error message. /// Error message.
pub message: String, pub message: String,
} }
impl fmt::Display for Error { impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.location.line_number == 0 { if self.location.line_number == 0 {
write!(f, "command-line arguments: {}", self.message) write!(f, "command-line arguments: {}", self.message)
@@ -32,20 +31,20 @@ impl fmt::Display for Error {
} }
} }
/// Result of a parser operation. The `Error` variant includes a location. /// Result of a parser operation. The `ParseError` variant includes a location.
pub type Result<T> = result::Result<T, Error>; pub type ParseResult<T> = Result<T, ParseError>;
// Create an `Err` variant of `Result<X>` from a location and `format!` args. // Create an `Err` variant of `ParseResult<X>` from a location and `format!` args.
macro_rules! err { macro_rules! err {
( $loc:expr, $msg:expr ) => { ( $loc:expr, $msg:expr ) => {
Err($crate::Error { Err($crate::ParseError {
location: $loc.clone(), location: $loc.clone(),
message: $msg.to_string(), message: $msg.to_string(),
}) })
}; };
( $loc:expr, $fmt:expr, $( $arg:expr ),+ ) => { ( $loc:expr, $fmt:expr, $( $arg:expr ),+ ) => {
Err($crate::Error { Err($crate::ParseError {
location: $loc.clone(), location: $loc.clone(),
message: format!( $fmt, $( $arg ),+ ), message: format!( $fmt, $( $arg ),+ ),
}) })

View File

@@ -7,8 +7,8 @@
//! ISAs. If the file contains no `isa` commands, the tests will be run against all supported ISAs. //! ISAs. If the file contains no `isa` commands, the tests will be run against all supported ISAs.
use cretonne_codegen::isa::TargetIsa; use cretonne_codegen::isa::TargetIsa;
use cretonne_codegen::settings::{Configurable, Error as SetError, Flags}; use cretonne_codegen::settings::{Configurable, Flags, SetError};
use error::{Location, Result}; use error::{Location, ParseResult};
use testcommand::TestOption; use testcommand::TestOption;
/// The ISA specifications in a `.cton` file. /// The ISA specifications in a `.cton` file.
@@ -35,7 +35,7 @@ impl IsaSpec {
} }
/// Parse an iterator of command line options and apply them to `config`. /// Parse an iterator of command line options and apply them to `config`.
pub fn parse_options<'a, I>(iter: I, config: &mut Configurable, loc: &Location) -> Result<()> pub fn parse_options<'a, I>(iter: I, config: &mut Configurable, loc: &Location) -> ParseResult<()>
where where
I: Iterator<Item = &'a str>, I: Iterator<Item = &'a str>,
{ {

View File

@@ -63,19 +63,19 @@ fn token(token: Token, loc: Location) -> Result<LocatedToken, LocatedError> {
/// An error from the lexical analysis. /// An error from the lexical analysis.
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Error { pub enum LexError {
InvalidChar, InvalidChar,
} }
/// An `Error` with an associated Location. /// A `LexError` with an associated Location.
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct LocatedError { pub struct LocatedError {
pub error: Error, pub error: LexError,
pub location: Location, pub location: Location,
} }
/// Wrap up an `Error` with the given location. /// Wrap up a `LexError` with the given location.
fn error<'a>(error: Error, loc: Location) -> Result<LocatedToken<'a>, LocatedError> { fn error<'a>(error: LexError, loc: Location) -> Result<LocatedToken<'a>, LocatedError> {
Err(LocatedError { Err(LocatedError {
error, error,
location: loc, location: loc,
@@ -468,7 +468,7 @@ impl<'a> Lexer<'a> {
_ => { _ => {
// Skip invalid char, return error. // Skip invalid char, return error.
self.next_ch(); self.next_ch();
Some(error(Error::InvalidChar, loc)) Some(error(LexError::InvalidChar, loc))
} }
}; };
} }
@@ -511,7 +511,7 @@ mod tests {
Some(super::token(token, Location { line_number: line })) Some(super::token(token, Location { line_number: line }))
} }
fn error<'a>(error: Error, line: usize) -> Option<Result<LocatedToken<'a>, LocatedError>> { fn error<'a>(error: LexError, line: usize) -> Option<Result<LocatedToken<'a>, LocatedError>> {
Some(super::error(error, Location { line_number: line })) Some(super::error(error, Location { line_number: line }))
} }
@@ -539,7 +539,7 @@ mod tests {
// Scan a comment after an invalid char. // Scan a comment after an invalid char.
let mut lex = Lexer::new("$; hello"); let mut lex = Lexer::new("$; hello");
assert_eq!(lex.next(), error(Error::InvalidChar, 1)); assert_eq!(lex.next(), error(LexError::InvalidChar, 1));
assert_eq!(lex.next(), token(Token::Comment("; hello"), 1)); assert_eq!(lex.next(), token(Token::Comment("; hello"), 1));
assert_eq!(lex.next(), None); assert_eq!(lex.next(), None);
} }

View File

@@ -18,7 +18,7 @@
extern crate cretonne_codegen; extern crate cretonne_codegen;
extern crate target_lexicon; extern crate target_lexicon;
pub use error::{Error, Location, Result}; pub use error::{Location, ParseError, ParseResult};
pub use isaspec::{parse_options, IsaSpec}; pub use isaspec::{parse_options, IsaSpec};
pub use parser::{parse_functions, parse_test}; pub use parser::{parse_functions, parse_test};
pub use sourcemap::SourceMap; pub use sourcemap::SourceMap;

View File

@@ -15,9 +15,9 @@ use cretonne_codegen::isa::{self, Encoding, RegUnit, TargetIsa};
use cretonne_codegen::packed_option::ReservedValue; use cretonne_codegen::packed_option::ReservedValue;
use cretonne_codegen::settings::CallConv; use cretonne_codegen::settings::CallConv;
use cretonne_codegen::{settings, timing}; use cretonne_codegen::{settings, timing};
use error::{Error, Location, Result}; use error::{Location, ParseError, ParseResult};
use isaspec; use isaspec;
use lexer::{self, Lexer, Token}; use lexer::{LexError, Lexer, LocatedError, LocatedToken, Token};
use sourcemap::SourceMap; use sourcemap::SourceMap;
use std::mem; use std::mem;
use std::str::FromStr; use std::str::FromStr;
@@ -29,7 +29,7 @@ use testfile::{Comment, Details, TestFile};
/// Parse the entire `text` into a list of functions. /// Parse the entire `text` into a list of functions.
/// ///
/// Any test commands or target declarations are ignored. /// Any test commands or target declarations are ignored.
pub fn parse_functions(text: &str) -> Result<Vec<Function>> { pub fn parse_functions(text: &str) -> ParseResult<Vec<Function>> {
let _tt = timing::parse_text(); let _tt = timing::parse_text();
parse_test(text).map(|file| file.functions.into_iter().map(|(func, _)| func).collect()) parse_test(text).map(|file| file.functions.into_iter().map(|(func, _)| func).collect())
} }
@@ -37,7 +37,7 @@ pub fn parse_functions(text: &str) -> Result<Vec<Function>> {
/// Parse the entire `text` as a test case file. /// Parse the entire `text` as a test case file.
/// ///
/// The returned `TestFile` contains direct references to substrings of `text`. /// The returned `TestFile` contains direct references to substrings of `text`.
pub fn parse_test(text: &str) -> Result<TestFile> { pub fn parse_test(text: &str) -> ParseResult<TestFile> {
let _tt = timing::parse_text(); let _tt = timing::parse_text();
let mut parser = Parser::new(text); let mut parser = Parser::new(text);
// Gather the preamble comments. // Gather the preamble comments.
@@ -63,7 +63,7 @@ pub fn parse_test(text: &str) -> Result<TestFile> {
pub struct Parser<'a> { pub struct Parser<'a> {
lex: Lexer<'a>, lex: Lexer<'a>,
lex_error: Option<lexer::Error>, lex_error: Option<LexError>,
/// Current lookahead token. /// Current lookahead token.
lookahead: Option<Token<'a>>, lookahead: Option<Token<'a>>,
@@ -121,7 +121,7 @@ impl<'a> Context<'a> {
} }
// Allocate a new stack slot. // Allocate a new stack slot.
fn add_ss(&mut self, ss: StackSlot, data: StackSlotData, loc: &Location) -> Result<()> { fn add_ss(&mut self, ss: StackSlot, data: StackSlotData, loc: &Location) -> ParseResult<()> {
while self.function.stack_slots.next_key().index() <= ss.index() { while self.function.stack_slots.next_key().index() <= ss.index() {
self.function self.function
.create_stack_slot(StackSlotData::new(StackSlotKind::SpillSlot, 0)); .create_stack_slot(StackSlotData::new(StackSlotKind::SpillSlot, 0));
@@ -131,7 +131,7 @@ impl<'a> Context<'a> {
} }
// Resolve a reference to a stack slot. // Resolve a reference to a stack slot.
fn check_ss(&self, ss: StackSlot, loc: &Location) -> Result<()> { fn check_ss(&self, ss: StackSlot, loc: &Location) -> ParseResult<()> {
if !self.map.contains_ss(ss) { if !self.map.contains_ss(ss) {
err!(loc, "undefined stack slot {}", ss) err!(loc, "undefined stack slot {}", ss)
} else { } else {
@@ -140,7 +140,7 @@ impl<'a> Context<'a> {
} }
// Allocate a global variable slot. // Allocate a global variable slot.
fn add_gv(&mut self, gv: GlobalVar, data: GlobalVarData, loc: &Location) -> Result<()> { fn add_gv(&mut self, gv: GlobalVar, data: GlobalVarData, loc: &Location) -> ParseResult<()> {
while self.function.global_vars.next_key().index() <= gv.index() { while self.function.global_vars.next_key().index() <= gv.index() {
self.function.create_global_var(GlobalVarData::Sym { self.function.create_global_var(GlobalVarData::Sym {
name: ExternalName::testcase(""), name: ExternalName::testcase(""),
@@ -152,7 +152,7 @@ impl<'a> Context<'a> {
} }
// Resolve a reference to a global variable. // Resolve a reference to a global variable.
fn check_gv(&self, gv: GlobalVar, loc: &Location) -> Result<()> { fn check_gv(&self, gv: GlobalVar, loc: &Location) -> ParseResult<()> {
if !self.map.contains_gv(gv) { if !self.map.contains_gv(gv) {
err!(loc, "undefined global variable {}", gv) err!(loc, "undefined global variable {}", gv)
} else { } else {
@@ -161,7 +161,7 @@ impl<'a> Context<'a> {
} }
// Allocate a heap slot. // Allocate a heap slot.
fn add_heap(&mut self, heap: Heap, data: HeapData, loc: &Location) -> Result<()> { fn add_heap(&mut self, heap: Heap, data: HeapData, loc: &Location) -> ParseResult<()> {
while self.function.heaps.next_key().index() <= heap.index() { while self.function.heaps.next_key().index() <= heap.index() {
self.function.create_heap(HeapData { self.function.create_heap(HeapData {
base: HeapBase::ReservedReg, base: HeapBase::ReservedReg,
@@ -177,7 +177,7 @@ impl<'a> Context<'a> {
} }
// Resolve a reference to a heap. // Resolve a reference to a heap.
fn check_heap(&self, heap: Heap, loc: &Location) -> Result<()> { fn check_heap(&self, heap: Heap, loc: &Location) -> ParseResult<()> {
if !self.map.contains_heap(heap) { if !self.map.contains_heap(heap) {
err!(loc, "undefined heap {}", heap) err!(loc, "undefined heap {}", heap)
} else { } else {
@@ -186,7 +186,7 @@ impl<'a> Context<'a> {
} }
// Allocate a new signature. // Allocate a new signature.
fn add_sig(&mut self, sig: SigRef, data: Signature, loc: &Location) -> Result<()> { fn add_sig(&mut self, sig: SigRef, data: Signature, loc: &Location) -> ParseResult<()> {
while self.function.dfg.signatures.next_key().index() <= sig.index() { while self.function.dfg.signatures.next_key().index() <= sig.index() {
self.function self.function
.import_signature(Signature::new(CallConv::Fast)); .import_signature(Signature::new(CallConv::Fast));
@@ -196,7 +196,7 @@ impl<'a> Context<'a> {
} }
// Resolve a reference to a signature. // Resolve a reference to a signature.
fn check_sig(&self, sig: SigRef, loc: &Location) -> Result<()> { fn check_sig(&self, sig: SigRef, loc: &Location) -> ParseResult<()> {
if !self.map.contains_sig(sig) { if !self.map.contains_sig(sig) {
err!(loc, "undefined signature {}", sig) err!(loc, "undefined signature {}", sig)
} else { } else {
@@ -205,7 +205,7 @@ impl<'a> Context<'a> {
} }
// Allocate a new external function. // Allocate a new external function.
fn add_fn(&mut self, fn_: FuncRef, data: ExtFuncData, loc: &Location) -> Result<()> { fn add_fn(&mut self, fn_: FuncRef, data: ExtFuncData, loc: &Location) -> ParseResult<()> {
while self.function.dfg.ext_funcs.next_key().index() <= fn_.index() { while self.function.dfg.ext_funcs.next_key().index() <= fn_.index() {
self.function.import_function(ExtFuncData { self.function.import_function(ExtFuncData {
name: ExternalName::testcase(""), name: ExternalName::testcase(""),
@@ -218,7 +218,7 @@ impl<'a> Context<'a> {
} }
// Resolve a reference to a function. // Resolve a reference to a function.
fn check_fn(&self, fn_: FuncRef, loc: &Location) -> Result<()> { fn check_fn(&self, fn_: FuncRef, loc: &Location) -> ParseResult<()> {
if !self.map.contains_fn(fn_) { if !self.map.contains_fn(fn_) {
err!(loc, "undefined function {}", fn_) err!(loc, "undefined function {}", fn_)
} else { } else {
@@ -227,7 +227,7 @@ impl<'a> Context<'a> {
} }
// Allocate a new jump table. // Allocate a new jump table.
fn add_jt(&mut self, jt: JumpTable, data: JumpTableData, loc: &Location) -> Result<()> { fn add_jt(&mut self, jt: JumpTable, data: JumpTableData, loc: &Location) -> ParseResult<()> {
while self.function.jump_tables.next_key().index() <= jt.index() { while self.function.jump_tables.next_key().index() <= jt.index() {
self.function.create_jump_table(JumpTableData::new()); self.function.create_jump_table(JumpTableData::new());
} }
@@ -236,7 +236,7 @@ impl<'a> Context<'a> {
} }
// Resolve a reference to a jump table. // Resolve a reference to a jump table.
fn check_jt(&self, jt: JumpTable, loc: &Location) -> Result<()> { fn check_jt(&self, jt: JumpTable, loc: &Location) -> ParseResult<()> {
if !self.map.contains_jt(jt) { if !self.map.contains_jt(jt) {
err!(loc, "undefined jump table {}", jt) err!(loc, "undefined jump table {}", jt)
} else { } else {
@@ -245,7 +245,7 @@ impl<'a> Context<'a> {
} }
// Assign the global for the stack limit. // Assign the global for the stack limit.
fn set_stack_limit(&mut self, gv: GlobalVar, loc: &Location) -> Result<()> { fn set_stack_limit(&mut self, gv: GlobalVar, loc: &Location) -> ParseResult<()> {
if let Some(_) = self.function.set_stack_limit(Some(gv)) { if let Some(_) = self.function.set_stack_limit(Some(gv)) {
err!(loc, "multiple stack_limit declarations") err!(loc, "multiple stack_limit declarations")
} else { } else {
@@ -254,7 +254,7 @@ impl<'a> Context<'a> {
} }
// Allocate a new EBB. // Allocate a new EBB.
fn add_ebb(&mut self, ebb: Ebb, loc: &Location) -> Result<Ebb> { fn add_ebb(&mut self, ebb: Ebb, loc: &Location) -> ParseResult<Ebb> {
while self.function.dfg.num_ebbs() <= ebb.index() { while self.function.dfg.num_ebbs() <= ebb.index() {
self.function.dfg.make_ebb(); self.function.dfg.make_ebb();
} }
@@ -298,7 +298,7 @@ impl<'a> Parser<'a> {
#[cfg_attr(feature = "cargo-clippy", allow(while_immutable_condition))] #[cfg_attr(feature = "cargo-clippy", allow(while_immutable_condition))]
while self.lookahead == None { while self.lookahead == None {
match self.lex.next() { match self.lex.next() {
Some(Ok(lexer::LocatedToken { token, location })) => { Some(Ok(LocatedToken { token, location })) => {
match token { match token {
Token::Comment(text) => { Token::Comment(text) => {
if self.gathering_comments { if self.gathering_comments {
@@ -309,7 +309,7 @@ impl<'a> Parser<'a> {
} }
self.loc = location; self.loc = location;
} }
Some(Err(lexer::LocatedError { error, location })) => { Some(Err(LocatedError { error, location })) => {
self.lex_error = Some(error); self.lex_error = Some(error);
self.loc = location; self.loc = location;
break; break;
@@ -347,7 +347,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a token without payload. // Match and consume a token without payload.
fn match_token(&mut self, want: Token<'a>, err_msg: &str) -> Result<Token<'a>> { fn match_token(&mut self, want: Token<'a>, err_msg: &str) -> ParseResult<Token<'a>> {
if self.token() == Some(want) { if self.token() == Some(want) {
Ok(self.consume()) Ok(self.consume())
} else { } else {
@@ -367,7 +367,7 @@ impl<'a> Parser<'a> {
// Match and consume a specific identifier string. // Match and consume a specific identifier string.
// Used for pseudo-keywords like "stack_slot" that only appear in certain contexts. // Used for pseudo-keywords like "stack_slot" that only appear in certain contexts.
fn match_identifier(&mut self, want: &'static str, err_msg: &str) -> Result<Token<'a>> { fn match_identifier(&mut self, want: &'static str, err_msg: &str) -> ParseResult<Token<'a>> {
if self.token() == Some(Token::Identifier(want)) { if self.token() == Some(Token::Identifier(want)) {
Ok(self.consume()) Ok(self.consume())
} else { } else {
@@ -376,7 +376,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a type. // Match and consume a type.
fn match_type(&mut self, err_msg: &str) -> Result<Type> { fn match_type(&mut self, err_msg: &str) -> ParseResult<Type> {
if let Some(Token::Type(t)) = self.token() { if let Some(Token::Type(t)) = self.token() {
self.consume(); self.consume();
Ok(t) Ok(t)
@@ -386,7 +386,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a stack slot reference. // Match and consume a stack slot reference.
fn match_ss(&mut self, err_msg: &str) -> Result<StackSlot> { fn match_ss(&mut self, err_msg: &str) -> ParseResult<StackSlot> {
if let Some(Token::StackSlot(ss)) = self.token() { if let Some(Token::StackSlot(ss)) = self.token() {
self.consume(); self.consume();
if let Some(ss) = StackSlot::with_number(ss) { if let Some(ss) = StackSlot::with_number(ss) {
@@ -397,7 +397,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a global variable reference. // Match and consume a global variable reference.
fn match_gv(&mut self, err_msg: &str) -> Result<GlobalVar> { fn match_gv(&mut self, err_msg: &str) -> ParseResult<GlobalVar> {
if let Some(Token::GlobalVar(gv)) = self.token() { if let Some(Token::GlobalVar(gv)) = self.token() {
self.consume(); self.consume();
if let Some(gv) = GlobalVar::with_number(gv) { if let Some(gv) = GlobalVar::with_number(gv) {
@@ -408,7 +408,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a function reference. // Match and consume a function reference.
fn match_fn(&mut self, err_msg: &str) -> Result<FuncRef> { fn match_fn(&mut self, err_msg: &str) -> ParseResult<FuncRef> {
if let Some(Token::FuncRef(fnref)) = self.token() { if let Some(Token::FuncRef(fnref)) = self.token() {
self.consume(); self.consume();
if let Some(fnref) = FuncRef::with_number(fnref) { if let Some(fnref) = FuncRef::with_number(fnref) {
@@ -419,7 +419,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a signature reference. // Match and consume a signature reference.
fn match_sig(&mut self, err_msg: &str) -> Result<SigRef> { fn match_sig(&mut self, err_msg: &str) -> ParseResult<SigRef> {
if let Some(Token::SigRef(sigref)) = self.token() { if let Some(Token::SigRef(sigref)) = self.token() {
self.consume(); self.consume();
if let Some(sigref) = SigRef::with_number(sigref) { if let Some(sigref) = SigRef::with_number(sigref) {
@@ -430,7 +430,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a heap reference. // Match and consume a heap reference.
fn match_heap(&mut self, err_msg: &str) -> Result<Heap> { fn match_heap(&mut self, err_msg: &str) -> ParseResult<Heap> {
if let Some(Token::Heap(heap)) = self.token() { if let Some(Token::Heap(heap)) = self.token() {
self.consume(); self.consume();
if let Some(heap) = Heap::with_number(heap) { if let Some(heap) = Heap::with_number(heap) {
@@ -441,7 +441,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a jump table reference. // Match and consume a jump table reference.
fn match_jt(&mut self) -> Result<JumpTable> { fn match_jt(&mut self) -> ParseResult<JumpTable> {
if let Some(Token::JumpTable(jt)) = self.token() { if let Some(Token::JumpTable(jt)) = self.token() {
self.consume(); self.consume();
if let Some(jt) = JumpTable::with_number(jt) { if let Some(jt) = JumpTable::with_number(jt) {
@@ -452,7 +452,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume an ebb reference. // Match and consume an ebb reference.
fn match_ebb(&mut self, err_msg: &str) -> Result<Ebb> { fn match_ebb(&mut self, err_msg: &str) -> ParseResult<Ebb> {
if let Some(Token::Ebb(ebb)) = self.token() { if let Some(Token::Ebb(ebb)) = self.token() {
self.consume(); self.consume();
Ok(ebb) Ok(ebb)
@@ -462,7 +462,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a value reference, direct or vtable. // Match and consume a value reference, direct or vtable.
fn match_value(&mut self, err_msg: &str) -> Result<Value> { fn match_value(&mut self, err_msg: &str) -> ParseResult<Value> {
if let Some(Token::Value(v)) = self.token() { if let Some(Token::Value(v)) = self.token() {
self.consume(); self.consume();
Ok(v) Ok(v)
@@ -471,15 +471,15 @@ impl<'a> Parser<'a> {
} }
} }
fn error(&self, message: &str) -> Error { fn error(&self, message: &str) -> ParseError {
Error { ParseError {
location: self.loc, location: self.loc,
message: message.to_string(), message: message.to_string(),
} }
} }
// Match and consume an Imm64 immediate. // Match and consume an Imm64 immediate.
fn match_imm64(&mut self, err_msg: &str) -> Result<Imm64> { fn match_imm64(&mut self, err_msg: &str) -> ParseResult<Imm64> {
if let Some(Token::Integer(text)) = self.token() { if let Some(Token::Integer(text)) = self.token() {
self.consume(); self.consume();
// Lexer just gives us raw text that looks like an integer. // Lexer just gives us raw text that looks like an integer.
@@ -491,7 +491,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a Uimm32 immediate. // Match and consume a Uimm32 immediate.
fn match_uimm32(&mut self, err_msg: &str) -> Result<Uimm32> { fn match_uimm32(&mut self, err_msg: &str) -> ParseResult<Uimm32> {
if let Some(Token::Integer(text)) = self.token() { if let Some(Token::Integer(text)) = self.token() {
self.consume(); self.consume();
// Lexer just gives us raw text that looks like an integer. // Lexer just gives us raw text that looks like an integer.
@@ -504,7 +504,7 @@ impl<'a> Parser<'a> {
// Match and consume a u8 immediate. // Match and consume a u8 immediate.
// This is used for lane numbers in SIMD vectors. // This is used for lane numbers in SIMD vectors.
fn match_uimm8(&mut self, err_msg: &str) -> Result<u8> { fn match_uimm8(&mut self, err_msg: &str) -> ParseResult<u8> {
if let Some(Token::Integer(text)) = self.token() { if let Some(Token::Integer(text)) = self.token() {
self.consume(); self.consume();
// Lexer just gives us raw text that looks like an integer. // Lexer just gives us raw text that looks like an integer.
@@ -518,7 +518,7 @@ impl<'a> Parser<'a> {
// Match and consume an i32 immediate. // Match and consume an i32 immediate.
// This is used for stack argument byte offsets. // This is used for stack argument byte offsets.
fn match_imm32(&mut self, err_msg: &str) -> Result<i32> { fn match_imm32(&mut self, err_msg: &str) -> ParseResult<i32> {
if let Some(Token::Integer(text)) = self.token() { if let Some(Token::Integer(text)) = self.token() {
self.consume(); self.consume();
// Lexer just gives us raw text that looks like an integer. // Lexer just gives us raw text that looks like an integer.
@@ -534,7 +534,7 @@ impl<'a> Parser<'a> {
// //
// Note that this will match an empty string as an empty offset, and that if an offset is // Note that this will match an empty string as an empty offset, and that if an offset is
// present, it must contain a sign. // present, it must contain a sign.
fn optional_offset32(&mut self) -> Result<Offset32> { fn optional_offset32(&mut self) -> ParseResult<Offset32> {
if let Some(Token::Integer(text)) = self.token() { if let Some(Token::Integer(text)) = self.token() {
self.consume(); self.consume();
// Lexer just gives us raw text that looks like an integer. // Lexer just gives us raw text that looks like an integer.
@@ -547,7 +547,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume an Ieee32 immediate. // Match and consume an Ieee32 immediate.
fn match_ieee32(&mut self, err_msg: &str) -> Result<Ieee32> { fn match_ieee32(&mut self, err_msg: &str) -> ParseResult<Ieee32> {
if let Some(Token::Float(text)) = self.token() { if let Some(Token::Float(text)) = self.token() {
self.consume(); self.consume();
// Lexer just gives us raw text that looks like a float. // Lexer just gives us raw text that looks like a float.
@@ -559,7 +559,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume an Ieee64 immediate. // Match and consume an Ieee64 immediate.
fn match_ieee64(&mut self, err_msg: &str) -> Result<Ieee64> { fn match_ieee64(&mut self, err_msg: &str) -> ParseResult<Ieee64> {
if let Some(Token::Float(text)) = self.token() { if let Some(Token::Float(text)) = self.token() {
self.consume(); self.consume();
// Lexer just gives us raw text that looks like a float. // Lexer just gives us raw text that looks like a float.
@@ -571,7 +571,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a boolean immediate. // Match and consume a boolean immediate.
fn match_bool(&mut self, err_msg: &str) -> Result<bool> { fn match_bool(&mut self, err_msg: &str) -> ParseResult<bool> {
if let Some(Token::Identifier(text)) = self.token() { if let Some(Token::Identifier(text)) = self.token() {
self.consume(); self.consume();
match text { match text {
@@ -585,7 +585,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume an enumerated immediate, like one of the condition codes. // Match and consume an enumerated immediate, like one of the condition codes.
fn match_enum<T: FromStr>(&mut self, err_msg: &str) -> Result<T> { fn match_enum<T: FromStr>(&mut self, err_msg: &str) -> ParseResult<T> {
if let Some(Token::Identifier(text)) = self.token() { if let Some(Token::Identifier(text)) = self.token() {
self.consume(); self.consume();
text.parse().map_err(|_| self.error(err_msg)) text.parse().map_err(|_| self.error(err_msg))
@@ -608,7 +608,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume an identifier. // Match and consume an identifier.
fn match_any_identifier(&mut self, err_msg: &str) -> Result<&'a str> { fn match_any_identifier(&mut self, err_msg: &str) -> ParseResult<&'a str> {
if let Some(Token::Identifier(text)) = self.token() { if let Some(Token::Identifier(text)) = self.token() {
self.consume(); self.consume();
Ok(text) Ok(text)
@@ -619,7 +619,7 @@ impl<'a> Parser<'a> {
// Match and consume a HexSequence that fits into a u16. // Match and consume a HexSequence that fits into a u16.
// This is used for instruction encodings. // This is used for instruction encodings.
fn match_hex16(&mut self, err_msg: &str) -> Result<u16> { fn match_hex16(&mut self, err_msg: &str) -> ParseResult<u16> {
if let Some(Token::HexSequence(bits_str)) = self.token() { if let Some(Token::HexSequence(bits_str)) = self.token() {
self.consume(); self.consume();
// The only error we anticipate from this parse is overflow, the lexer should // The only error we anticipate from this parse is overflow, the lexer should
@@ -633,7 +633,7 @@ impl<'a> Parser<'a> {
} }
// Match and consume a register unit either by number `%15` or by name `%rax`. // Match and consume a register unit either by number `%15` or by name `%rax`.
fn match_regunit(&mut self, isa: Option<&TargetIsa>) -> Result<RegUnit> { fn match_regunit(&mut self, isa: Option<&TargetIsa>) -> ParseResult<RegUnit> {
if let Some(Token::Name(name)) = self.token() { if let Some(Token::Name(name)) = self.token() {
self.consume(); self.consume();
match isa { match isa {
@@ -654,7 +654,7 @@ impl<'a> Parser<'a> {
/// Parse an optional source location. /// Parse an optional source location.
/// ///
/// Return an optional source location if no real location is present. /// Return an optional source location if no real location is present.
fn optional_srcloc(&mut self) -> Result<ir::SourceLoc> { fn optional_srcloc(&mut self) -> ParseResult<ir::SourceLoc> {
if let Some(Token::SourceLoc(text)) = self.token() { if let Some(Token::SourceLoc(text)) = self.token() {
match u32::from_str_radix(text, 16) { match u32::from_str_radix(text, 16) {
Ok(num) => { Ok(num) => {
@@ -681,7 +681,7 @@ impl<'a> Parser<'a> {
/// ///
/// Accept a mix of `target` and `set` command lines. The `set` commands are cumulative. /// Accept a mix of `target` and `set` command lines. The `set` commands are cumulative.
/// ///
pub fn parse_target_specs(&mut self) -> Result<isaspec::IsaSpec> { pub fn parse_target_specs(&mut self) -> ParseResult<isaspec::IsaSpec> {
// Was there any `target` commands? // Was there any `target` commands?
let mut seen_target = false; let mut seen_target = false;
// Location of last `set` command since the last `target`. // Location of last `set` command since the last `target`.
@@ -753,14 +753,14 @@ impl<'a> Parser<'a> {
pub fn parse_function_list( pub fn parse_function_list(
&mut self, &mut self,
unique_isa: Option<&TargetIsa>, unique_isa: Option<&TargetIsa>,
) -> Result<Vec<(Function, Details<'a>)>> { ) -> ParseResult<Vec<(Function, Details<'a>)>> {
let mut list = Vec::new(); let mut list = Vec::new();
while self.token().is_some() { while self.token().is_some() {
list.push(self.parse_function(unique_isa)?); list.push(self.parse_function(unique_isa)?);
} }
if let Some(err) = self.lex_error { if let Some(err) = self.lex_error {
return match err { return match err {
lexer::Error::InvalidChar => err!(self.loc, "invalid character"), LexError::InvalidChar => err!(self.loc, "invalid character"),
}; };
} }
Ok(list) Ok(list)
@@ -773,7 +773,7 @@ impl<'a> Parser<'a> {
fn parse_function( fn parse_function(
&mut self, &mut self,
unique_isa: Option<&TargetIsa>, unique_isa: Option<&TargetIsa>,
) -> Result<(Function, Details<'a>)> { ) -> ParseResult<(Function, Details<'a>)> {
// Begin gathering comments. // Begin gathering comments.
// Make sure we don't include any comments before the `function` keyword. // Make sure we don't include any comments before the `function` keyword.
self.token(); self.token();
@@ -825,7 +825,7 @@ impl<'a> Parser<'a> {
// //
// function ::= "function" * name signature { ... } // function ::= "function" * name signature { ... }
// //
fn parse_external_name(&mut self) -> Result<ExternalName> { fn parse_external_name(&mut self) -> ParseResult<ExternalName> {
match self.token() { match self.token() {
Some(Token::Name(s)) => { Some(Token::Name(s)) => {
self.consume(); self.consume();
@@ -859,7 +859,7 @@ impl<'a> Parser<'a> {
// //
// signature ::= * "(" [paramlist] ")" ["->" retlist] [callconv] // signature ::= * "(" [paramlist] ")" ["->" retlist] [callconv]
// //
fn parse_signature(&mut self, unique_isa: Option<&TargetIsa>) -> Result<Signature> { fn parse_signature(&mut self, unique_isa: Option<&TargetIsa>) -> ParseResult<Signature> {
// Calling convention defaults to `fast`, but can be changed. // Calling convention defaults to `fast`, but can be changed.
let mut sig = Signature::new(CallConv::Fast); let mut sig = Signature::new(CallConv::Fast);
@@ -895,7 +895,10 @@ impl<'a> Parser<'a> {
// //
// paramlist ::= * param { "," param } // paramlist ::= * param { "," param }
// //
fn parse_abi_param_list(&mut self, unique_isa: Option<&TargetIsa>) -> Result<Vec<AbiParam>> { fn parse_abi_param_list(
&mut self,
unique_isa: Option<&TargetIsa>,
) -> ParseResult<Vec<AbiParam>> {
let mut list = Vec::new(); let mut list = Vec::new();
// abi-param-list ::= * abi-param { "," abi-param } // abi-param-list ::= * abi-param { "," abi-param }
@@ -911,7 +914,7 @@ impl<'a> Parser<'a> {
} }
// Parse a single argument type with flags. // Parse a single argument type with flags.
fn parse_abi_param(&mut self, unique_isa: Option<&TargetIsa>) -> Result<AbiParam> { fn parse_abi_param(&mut self, unique_isa: Option<&TargetIsa>) -> ParseResult<AbiParam> {
// abi-param ::= * type { flag } [ argumentloc ] // abi-param ::= * type { flag } [ argumentloc ]
let mut arg = AbiParam::new(self.match_type("expected parameter type")?); let mut arg = AbiParam::new(self.match_type("expected parameter type")?);
@@ -938,7 +941,10 @@ impl<'a> Parser<'a> {
} }
// Parse an argument location specifier; either a register or a byte offset into the stack. // Parse an argument location specifier; either a register or a byte offset into the stack.
fn parse_argument_location(&mut self, unique_isa: Option<&TargetIsa>) -> Result<ArgumentLoc> { fn parse_argument_location(
&mut self,
unique_isa: Option<&TargetIsa>,
) -> ParseResult<ArgumentLoc> {
// argumentloc ::= '[' regname | uimm32 ']' // argumentloc ::= '[' regname | uimm32 ']'
if self.optional(Token::LBracket) { if self.optional(Token::LBracket) {
let result = match self.token() { let result = match self.token() {
@@ -985,7 +991,7 @@ impl<'a> Parser<'a> {
// * stack-limit-decl // * stack-limit-decl
// //
// The parsed decls are added to `ctx` rather than returned. // The parsed decls are added to `ctx` rather than returned.
fn parse_preamble(&mut self, ctx: &mut Context) -> Result<()> { fn parse_preamble(&mut self, ctx: &mut Context) -> ParseResult<()> {
loop { loop {
match self.token() { match self.token() {
Some(Token::StackSlot(..)) => { Some(Token::StackSlot(..)) => {
@@ -1034,7 +1040,7 @@ impl<'a> Parser<'a> {
// | "spill_slot" // | "spill_slot"
// | "incoming_arg" // | "incoming_arg"
// | "outgoing_arg" // | "outgoing_arg"
fn parse_stack_slot_decl(&mut self) -> Result<(StackSlot, StackSlotData)> { fn parse_stack_slot_decl(&mut self) -> ParseResult<(StackSlot, StackSlotData)> {
let ss = self.match_ss("expected stack slot number: ss«n»")?; let ss = self.match_ss("expected stack slot number: ss«n»")?;
self.match_token(Token::Equal, "expected '=' in stack slot declaration")?; self.match_token(Token::Equal, "expected '=' in stack slot declaration")?;
let kind = self.match_enum("expected stack slot kind")?; let kind = self.match_enum("expected stack slot kind")?;
@@ -1073,7 +1079,7 @@ impl<'a> Parser<'a> {
// | "deref" "(" GlobalVar(base) ")" offset32 // | "deref" "(" GlobalVar(base) ")" offset32
// | globalsym ["colocated"] name // | globalsym ["colocated"] name
// //
fn parse_global_var_decl(&mut self) -> Result<(GlobalVar, GlobalVarData)> { fn parse_global_var_decl(&mut self) -> ParseResult<(GlobalVar, GlobalVarData)> {
let gv = self.match_gv("expected global variable number: gv«n»")?; let gv = self.match_gv("expected global variable number: gv«n»")?;
self.match_token(Token::Equal, "expected '=' in global variable declaration")?; self.match_token(Token::Equal, "expected '=' in global variable declaration")?;
@@ -1116,7 +1122,7 @@ impl<'a> Parser<'a> {
// | "max" Imm64(bytes) // | "max" Imm64(bytes)
// | "guard" Imm64(bytes) // | "guard" Imm64(bytes)
// //
fn parse_heap_decl(&mut self) -> Result<(Heap, HeapData)> { fn parse_heap_decl(&mut self) -> ParseResult<(Heap, HeapData)> {
let heap = self.match_heap("expected heap number: heap«n»")?; let heap = self.match_heap("expected heap number: heap«n»")?;
self.match_token(Token::Equal, "expected '=' in heap declaration")?; self.match_token(Token::Equal, "expected '=' in heap declaration")?;
@@ -1183,7 +1189,7 @@ impl<'a> Parser<'a> {
fn parse_signature_decl( fn parse_signature_decl(
&mut self, &mut self,
unique_isa: Option<&TargetIsa>, unique_isa: Option<&TargetIsa>,
) -> Result<(SigRef, Signature)> { ) -> ParseResult<(SigRef, Signature)> {
let sig = self.match_sig("expected signature number: sig«n»")?; let sig = self.match_sig("expected signature number: sig«n»")?;
self.match_token(Token::Equal, "expected '=' in signature decl")?; self.match_token(Token::Equal, "expected '=' in signature decl")?;
let data = self.parse_signature(unique_isa)?; let data = self.parse_signature(unique_isa)?;
@@ -1205,7 +1211,7 @@ impl<'a> Parser<'a> {
// The first variant allocates a new signature reference. The second references an existing // The first variant allocates a new signature reference. The second references an existing
// signature which must be declared first. // signature which must be declared first.
// //
fn parse_function_decl(&mut self, ctx: &mut Context) -> Result<(FuncRef, ExtFuncData)> { fn parse_function_decl(&mut self, ctx: &mut Context) -> ParseResult<(FuncRef, ExtFuncData)> {
let fn_ = self.match_fn("expected function number: fn«n»")?; let fn_ = self.match_fn("expected function number: fn«n»")?;
self.match_token(Token::Equal, "expected '=' in function decl")?; self.match_token(Token::Equal, "expected '=' in function decl")?;
@@ -1260,7 +1266,7 @@ impl<'a> Parser<'a> {
// Parse a jump table decl. // Parse a jump table decl.
// //
// jump-table-decl ::= * JumpTable(jt) "=" "jump_table" jt-entry {"," jt-entry} // jump-table-decl ::= * JumpTable(jt) "=" "jump_table" jt-entry {"," jt-entry}
fn parse_jump_table_decl(&mut self) -> Result<(JumpTable, JumpTableData)> { fn parse_jump_table_decl(&mut self) -> ParseResult<(JumpTable, JumpTableData)> {
let jt = self.match_jt()?; let jt = self.match_jt()?;
self.match_token(Token::Equal, "expected '=' in jump_table decl")?; self.match_token(Token::Equal, "expected '=' in jump_table decl")?;
self.match_identifier("jump_table", "expected 'jump_table'")?; self.match_identifier("jump_table", "expected 'jump_table'")?;
@@ -1285,7 +1291,7 @@ impl<'a> Parser<'a> {
} }
// jt-entry ::= * Ebb(dest) | "0" // jt-entry ::= * Ebb(dest) | "0"
fn parse_jump_table_entry(&mut self) -> Result<Option<Ebb>> { fn parse_jump_table_entry(&mut self) -> ParseResult<Option<Ebb>> {
match self.token() { match self.token() {
Some(Token::Integer(s)) => { Some(Token::Integer(s)) => {
if s == "0" { if s == "0" {
@@ -1304,7 +1310,7 @@ impl<'a> Parser<'a> {
} }
/// stack-limit-decl ::= "stack_limit" "=" GlobalVar(gv) /// stack-limit-decl ::= "stack_limit" "=" GlobalVar(gv)
fn parse_stack_limit_decl(&mut self) -> Result<GlobalVar> { fn parse_stack_limit_decl(&mut self) -> ParseResult<GlobalVar> {
self.consume(); self.consume();
self.match_token(Token::Equal, "expected '=' in stack limit declaration")?; self.match_token(Token::Equal, "expected '=' in stack limit declaration")?;
let gv = self.match_gv("expected global variable")?; let gv = self.match_gv("expected global variable")?;
@@ -1316,7 +1322,7 @@ impl<'a> Parser<'a> {
// //
// function-body ::= * { extended-basic-block } // function-body ::= * { extended-basic-block }
// //
fn parse_function_body(&mut self, ctx: &mut Context) -> Result<()> { fn parse_function_body(&mut self, ctx: &mut Context) -> ParseResult<()> {
while self.token() != Some(Token::RBrace) { while self.token() != Some(Token::RBrace) {
self.parse_extended_basic_block(ctx)?; self.parse_extended_basic_block(ctx)?;
} }
@@ -1352,7 +1358,7 @@ impl<'a> Parser<'a> {
// extended-basic-block ::= * ebb-header { instruction } // extended-basic-block ::= * ebb-header { instruction }
// ebb-header ::= Ebb(ebb) [ebb-params] ":" // ebb-header ::= Ebb(ebb) [ebb-params] ":"
// //
fn parse_extended_basic_block(&mut self, ctx: &mut Context) -> Result<()> { fn parse_extended_basic_block(&mut self, ctx: &mut Context) -> ParseResult<()> {
// Collect comments for the next ebb. // Collect comments for the next ebb.
self.start_gathering_comments(); self.start_gathering_comments();
@@ -1415,7 +1421,7 @@ impl<'a> Parser<'a> {
// value numbers of the defined values and the defined types. // value numbers of the defined values and the defined types.
// //
// ebb-params ::= * "(" ebb-param { "," ebb-param } ")" // ebb-params ::= * "(" ebb-param { "," ebb-param } ")"
fn parse_ebb_params(&mut self, ctx: &mut Context, ebb: Ebb) -> Result<()> { fn parse_ebb_params(&mut self, ctx: &mut Context, ebb: Ebb) -> ParseResult<()> {
// ebb-params ::= * "(" ebb-param { "," ebb-param } ")" // ebb-params ::= * "(" ebb-param { "," ebb-param } ")"
self.match_token(Token::LPar, "expected '(' before EBB parameters")?; self.match_token(Token::LPar, "expected '(' before EBB parameters")?;
@@ -1439,7 +1445,7 @@ impl<'a> Parser<'a> {
// ebb-param ::= * Value(v) ":" Type(t) arg-loc? // ebb-param ::= * Value(v) ":" Type(t) arg-loc?
// arg-loc ::= "[" value-location "]" // arg-loc ::= "[" value-location "]"
// //
fn parse_ebb_param(&mut self, ctx: &mut Context, ebb: Ebb) -> Result<()> { fn parse_ebb_param(&mut self, ctx: &mut Context, ebb: Ebb) -> ParseResult<()> {
// ebb-param ::= * Value(v) ":" Type(t) arg-loc? // ebb-param ::= * Value(v) ":" Type(t) arg-loc?
let v = self.match_value("EBB argument must be a value")?; let v = self.match_value("EBB argument must be a value")?;
let v_location = self.loc; let v_location = self.loc;
@@ -1466,7 +1472,7 @@ impl<'a> Parser<'a> {
Ok(()) Ok(())
} }
fn parse_value_location(&mut self, ctx: &Context) -> Result<ValueLoc> { fn parse_value_location(&mut self, ctx: &Context) -> ParseResult<ValueLoc> {
match self.token() { match self.token() {
Some(Token::StackSlot(src_num)) => { Some(Token::StackSlot(src_num)) => {
self.consume(); self.consume();
@@ -1505,7 +1511,7 @@ impl<'a> Parser<'a> {
fn parse_instruction_encoding( fn parse_instruction_encoding(
&mut self, &mut self,
ctx: &Context, ctx: &Context,
) -> Result<(Option<Encoding>, Option<Vec<ValueLoc>>)> { ) -> ParseResult<(Option<Encoding>, Option<Vec<ValueLoc>>)> {
let (mut encoding, mut result_locations) = (None, None); let (mut encoding, mut result_locations) = (None, None);
// encoding ::= "[" encoding_literal result_locations "]" // encoding ::= "[" encoding_literal result_locations "]"
@@ -1551,7 +1557,7 @@ impl<'a> Parser<'a> {
// //
// inst-results ::= Value(v) { "," Value(v) } // inst-results ::= Value(v) { "," Value(v) }
// //
fn parse_inst_results(&mut self) -> Result<Vec<Value>> { fn parse_inst_results(&mut self) -> ParseResult<Vec<Value>> {
// Result value numbers. // Result value numbers.
let mut results = Vec::new(); let mut results = Vec::new();
@@ -1576,7 +1582,7 @@ impl<'a> Parser<'a> {
// //
// value_alias ::= [inst-results] "->" Value(v) // value_alias ::= [inst-results] "->" Value(v)
// //
fn parse_value_alias(&mut self, results: &[Value], ctx: &mut Context) -> Result<()> { fn parse_value_alias(&mut self, results: &[Value], ctx: &mut Context) -> ParseResult<()> {
if results.len() != 1 { if results.len() != 1 {
return err!(self.loc, "wrong number of aliases"); return err!(self.loc, "wrong number of aliases");
} }
@@ -1623,7 +1629,7 @@ impl<'a> Parser<'a> {
result_locations: Option<Vec<ValueLoc>>, result_locations: Option<Vec<ValueLoc>>,
ctx: &mut Context, ctx: &mut Context,
ebb: Ebb, ebb: Ebb,
) -> Result<()> { ) -> ParseResult<()> {
// Define the result values. // Define the result values.
for val in results { for val in results {
ctx.map.def_value(*val, &self.loc)?; ctx.map.def_value(*val, &self.loc)?;
@@ -1731,7 +1737,7 @@ impl<'a> Parser<'a> {
opcode: Opcode, opcode: Opcode,
explicit_ctrl_type: Option<Type>, explicit_ctrl_type: Option<Type>,
inst_data: &InstructionData, inst_data: &InstructionData,
) -> Result<Type> { ) -> ParseResult<Type> {
let constraints = opcode.constraints(); let constraints = opcode.constraints();
let ctrl_type = match explicit_ctrl_type { let ctrl_type = match explicit_ctrl_type {
Some(t) => t, Some(t) => t,
@@ -1808,7 +1814,7 @@ impl<'a> Parser<'a> {
// //
// value_list ::= [ value { "," value } ] // value_list ::= [ value { "," value } ]
// //
fn parse_value_list(&mut self) -> Result<VariableArgs> { fn parse_value_list(&mut self) -> ParseResult<VariableArgs> {
let mut args = VariableArgs::new(); let mut args = VariableArgs::new();
if let Some(Token::Value(v)) = self.token() { if let Some(Token::Value(v)) = self.token() {
@@ -1825,7 +1831,7 @@ impl<'a> Parser<'a> {
Ok(args) Ok(args)
} }
fn parse_value_sequence(&mut self) -> Result<VariableArgs> { fn parse_value_sequence(&mut self) -> ParseResult<VariableArgs> {
let mut args = VariableArgs::new(); let mut args = VariableArgs::new();
if let Some(Token::Value(v)) = self.token() { if let Some(Token::Value(v)) = self.token() {
@@ -1843,7 +1849,7 @@ impl<'a> Parser<'a> {
} }
// Parse an optional value list enclosed in parantheses. // Parse an optional value list enclosed in parantheses.
fn parse_opt_value_list(&mut self) -> Result<VariableArgs> { fn parse_opt_value_list(&mut self) -> ParseResult<VariableArgs> {
if !self.optional(Token::LPar) { if !self.optional(Token::LPar) {
return Ok(VariableArgs::new()); return Ok(VariableArgs::new());
} }
@@ -1861,7 +1867,7 @@ impl<'a> Parser<'a> {
&mut self, &mut self,
ctx: &mut Context, ctx: &mut Context,
opcode: Opcode, opcode: Opcode,
) -> Result<InstructionData> { ) -> ParseResult<InstructionData> {
let idata = match opcode.format() { let idata = match opcode.format() {
InstructionFormat::Unary => InstructionData::Unary { InstructionFormat::Unary => InstructionData::Unary {
opcode, opcode,
@@ -2289,7 +2295,7 @@ mod tests {
use cretonne_codegen::ir::StackSlotKind; use cretonne_codegen::ir::StackSlotKind;
use cretonne_codegen::ir::{ArgumentExtension, ArgumentPurpose}; use cretonne_codegen::ir::{ArgumentExtension, ArgumentPurpose};
use cretonne_codegen::settings::CallConv; use cretonne_codegen::settings::CallConv;
use error::Error; use error::ParseError;
use isaspec::IsaSpec; use isaspec::IsaSpec;
use testfile::{Comment, Details}; use testfile::{Comment, Details};
@@ -2300,7 +2306,7 @@ mod tests {
assert_eq!(arg.value_type, types::I32); assert_eq!(arg.value_type, types::I32);
assert_eq!(arg.extension, ArgumentExtension::Sext); assert_eq!(arg.extension, ArgumentExtension::Sext);
assert_eq!(arg.purpose, ArgumentPurpose::Normal); assert_eq!(arg.purpose, ArgumentPurpose::Normal);
let Error { location, message } = p.parse_abi_param(None).unwrap_err(); let ParseError { location, message } = p.parse_abi_param(None).unwrap_err();
assert_eq!(location.line_number, 1); assert_eq!(location.line_number, 1);
assert_eq!(message, "expected parameter type"); assert_eq!(message, "expected parameter type");
} }

View File

@@ -8,7 +8,7 @@
use cretonne_codegen::ir::entities::AnyEntity; use cretonne_codegen::ir::entities::AnyEntity;
use cretonne_codegen::ir::{Ebb, FuncRef, GlobalVar, Heap, JumpTable, SigRef, StackSlot, Value}; use cretonne_codegen::ir::{Ebb, FuncRef, GlobalVar, Heap, JumpTable, SigRef, StackSlot, Value};
use error::{Location, Result}; use error::{Location, ParseResult};
use lexer::split_entity_name; use lexer::split_entity_name;
use std::collections::HashMap; use std::collections::HashMap;
@@ -140,48 +140,48 @@ impl SourceMap {
} }
/// Define the value `entity`. /// Define the value `entity`.
pub fn def_value(&mut self, entity: Value, loc: &Location) -> Result<()> { pub fn def_value(&mut self, entity: Value, loc: &Location) -> ParseResult<()> {
self.def_entity(entity.into(), loc) self.def_entity(entity.into(), loc)
} }
/// Define the ebb `entity`. /// Define the ebb `entity`.
pub fn def_ebb(&mut self, entity: Ebb, loc: &Location) -> Result<()> { pub fn def_ebb(&mut self, entity: Ebb, loc: &Location) -> ParseResult<()> {
self.def_entity(entity.into(), loc) self.def_entity(entity.into(), loc)
} }
/// Define the stack slot `entity`. /// Define the stack slot `entity`.
pub fn def_ss(&mut self, entity: StackSlot, loc: &Location) -> Result<()> { pub fn def_ss(&mut self, entity: StackSlot, loc: &Location) -> ParseResult<()> {
self.def_entity(entity.into(), loc) self.def_entity(entity.into(), loc)
} }
/// Define the global variable `entity`. /// Define the global variable `entity`.
pub fn def_gv(&mut self, entity: GlobalVar, loc: &Location) -> Result<()> { pub fn def_gv(&mut self, entity: GlobalVar, loc: &Location) -> ParseResult<()> {
self.def_entity(entity.into(), loc) self.def_entity(entity.into(), loc)
} }
/// Define the heap `entity`. /// Define the heap `entity`.
pub fn def_heap(&mut self, entity: Heap, loc: &Location) -> Result<()> { pub fn def_heap(&mut self, entity: Heap, loc: &Location) -> ParseResult<()> {
self.def_entity(entity.into(), loc) self.def_entity(entity.into(), loc)
} }
/// Define the signature `entity`. /// Define the signature `entity`.
pub fn def_sig(&mut self, entity: SigRef, loc: &Location) -> Result<()> { pub fn def_sig(&mut self, entity: SigRef, loc: &Location) -> ParseResult<()> {
self.def_entity(entity.into(), loc) self.def_entity(entity.into(), loc)
} }
/// Define the external function `entity`. /// Define the external function `entity`.
pub fn def_fn(&mut self, entity: FuncRef, loc: &Location) -> Result<()> { pub fn def_fn(&mut self, entity: FuncRef, loc: &Location) -> ParseResult<()> {
self.def_entity(entity.into(), loc) self.def_entity(entity.into(), loc)
} }
/// Define the jump table `entity`. /// Define the jump table `entity`.
pub fn def_jt(&mut self, entity: JumpTable, loc: &Location) -> Result<()> { pub fn def_jt(&mut self, entity: JumpTable, loc: &Location) -> ParseResult<()> {
self.def_entity(entity.into(), loc) self.def_entity(entity.into(), loc)
} }
/// Define an entity. This can be used for instructions whose numbers never /// Define an entity. This can be used for instructions whose numbers never
/// appear in source, or implicitly defined signatures. /// appear in source, or implicitly defined signatures.
pub fn def_entity(&mut self, entity: AnyEntity, loc: &Location) -> Result<()> { pub fn def_entity(&mut self, entity: AnyEntity, loc: &Location) -> ParseResult<()> {
if self.locations.insert(entity, *loc).is_some() { if self.locations.insert(entity, *loc).is_some() {
err!(loc, "duplicate entity: {}", entity) err!(loc, "duplicate entity: {}", entity)
} else { } else {

View File

@@ -47,7 +47,7 @@ fn return_at_end() {
handle_module(Path::new("../../wasmtests/return_at_end.wat"), &flags); handle_module(Path::new("../../wasmtests/return_at_end.wat"), &flags);
} }
fn read_file(path: &Path) -> Result<Vec<u8>, io::Error> { fn read_file(path: &Path) -> io::Result<Vec<u8>> {
let mut buf: Vec<u8> = Vec::new(); let mut buf: Vec<u8> = Vec::new();
let mut file = File::open(path)?; let mut file = File::open(path)?;
file.read_to_end(&mut buf)?; file.read_to_end(&mut buf)?;