//! Functions for parsing and evaluating DWARF expressions.

#[cfg(feature = "read")]
use alloc::vec::Vec;
use core::mem;

use super::util::{ArrayLike, ArrayVec};
use crate::common::{DebugAddrIndex, DebugInfoOffset, Encoding, Register};
use crate::constants;
use crate::read::{Error, Reader, ReaderOffset, Result, StoreOnHeap, UnitOffset, Value, ValueType};

/// A reference to a DIE, either relative to the current CU or
/// relative to the section.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DieReference<T = usize> {
    /// A CU-relative reference.
    UnitRef(UnitOffset<T>),
    /// A section-relative reference.
    DebugInfoRef(DebugInfoOffset<T>),
}

/// A single decoded DWARF expression operation.
///
/// DWARF expression evaluation is done in two parts: first the raw
/// bytes of the next part of the expression are decoded; and then the
/// decoded operation is evaluated.  This approach lets other
/// consumers inspect the DWARF expression without reimplementing the
/// decoding operation.
///
/// Multiple DWARF opcodes may decode into a single `Operation`.  For
/// example, both `DW_OP_deref` and `DW_OP_xderef` are represented
/// using `Operation::Deref`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Operation<R, Offset = <R as Reader>::Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    /// Dereference the topmost value of the stack.
    Deref {
        /// The DIE of the base type or 0 to indicate the generic type
        base_type: UnitOffset<Offset>,
        /// The size of the data to dereference.
        size: u8,
        /// True if the dereference operation takes an address space
        /// argument from the stack; false otherwise.
        space: bool,
    },
    /// Drop an item from the stack.
    Drop,
    /// Pick an item from the stack and push it on top of the stack.
    /// This operation handles `DW_OP_pick`, `DW_OP_dup`, and
    /// `DW_OP_over`.
    Pick {
        /// The index, from the top of the stack, of the item to copy.
        index: u8,
    },
    /// Swap the top two stack items.
    Swap,
    /// Rotate the top three stack items.
    Rot,
    /// Take the absolute value of the top of the stack.
    Abs,
    /// Bitwise `and` of the top two values on the stack.
    And,
    /// Divide the top two values on the stack.
    Div,
    /// Subtract the top two values on the stack.
    Minus,
    /// Modulus of the top two values on the stack.
    Mod,
    /// Multiply the top two values on the stack.
    Mul,
    /// Negate the top of the stack.
    Neg,
    /// Bitwise `not` of the top of the stack.
    Not,
    /// Bitwise `or` of the top two values on the stack.
    Or,
    /// Add the top two values on the stack.
    Plus,
    /// Add a constant to the topmost value on the stack.
    PlusConstant {
        /// The value to add.
        value: u64,
    },
    /// Logical left shift of the 2nd value on the stack by the number
    /// of bits given by the topmost value on the stack.
    Shl,
    /// Right shift of the 2nd value on the stack by the number of
    /// bits given by the topmost value on the stack.
    Shr,
    /// Arithmetic left shift of the 2nd value on the stack by the
    /// number of bits given by the topmost value on the stack.
    Shra,
    /// Bitwise `xor` of the top two values on the stack.
    Xor,
    /// Branch to the target location if the top of stack is nonzero.
    Bra {
        /// The relative offset to the target bytecode.
        target: i16,
    },
    /// Compare the top two stack values for equality.
    Eq,
    /// Compare the top two stack values using `>=`.
    Ge,
    /// Compare the top two stack values using `>`.
    Gt,
    /// Compare the top two stack values using `<=`.
    Le,
    /// Compare the top two stack values using `<`.
    Lt,
    /// Compare the top two stack values using `!=`.
    Ne,
    /// Unconditional branch to the target location.
    Skip {
        /// The relative offset to the target bytecode.
        target: i16,
    },
    /// Push an unsigned constant value on the stack.  This handles multiple
    /// DWARF opcodes.
    UnsignedConstant {
        /// The value to push.
        value: u64,
    },
    /// Push a signed constant value on the stack.  This handles multiple
    /// DWARF opcodes.
    SignedConstant {
        /// The value to push.
        value: i64,
    },
    /// Indicate that this piece's location is in the given register.
    ///
    /// Completes the piece or expression.
    Register {
        /// The register number.
        register: Register,
    },
    /// Find the value of the given register, add the offset, and then
    /// push the resulting sum on the stack.
    RegisterOffset {
        /// The register number.
        register: Register,
        /// The offset to add.
        offset: i64,
        /// The DIE of the base type or 0 to indicate the generic type
        base_type: UnitOffset<Offset>,
    },
    /// Compute the frame base (using `DW_AT_frame_base`), add the
    /// given offset, and then push the resulting sum on the stack.
    FrameOffset {
        /// The offset to add.
        offset: i64,
    },
    /// No operation.
    Nop,
    /// Push the object address on the stack.
    PushObjectAddress,
    /// Evaluate a DWARF expression as a subroutine.  The expression
    /// comes from the `DW_AT_location` attribute of the indicated
    /// DIE.
    Call {
        /// The DIE to use.
        offset: DieReference<Offset>,
    },
    /// Compute the address of a thread-local variable and push it on
    /// the stack.
    TLS,
    /// Compute the call frame CFA and push it on the stack.
    CallFrameCFA,
    /// Terminate a piece.
    Piece {
        /// The size of this piece in bits.
        size_in_bits: u64,
        /// The bit offset of this piece.  If `None`, then this piece
        /// was specified using `DW_OP_piece` and should start at the
        /// next byte boundary.
        bit_offset: Option<u64>,
    },
    /// The object has no location, but has a known constant value.
    ///
    /// Represents `DW_OP_implicit_value`.
    /// Completes the piece or expression.
    ImplicitValue {
        /// The implicit value to use.
        data: R,
    },
    /// The object has no location, but its value is at the top of the stack.
    ///
    /// Represents `DW_OP_stack_value`.
    /// Completes the piece or expression.
    StackValue,
    /// The object is a pointer to a value which has no actual location,
    /// such as an implicit value or a stack value.
    ///
    /// Represents `DW_OP_implicit_pointer`.
    /// Completes the piece or expression.
    ImplicitPointer {
        /// The `.debug_info` offset of the value that this is an implicit pointer into.
        value: DebugInfoOffset<Offset>,
        /// The byte offset into the value that the implicit pointer points to.
        byte_offset: i64,
    },
    /// Evaluate an expression at the entry to the current subprogram, and push it on the stack.
    ///
    /// Represents `DW_OP_entry_value`.
    EntryValue {
        /// The expression to be evaluated.
        expression: R,
    },
    /// This represents a parameter that was optimized out.
    ///
    /// The offset points to the definition of the parameter, and is
    /// matched to the `DW_TAG_GNU_call_site_parameter` in the caller that also
    /// points to the same definition of the parameter.
    ///
    /// Represents `DW_OP_GNU_parameter_ref`.
    ParameterRef {
        /// The DIE to use.
        offset: UnitOffset<Offset>,
    },
    /// Relocate the address if needed, and push it on the stack.
    ///
    /// Represents `DW_OP_addr`.
    Address {
        /// The offset to add.
        address: u64,
    },
    /// Read the address at the given index in `.debug_addr, relocate the address if needed,
    /// and push it on the stack.
    ///
    /// Represents `DW_OP_addrx`.
    AddressIndex {
        /// The index of the address in `.debug_addr`.
        index: DebugAddrIndex<Offset>,
    },
    /// Read the address at the given index in `.debug_addr, and push it on the stack.
    /// Do not relocate the address.
    ///
    /// Represents `DW_OP_constx`.
    ConstantIndex {
        /// The index of the address in `.debug_addr`.
        index: DebugAddrIndex<Offset>,
    },
    /// Interpret the value bytes as a constant of a given type, and push it on the stack.
    ///
    /// Represents `DW_OP_const_type`.
    TypedLiteral {
        /// The DIE of the base type.
        base_type: UnitOffset<Offset>,
        /// The value bytes.
        value: R,
    },
    /// Pop the top stack entry, convert it to a different type, and push it on the stack.
    ///
    /// Represents `DW_OP_convert`.
    Convert {
        /// The DIE of the base type.
        base_type: UnitOffset<Offset>,
    },
    /// Pop the top stack entry, reinterpret the bits in its value as a different type,
    /// and push it on the stack.
    ///
    /// Represents `DW_OP_reinterpret`.
    Reinterpret {
        /// The DIE of the base type.
        base_type: UnitOffset<Offset>,
    },
    /// The index of a local in the currently executing function.
    ///
    /// Represents `DW_OP_WASM_location 0x00`.
    /// Completes the piece or expression.
    WasmLocal {
        /// The index of the local.
        index: u32,
    },
    /// The index of a global.
    ///
    /// Represents `DW_OP_WASM_location 0x01` or `DW_OP_WASM_location 0x03`.
    /// Completes the piece or expression.
    WasmGlobal {
        /// The index of the global.
        index: u32,
    },
    /// The index of an item on the operand stack.
    ///
    /// Represents `DW_OP_WASM_location 0x02`.
    /// Completes the piece or expression.
    WasmStack {
        /// The index of the stack item. 0 is the bottom of the operand stack.
        index: u32,
    },
}

#[derive(Debug)]
enum OperationEvaluationResult<R: Reader> {
    Piece,
    Incomplete,
    Complete { location: Location<R> },
    Waiting(EvaluationWaiting<R>, EvaluationResult<R>),
}

/// A single location of a piece of the result of a DWARF expression.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Location<R, Offset = <R as Reader>::Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    /// The piece is empty.  Ordinarily this means the piece has been
    /// optimized away.
    Empty,
    /// The piece is found in a register.
    Register {
        /// The register number.
        register: Register,
    },
    /// The piece is found in memory.
    Address {
        /// The address.
        address: u64,
    },
    /// The piece has no location but its value is known.
    Value {
        /// The value.
        value: Value,
    },
    /// The piece is represented by some constant bytes.
    Bytes {
        /// The value.
        value: R,
    },
    /// The piece is a pointer to a value which has no actual location.
    ImplicitPointer {
        /// The `.debug_info` offset of the value that this is an implicit pointer into.
        value: DebugInfoOffset<Offset>,
        /// The byte offset into the value that the implicit pointer points to.
        byte_offset: i64,
    },
}

impl<R, Offset> Location<R, Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    /// Return true if the piece is empty.
    pub fn is_empty(&self) -> bool {
        matches!(*self, Location::Empty)
    }
}

/// The description of a single piece of the result of a DWARF
/// expression.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Piece<R, Offset = <R as Reader>::Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    /// If given, the size of the piece in bits.  If `None`, there
    /// must be only one piece whose size is all of the object.
    pub size_in_bits: Option<u64>,
    /// If given, the bit offset of the piece within the location.
    /// If the location is a `Location::Register` or `Location::Value`,
    /// then this offset is from the least significant bit end of
    /// the register or value.
    /// If the location is a `Location::Address` then the offset uses
    /// the bit numbering and direction conventions of the language
    /// and target system.
    ///
    /// If `None`, the piece starts at the location. If the
    /// location is a register whose size is larger than the piece,
    /// then placement within the register is defined by the ABI.
    pub bit_offset: Option<u64>,
    /// Where this piece is to be found.
    pub location: Location<R, Offset>,
}

// A helper function to handle branch offsets.
fn compute_pc<R: Reader>(pc: &R, bytecode: &R, offset: i16) -> Result<R> {
    let pc_offset = pc.offset_from(bytecode);
    let new_pc_offset = pc_offset.wrapping_add(R::Offset::from_i16(offset));
    if new_pc_offset > bytecode.len() {
        Err(Error::BadBranchTarget(new_pc_offset.into_u64()))
    } else {
        let mut new_pc = bytecode.clone();
        new_pc.skip(new_pc_offset)?;
        Ok(new_pc)
    }
}

fn generic_type<O: ReaderOffset>() -> UnitOffset<O> {
    UnitOffset(O::from_u64(0).unwrap())
}

impl<R, Offset> Operation<R, Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    /// Parse a single DWARF expression operation.
    ///
    /// This is useful when examining a DWARF expression for reasons other
    /// than direct evaluation.
    ///
    /// `bytes` points to a the operation to decode.  It should point into
    /// the same array as `bytecode`, which should be the entire
    /// expression.
    pub fn parse(bytes: &mut R, encoding: Encoding) -> Result<Operation<R, Offset>> {
        let opcode = bytes.read_u8()?;
        let name = constants::DwOp(opcode);
        match name {
            constants::DW_OP_addr => {
                let address = bytes.read_address(encoding.address_size)?;
                Ok(Operation::Address { address })
            }
            constants::DW_OP_deref => Ok(Operation::Deref {
                base_type: generic_type(),
                size: encoding.address_size,
                space: false,
            }),
            constants::DW_OP_const1u => {
                let value = bytes.read_u8()?;
                Ok(Operation::UnsignedConstant {
                    value: u64::from(value),
                })
            }
            constants::DW_OP_const1s => {
                let value = bytes.read_i8()?;
                Ok(Operation::SignedConstant {
                    value: i64::from(value),
                })
            }
            constants::DW_OP_const2u => {
                let value = bytes.read_u16()?;
                Ok(Operation::UnsignedConstant {
                    value: u64::from(value),
                })
            }
            constants::DW_OP_const2s => {
                let value = bytes.read_i16()?;
                Ok(Operation::SignedConstant {
                    value: i64::from(value),
                })
            }
            constants::DW_OP_const4u => {
                let value = bytes.read_u32()?;
                Ok(Operation::UnsignedConstant {
                    value: u64::from(value),
                })
            }
            constants::DW_OP_const4s => {
                let value = bytes.read_i32()?;
                Ok(Operation::SignedConstant {
                    value: i64::from(value),
                })
            }
            constants::DW_OP_const8u => {
                let value = bytes.read_u64()?;
                Ok(Operation::UnsignedConstant { value })
            }
            constants::DW_OP_const8s => {
                let value = bytes.read_i64()?;
                Ok(Operation::SignedConstant { value })
            }
            constants::DW_OP_constu => {
                let value = bytes.read_uleb128()?;
                Ok(Operation::UnsignedConstant { value })
            }
            constants::DW_OP_consts => {
                let value = bytes.read_sleb128()?;
                Ok(Operation::SignedConstant { value })
            }
            constants::DW_OP_dup => Ok(Operation::Pick { index: 0 }),
            constants::DW_OP_drop => Ok(Operation::Drop),
            constants::DW_OP_over => Ok(Operation::Pick { index: 1 }),
            constants::DW_OP_pick => {
                let value = bytes.read_u8()?;
                Ok(Operation::Pick { index: value })
            }
            constants::DW_OP_swap => Ok(Operation::Swap),
            constants::DW_OP_rot => Ok(Operation::Rot),
            constants::DW_OP_xderef => Ok(Operation::Deref {
                base_type: generic_type(),
                size: encoding.address_size,
                space: true,
            }),
            constants::DW_OP_abs => Ok(Operation::Abs),
            constants::DW_OP_and => Ok(Operation::And),
            constants::DW_OP_div => Ok(Operation::Div),
            constants::DW_OP_minus => Ok(Operation::Minus),
            constants::DW_OP_mod => Ok(Operation::Mod),
            constants::DW_OP_mul => Ok(Operation::Mul),
            constants::DW_OP_neg => Ok(Operation::Neg),
            constants::DW_OP_not => Ok(Operation::Not),
            constants::DW_OP_or => Ok(Operation::Or),
            constants::DW_OP_plus => Ok(Operation::Plus),
            constants::DW_OP_plus_uconst => {
                let value = bytes.read_uleb128()?;
                Ok(Operation::PlusConstant { value })
            }
            constants::DW_OP_shl => Ok(Operation::Shl),
            constants::DW_OP_shr => Ok(Operation::Shr),
            constants::DW_OP_shra => Ok(Operation::Shra),
            constants::DW_OP_xor => Ok(Operation::Xor),
            constants::DW_OP_bra => {
                let target = bytes.read_i16()?;
                Ok(Operation::Bra { target })
            }
            constants::DW_OP_eq => Ok(Operation::Eq),
            constants::DW_OP_ge => Ok(Operation::Ge),
            constants::DW_OP_gt => Ok(Operation::Gt),
            constants::DW_OP_le => Ok(Operation::Le),
            constants::DW_OP_lt => Ok(Operation::Lt),
            constants::DW_OP_ne => Ok(Operation::Ne),
            constants::DW_OP_skip => {
                let target = bytes.read_i16()?;
                Ok(Operation::Skip { target })
            }
            constants::DW_OP_lit0
            | constants::DW_OP_lit1
            | constants::DW_OP_lit2
            | constants::DW_OP_lit3
            | constants::DW_OP_lit4
            | constants::DW_OP_lit5
            | constants::DW_OP_lit6
            | constants::DW_OP_lit7
            | constants::DW_OP_lit8
            | constants::DW_OP_lit9
            | constants::DW_OP_lit10
            | constants::DW_OP_lit11
            | constants::DW_OP_lit12
            | constants::DW_OP_lit13
            | constants::DW_OP_lit14
            | constants::DW_OP_lit15
            | constants::DW_OP_lit16
            | constants::DW_OP_lit17
            | constants::DW_OP_lit18
            | constants::DW_OP_lit19
            | constants::DW_OP_lit20
            | constants::DW_OP_lit21
            | constants::DW_OP_lit22
            | constants::DW_OP_lit23
            | constants::DW_OP_lit24
            | constants::DW_OP_lit25
            | constants::DW_OP_lit26
            | constants::DW_OP_lit27
            | constants::DW_OP_lit28
            | constants::DW_OP_lit29
            | constants::DW_OP_lit30
            | constants::DW_OP_lit31 => Ok(Operation::UnsignedConstant {
                value: (opcode - constants::DW_OP_lit0.0).into(),
            }),
            constants::DW_OP_reg0
            | constants::DW_OP_reg1
            | constants::DW_OP_reg2
            | constants::DW_OP_reg3
            | constants::DW_OP_reg4
            | constants::DW_OP_reg5
            | constants::DW_OP_reg6
            | constants::DW_OP_reg7
            | constants::DW_OP_reg8
            | constants::DW_OP_reg9
            | constants::DW_OP_reg10
            | constants::DW_OP_reg11
            | constants::DW_OP_reg12
            | constants::DW_OP_reg13
            | constants::DW_OP_reg14
            | constants::DW_OP_reg15
            | constants::DW_OP_reg16
            | constants::DW_OP_reg17
            | constants::DW_OP_reg18
            | constants::DW_OP_reg19
            | constants::DW_OP_reg20
            | constants::DW_OP_reg21
            | constants::DW_OP_reg22
            | constants::DW_OP_reg23
            | constants::DW_OP_reg24
            | constants::DW_OP_reg25
            | constants::DW_OP_reg26
            | constants::DW_OP_reg27
            | constants::DW_OP_reg28
            | constants::DW_OP_reg29
            | constants::DW_OP_reg30
            | constants::DW_OP_reg31 => Ok(Operation::Register {
                register: Register((opcode - constants::DW_OP_reg0.0).into()),
            }),
            constants::DW_OP_breg0
            | constants::DW_OP_breg1
            | constants::DW_OP_breg2
            | constants::DW_OP_breg3
            | constants::DW_OP_breg4
            | constants::DW_OP_breg5
            | constants::DW_OP_breg6
            | constants::DW_OP_breg7
            | constants::DW_OP_breg8
            | constants::DW_OP_breg9
            | constants::DW_OP_breg10
            | constants::DW_OP_breg11
            | constants::DW_OP_breg12
            | constants::DW_OP_breg13
            | constants::DW_OP_breg14
            | constants::DW_OP_breg15
            | constants::DW_OP_breg16
            | constants::DW_OP_breg17
            | constants::DW_OP_breg18
            | constants::DW_OP_breg19
            | constants::DW_OP_breg20
            | constants::DW_OP_breg21
            | constants::DW_OP_breg22
            | constants::DW_OP_breg23
            | constants::DW_OP_breg24
            | constants::DW_OP_breg25
            | constants::DW_OP_breg26
            | constants::DW_OP_breg27
            | constants::DW_OP_breg28
            | constants::DW_OP_breg29
            | constants::DW_OP_breg30
            | constants::DW_OP_breg31 => {
                let value = bytes.read_sleb128()?;
                Ok(Operation::RegisterOffset {
                    register: Register((opcode - constants::DW_OP_breg0.0).into()),
                    offset: value,
                    base_type: generic_type(),
                })
            }
            constants::DW_OP_regx => {
                let register = bytes.read_uleb128().and_then(Register::from_u64)?;
                Ok(Operation::Register { register })
            }
            constants::DW_OP_fbreg => {
                let value = bytes.read_sleb128()?;
                Ok(Operation::FrameOffset { offset: value })
            }
            constants::DW_OP_bregx => {
                let register = bytes.read_uleb128().and_then(Register::from_u64)?;
                let offset = bytes.read_sleb128()?;
                Ok(Operation::RegisterOffset {
                    register,
                    offset,
                    base_type: generic_type(),
                })
            }
            constants::DW_OP_piece => {
                let size = bytes.read_uleb128()?;
                Ok(Operation::Piece {
                    size_in_bits: 8 * size,
                    bit_offset: None,
                })
            }
            constants::DW_OP_deref_size => {
                let size = bytes.read_u8()?;
                Ok(Operation::Deref {
                    base_type: generic_type(),
                    size,
                    space: false,
                })
            }
            constants::DW_OP_xderef_size => {
                let size = bytes.read_u8()?;
                Ok(Operation::Deref {
                    base_type: generic_type(),
                    size,
                    space: true,
                })
            }
            constants::DW_OP_nop => Ok(Operation::Nop),
            constants::DW_OP_push_object_address => Ok(Operation::PushObjectAddress),
            constants::DW_OP_call2 => {
                let value = bytes.read_u16().map(R::Offset::from_u16)?;
                Ok(Operation::Call {
                    offset: DieReference::UnitRef(UnitOffset(value)),
                })
            }
            constants::DW_OP_call4 => {
                let value = bytes.read_u32().map(R::Offset::from_u32)?;
                Ok(Operation::Call {
                    offset: DieReference::UnitRef(UnitOffset(value)),
                })
            }
            constants::DW_OP_call_ref => {
                let value = bytes.read_offset(encoding.format)?;
                Ok(Operation::Call {
                    offset: DieReference::DebugInfoRef(DebugInfoOffset(value)),
                })
            }
            constants::DW_OP_form_tls_address | constants::DW_OP_GNU_push_tls_address => {
                Ok(Operation::TLS)
            }
            constants::DW_OP_call_frame_cfa => Ok(Operation::CallFrameCFA),
            constants::DW_OP_bit_piece => {
                let size = bytes.read_uleb128()?;
                let offset = bytes.read_uleb128()?;
                Ok(Operation::Piece {
                    size_in_bits: size,
                    bit_offset: Some(offset),
                })
            }
            constants::DW_OP_implicit_value => {
                let len = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
                let data = bytes.split(len)?;
                Ok(Operation::ImplicitValue { data })
            }
            constants::DW_OP_stack_value => Ok(Operation::StackValue),
            constants::DW_OP_implicit_pointer | constants::DW_OP_GNU_implicit_pointer => {
                let value = if encoding.version == 2 {
                    bytes
                        .read_address(encoding.address_size)
                        .and_then(Offset::from_u64)?
                } else {
                    bytes.read_offset(encoding.format)?
                };
                let byte_offset = bytes.read_sleb128()?;
                Ok(Operation::ImplicitPointer {
                    value: DebugInfoOffset(value),
                    byte_offset,
                })
            }
            constants::DW_OP_addrx | constants::DW_OP_GNU_addr_index => {
                let index = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
                Ok(Operation::AddressIndex {
                    index: DebugAddrIndex(index),
                })
            }
            constants::DW_OP_constx | constants::DW_OP_GNU_const_index => {
                let index = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
                Ok(Operation::ConstantIndex {
                    index: DebugAddrIndex(index),
                })
            }
            constants::DW_OP_entry_value | constants::DW_OP_GNU_entry_value => {
                let len = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
                let expression = bytes.split(len)?;
                Ok(Operation::EntryValue { expression })
            }
            constants::DW_OP_GNU_parameter_ref => {
                let value = bytes.read_u32().map(R::Offset::from_u32)?;
                Ok(Operation::ParameterRef {
                    offset: UnitOffset(value),
                })
            }
            constants::DW_OP_const_type | constants::DW_OP_GNU_const_type => {
                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
                let len = bytes.read_u8()?;
                let value = bytes.split(R::Offset::from_u8(len))?;
                Ok(Operation::TypedLiteral {
                    base_type: UnitOffset(base_type),
                    value,
                })
            }
            constants::DW_OP_regval_type | constants::DW_OP_GNU_regval_type => {
                let register = bytes.read_uleb128().and_then(Register::from_u64)?;
                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
                Ok(Operation::RegisterOffset {
                    register,
                    offset: 0,
                    base_type: UnitOffset(base_type),
                })
            }
            constants::DW_OP_deref_type | constants::DW_OP_GNU_deref_type => {
                let size = bytes.read_u8()?;
                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
                Ok(Operation::Deref {
                    base_type: UnitOffset(base_type),
                    size,
                    space: false,
                })
            }
            constants::DW_OP_xderef_type => {
                let size = bytes.read_u8()?;
                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
                Ok(Operation::Deref {
                    base_type: UnitOffset(base_type),
                    size,
                    space: true,
                })
            }
            constants::DW_OP_convert | constants::DW_OP_GNU_convert => {
                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
                Ok(Operation::Convert {
                    base_type: UnitOffset(base_type),
                })
            }
            constants::DW_OP_reinterpret | constants::DW_OP_GNU_reinterpret => {
                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
                Ok(Operation::Reinterpret {
                    base_type: UnitOffset(base_type),
                })
            }
            constants::DW_OP_WASM_location => match bytes.read_u8()? {
                0x0 => {
                    let index = bytes.read_uleb128_u32()?;
                    Ok(Operation::WasmLocal { index })
                }
                0x1 => {
                    let index = bytes.read_uleb128_u32()?;
                    Ok(Operation::WasmGlobal { index })
                }
                0x2 => {
                    let index = bytes.read_uleb128_u32()?;
                    Ok(Operation::WasmStack { index })
                }
                0x3 => {
                    let index = bytes.read_u32()?;
                    Ok(Operation::WasmGlobal { index })
                }
                _ => Err(Error::InvalidExpression(name)),
            },
            _ => Err(Error::InvalidExpression(name)),
        }
    }
}

#[derive(Debug)]
enum EvaluationState<R: Reader> {
    Start(Option<u64>),
    Ready,
    Error(Error),
    Complete,
    Waiting(EvaluationWaiting<R>),
}

#[derive(Debug)]
enum EvaluationWaiting<R: Reader> {
    Memory,
    Register { offset: i64 },
    FrameBase { offset: i64 },
    Tls,
    Cfa,
    AtLocation,
    EntryValue,
    ParameterRef,
    RelocatedAddress,
    IndexedAddress,
    TypedLiteral { value: R },
    Convert,
    Reinterpret,
}

/// The state of an `Evaluation` after evaluating a DWARF expression.
/// The evaluation is either `Complete`, or it requires more data
/// to continue, as described by the variant.
#[derive(Debug, PartialEq)]
pub enum EvaluationResult<R: Reader> {
    /// The `Evaluation` is complete, and `Evaluation::result()` can be called.
    Complete,
    /// The `Evaluation` needs a value from memory to proceed further.  Once the
    /// caller determines what value to provide it should resume the `Evaluation`
    /// by calling `Evaluation::resume_with_memory`.
    RequiresMemory {
        /// The address of the value required.
        address: u64,
        /// The size of the value required. This is guaranteed to be at most the
        /// word size of the target architecture.
        size: u8,
        /// If not `None`, a target-specific address space value.
        space: Option<u64>,
        /// The DIE of the base type or 0 to indicate the generic type
        base_type: UnitOffset<R::Offset>,
    },
    /// The `Evaluation` needs a value from a register to proceed further.  Once
    /// the caller determines what value to provide it should resume the
    /// `Evaluation` by calling `Evaluation::resume_with_register`.
    RequiresRegister {
        /// The register number.
        register: Register,
        /// The DIE of the base type or 0 to indicate the generic type
        base_type: UnitOffset<R::Offset>,
    },
    /// The `Evaluation` needs the frame base address to proceed further.  Once
    /// the caller determines what value to provide it should resume the
    /// `Evaluation` by calling `Evaluation::resume_with_frame_base`.  The frame
    /// base address is the address produced by the location description in the
    /// `DW_AT_frame_base` attribute of the current function.
    RequiresFrameBase,
    /// The `Evaluation` needs a value from TLS to proceed further.  Once the
    /// caller determines what value to provide it should resume the
    /// `Evaluation` by calling `Evaluation::resume_with_tls`.
    RequiresTls(u64),
    /// The `Evaluation` needs the CFA to proceed further.  Once the caller
    /// determines what value to provide it should resume the `Evaluation` by
    /// calling `Evaluation::resume_with_call_frame_cfa`.
    RequiresCallFrameCfa,
    /// The `Evaluation` needs the DWARF expression at the given location to
    /// proceed further.  Once the caller determines what value to provide it
    /// should resume the `Evaluation` by calling
    /// `Evaluation::resume_with_at_location`.
    RequiresAtLocation(DieReference<R::Offset>),
    /// The `Evaluation` needs the value produced by evaluating a DWARF
    /// expression at the entry point of the current subprogram.  Once the
    /// caller determines what value to provide it should resume the
    /// `Evaluation` by calling `Evaluation::resume_with_entry_value`.
    RequiresEntryValue(Expression<R>),
    /// The `Evaluation` needs the value of the parameter at the given location
    /// in the current function's caller.  Once the caller determines what value
    /// to provide it should resume the `Evaluation` by calling
    /// `Evaluation::resume_with_parameter_ref`.
    RequiresParameterRef(UnitOffset<R::Offset>),
    /// The `Evaluation` needs an address to be relocated to proceed further.
    /// Once the caller determines what value to provide it should resume the
    /// `Evaluation` by calling `Evaluation::resume_with_relocated_address`.
    RequiresRelocatedAddress(u64),
    /// The `Evaluation` needs an address from the `.debug_addr` section.
    /// This address may also need to be relocated.
    /// Once the caller determines what value to provide it should resume the
    /// `Evaluation` by calling `Evaluation::resume_with_indexed_address`.
    RequiresIndexedAddress {
        /// The index of the address in the `.debug_addr` section,
        /// relative to the `DW_AT_addr_base` of the compilation unit.
        index: DebugAddrIndex<R::Offset>,
        /// Whether the address also needs to be relocated.
        relocate: bool,
    },
    /// The `Evaluation` needs the `ValueType` for the base type DIE at
    /// the give unit offset.  Once the caller determines what value to provide it
    /// should resume the `Evaluation` by calling
    /// `Evaluation::resume_with_base_type`.
    RequiresBaseType(UnitOffset<R::Offset>),
}

/// The bytecode for a DWARF expression or location description.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Expression<R: Reader>(pub R);

impl<R: Reader> Expression<R> {
    /// Create an evaluation for this expression.
    ///
    /// The `encoding` is determined by the
    /// [`CompilationUnitHeader`](struct.CompilationUnitHeader.html) or
    /// [`TypeUnitHeader`](struct.TypeUnitHeader.html) that this expression
    /// relates to.
    ///
    /// # Examples
    /// ```rust,no_run
    /// use gimli::Expression;
    /// # let endian = gimli::LittleEndian;
    /// # let debug_info = gimli::DebugInfo::from(gimli::EndianSlice::new(&[], endian));
    /// # let unit = debug_info.units().next().unwrap().unwrap();
    /// # let bytecode = gimli::EndianSlice::new(&[], endian);
    /// let expression = gimli::Expression(bytecode);
    /// let mut eval = expression.evaluation(unit.encoding());
    /// let mut result = eval.evaluate().unwrap();
    /// ```
    #[cfg(feature = "read")]
    #[inline]
    pub fn evaluation(self, encoding: Encoding) -> Evaluation<R> {
        Evaluation::new(self.0, encoding)
    }

    /// Return an iterator for the operations in the expression.
    pub fn operations(self, encoding: Encoding) -> OperationIter<R> {
        OperationIter {
            input: self.0,
            encoding,
        }
    }
}

/// An iterator for the operations in an expression.
#[derive(Debug, Clone, Copy)]
pub struct OperationIter<R: Reader> {
    input: R,
    encoding: Encoding,
}

impl<R: Reader> OperationIter<R> {
    /// Read the next operation in an expression.
    pub fn next(&mut self) -> Result<Option<Operation<R>>> {
        if self.input.is_empty() {
            return Ok(None);
        }
        match Operation::parse(&mut self.input, self.encoding) {
            Ok(op) => Ok(Some(op)),
            Err(e) => {
                self.input.empty();
                Err(e)
            }
        }
    }

    /// Return the current byte offset of the iterator.
    pub fn offset_from(&self, expression: &Expression<R>) -> R::Offset {
        self.input.offset_from(&expression.0)
    }
}

#[cfg(feature = "fallible-iterator")]
impl<R: Reader> fallible_iterator::FallibleIterator for OperationIter<R> {
    type Item = Operation<R>;
    type Error = Error;

    fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
        OperationIter::next(self)
    }
}

/// Specification of what storage should be used for [`Evaluation`].
///
#[cfg_attr(
    feature = "read",
    doc = "
Normally you would only need to use [`StoreOnHeap`], which places the stacks and the results
on the heap using [`Vec`]. This is the default storage type parameter for [`Evaluation`].
"
)]
///
/// If you need to avoid [`Evaluation`] from allocating memory, e.g. for signal safety,
/// you can provide you own storage specification:
/// ```rust,no_run
/// # use gimli::*;
/// # let bytecode = EndianSlice::new(&[], LittleEndian);
/// # let encoding = unimplemented!();
/// # let get_register_value = |_, _| Value::Generic(42);
/// # let get_frame_base = || 0xdeadbeef;
/// #
/// struct StoreOnStack;
///
/// impl<R: Reader> EvaluationStorage<R> for StoreOnStack {
///     type Stack = [Value; 64];
///     type ExpressionStack = [(R, R); 4];
///     type Result = [Piece<R>; 1];
/// }
///
/// let mut eval = Evaluation::<_, StoreOnStack>::new_in(bytecode, encoding);
/// let mut result = eval.evaluate().unwrap();
/// while result != EvaluationResult::Complete {
///   match result {
///     EvaluationResult::RequiresRegister { register, base_type } => {
///       let value = get_register_value(register, base_type);
///       result = eval.resume_with_register(value).unwrap();
///     },
///     EvaluationResult::RequiresFrameBase => {
///       let frame_base = get_frame_base();
///       result = eval.resume_with_frame_base(frame_base).unwrap();
///     },
///     _ => unimplemented!(),
///   };
/// }
///
/// let result = eval.as_result();
/// println!("{:?}", result);
/// ```
pub trait EvaluationStorage<R: Reader> {
    /// The storage used for the evaluation stack.
    type Stack: ArrayLike<Item = Value>;
    /// The storage used for the expression stack.
    type ExpressionStack: ArrayLike<Item = (R, R)>;
    /// The storage used for the results.
    type Result: ArrayLike<Item = Piece<R>>;
}

#[cfg(feature = "read")]
impl<R: Reader> EvaluationStorage<R> for StoreOnHeap {
    type Stack = Vec<Value>;
    type ExpressionStack = Vec<(R, R)>;
    type Result = Vec<Piece<R>>;
}

/// A DWARF expression evaluator.
///
/// # Usage
/// A DWARF expression may require additional data to produce a final result,
/// such as the value of a register or a memory location.  Once initial setup
/// is complete (i.e. `set_initial_value()`, `set_object_address()`) the
/// consumer calls the `evaluate()` method.  That returns an `EvaluationResult`,
/// which is either `EvaluationResult::Complete` or a value indicating what
/// data is needed to resume the `Evaluation`.  The consumer is responsible for
/// producing that data and resuming the computation with the correct method,
/// as documented for `EvaluationResult`.  Only once an `EvaluationResult::Complete`
/// is returned can the consumer call `result()`.
///
/// This design allows the consumer of `Evaluation` to decide how and when to
/// produce the required data and resume the computation.  The `Evaluation` can
/// be driven synchronously (as shown below) or by some asynchronous mechanism
/// such as futures.
///
/// # Examples
/// ```rust,no_run
/// use gimli::{Evaluation, EvaluationResult, Expression};
/// # let bytecode = gimli::EndianSlice::new(&[], gimli::LittleEndian);
/// # let encoding = unimplemented!();
/// # let get_register_value = |_, _| gimli::Value::Generic(42);
/// # let get_frame_base = || 0xdeadbeef;
///
/// let mut eval = Evaluation::new(bytecode, encoding);
/// let mut result = eval.evaluate().unwrap();
/// while result != EvaluationResult::Complete {
///   match result {
///     EvaluationResult::RequiresRegister { register, base_type } => {
///       let value = get_register_value(register, base_type);
///       result = eval.resume_with_register(value).unwrap();
///     },
///     EvaluationResult::RequiresFrameBase => {
///       let frame_base = get_frame_base();
///       result = eval.resume_with_frame_base(frame_base).unwrap();
///     },
///     _ => unimplemented!(),
///   };
/// }
///
/// let result = eval.result();
/// println!("{:?}", result);
/// ```
#[derive(Debug)]
pub struct Evaluation<R: Reader, S: EvaluationStorage<R> = StoreOnHeap> {
    bytecode: R,
    encoding: Encoding,
    object_address: Option<u64>,
    max_iterations: Option<u32>,
    iteration: u32,
    state: EvaluationState<R>,

    // Stack operations are done on word-sized values.  We do all
    // operations on 64-bit values, and then mask the results
    // appropriately when popping.
    addr_mask: u64,

    // The stack.
    stack: ArrayVec<S::Stack>,

    // The next operation to decode and evaluate.
    pc: R,

    // If we see a DW_OP_call* operation, the previous PC and bytecode
    // is stored here while evaluating the subroutine.
    expression_stack: ArrayVec<S::ExpressionStack>,

    value_result: Option<Value>,
    result: ArrayVec<S::Result>,
}

#[cfg(feature = "read")]
impl<R: Reader> Evaluation<R> {
    /// Create a new DWARF expression evaluator.
    ///
    /// The new evaluator is created without an initial value, without
    /// an object address, and without a maximum number of iterations.
    pub fn new(bytecode: R, encoding: Encoding) -> Self {
        Self::new_in(bytecode, encoding)
    }

    /// Get the result of this `Evaluation`.
    ///
    /// # Panics
    /// Panics if this `Evaluation` has not been driven to completion.
    pub fn result(self) -> Vec<Piece<R>> {
        match self.state {
            EvaluationState::Complete => self.result.into_vec(),
            _ => {
                panic!("Called `Evaluation::result` on an `Evaluation` that has not been completed")
            }
        }
    }
}

impl<R: Reader, S: EvaluationStorage<R>> Evaluation<R, S> {
    /// Create a new DWARF expression evaluator.
    ///
    /// The new evaluator is created without an initial value, without
    /// an object address, and without a maximum number of iterations.
    pub fn new_in(bytecode: R, encoding: Encoding) -> Self {
        let pc = bytecode.clone();
        Evaluation {
            bytecode,
            encoding,
            object_address: None,
            max_iterations: None,
            iteration: 0,
            state: EvaluationState::Start(None),
            addr_mask: if encoding.address_size == 8 {
                !0u64
            } else {
                (1 << (8 * u64::from(encoding.address_size))) - 1
            },
            stack: Default::default(),
            expression_stack: Default::default(),
            pc,
            value_result: None,
            result: Default::default(),
        }
    }

    /// Set an initial value to be pushed on the DWARF expression
    /// evaluator's stack.  This can be used in cases like
    /// `DW_AT_vtable_elem_location`, which require a value on the
    /// stack before evaluation commences.  If no initial value is
    /// set, and the expression uses an opcode requiring the initial
    /// value, then evaluation will fail with an error.
    ///
    /// # Panics
    /// Panics if `set_initial_value()` has already been called, or if
    /// `evaluate()` has already been called.
    pub fn set_initial_value(&mut self, value: u64) {
        match self.state {
            EvaluationState::Start(None) => {
                self.state = EvaluationState::Start(Some(value));
            }
            _ => panic!(
                "`Evaluation::set_initial_value` was called twice, or after evaluation began."
            ),
        };
    }

    /// Set the enclosing object's address, as used by
    /// `DW_OP_push_object_address`.  If no object address is set, and
    /// the expression uses an opcode requiring the object address,
    /// then evaluation will fail with an error.
    pub fn set_object_address(&mut self, value: u64) {
        self.object_address = Some(value);
    }

    /// Set the maximum number of iterations to be allowed by the
    /// expression evaluator.
    ///
    /// An iteration corresponds approximately to the evaluation of a
    /// single operation in an expression ("approximately" because the
    /// implementation may allow two such operations in some cases).
    /// The default is not to have a maximum; once set, it's not
    /// possible to go back to this default state.  This value can be
    /// set to avoid denial of service attacks by bad DWARF bytecode.
    pub fn set_max_iterations(&mut self, value: u32) {
        self.max_iterations = Some(value);
    }

    fn pop(&mut self) -> Result<Value> {
        match self.stack.pop() {
            Some(value) => Ok(value),
            None => Err(Error::NotEnoughStackItems),
        }
    }

    fn push(&mut self, value: Value) -> Result<()> {
        self.stack.try_push(value).map_err(|_| Error::StackFull)
    }

    fn evaluate_one_operation(&mut self) -> Result<OperationEvaluationResult<R>> {
        let operation = Operation::parse(&mut self.pc, self.encoding)?;

        match operation {
            Operation::Deref {
                base_type,
                size,
                space,
            } => {
                let entry = self.pop()?;
                let addr = entry.to_u64(self.addr_mask)?;
                let addr_space = if space {
                    let entry = self.pop()?;
                    let value = entry.to_u64(self.addr_mask)?;
                    Some(value)
                } else {
                    None
                };
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::Memory,
                    EvaluationResult::RequiresMemory {
                        address: addr,
                        size,
                        space: addr_space,
                        base_type,
                    },
                ));
            }

            Operation::Drop => {
                self.pop()?;
            }
            Operation::Pick { index } => {
                let len = self.stack.len();
                let index = index as usize;
                if index >= len {
                    return Err(Error::NotEnoughStackItems);
                }
                let value = self.stack[len - index - 1];
                self.push(value)?;
            }
            Operation::Swap => {
                let top = self.pop()?;
                let next = self.pop()?;
                self.push(top)?;
                self.push(next)?;
            }
            Operation::Rot => {
                let one = self.pop()?;
                let two = self.pop()?;
                let three = self.pop()?;
                self.push(one)?;
                self.push(three)?;
                self.push(two)?;
            }

            Operation::Abs => {
                let value = self.pop()?;
                let result = value.abs(self.addr_mask)?;
                self.push(result)?;
            }
            Operation::And => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.and(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Div => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.div(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Minus => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.sub(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Mod => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.rem(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Mul => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.mul(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Neg => {
                let v = self.pop()?;
                let result = v.neg(self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Not => {
                let value = self.pop()?;
                let result = value.not(self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Or => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.or(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Plus => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.add(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::PlusConstant { value } => {
                let lhs = self.pop()?;
                let rhs = Value::from_u64(lhs.value_type(), value)?;
                let result = lhs.add(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Shl => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.shl(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Shr => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.shr(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Shra => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.shra(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Xor => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.xor(rhs, self.addr_mask)?;
                self.push(result)?;
            }

            Operation::Bra { target } => {
                let entry = self.pop()?;
                let v = entry.to_u64(self.addr_mask)?;
                if v != 0 {
                    self.pc = compute_pc(&self.pc, &self.bytecode, target)?;
                }
            }

            Operation::Eq => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.eq(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Ge => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.ge(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Gt => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.gt(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Le => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.le(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Lt => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.lt(rhs, self.addr_mask)?;
                self.push(result)?;
            }
            Operation::Ne => {
                let rhs = self.pop()?;
                let lhs = self.pop()?;
                let result = lhs.ne(rhs, self.addr_mask)?;
                self.push(result)?;
            }

            Operation::Skip { target } => {
                self.pc = compute_pc(&self.pc, &self.bytecode, target)?;
            }

            Operation::UnsignedConstant { value } => {
                self.push(Value::Generic(value))?;
            }

            Operation::SignedConstant { value } => {
                self.push(Value::Generic(value as u64))?;
            }

            Operation::RegisterOffset {
                register,
                offset,
                base_type,
            } => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::Register { offset },
                    EvaluationResult::RequiresRegister {
                        register,
                        base_type,
                    },
                ));
            }

            Operation::FrameOffset { offset } => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::FrameBase { offset },
                    EvaluationResult::RequiresFrameBase,
                ));
            }

            Operation::Nop => {}

            Operation::PushObjectAddress => {
                if let Some(value) = self.object_address {
                    self.push(Value::Generic(value))?;
                } else {
                    return Err(Error::InvalidPushObjectAddress);
                }
            }

            Operation::Call { offset } => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::AtLocation,
                    EvaluationResult::RequiresAtLocation(offset),
                ));
            }

            Operation::TLS => {
                let entry = self.pop()?;
                let index = entry.to_u64(self.addr_mask)?;
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::Tls,
                    EvaluationResult::RequiresTls(index),
                ));
            }

            Operation::CallFrameCFA => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::Cfa,
                    EvaluationResult::RequiresCallFrameCfa,
                ));
            }

            Operation::Register { register } => {
                let location = Location::Register { register };
                return Ok(OperationEvaluationResult::Complete { location });
            }

            Operation::ImplicitValue { ref data } => {
                let location = Location::Bytes {
                    value: data.clone(),
                };
                return Ok(OperationEvaluationResult::Complete { location });
            }

            Operation::StackValue => {
                let value = self.pop()?;
                let location = Location::Value { value };
                return Ok(OperationEvaluationResult::Complete { location });
            }

            Operation::ImplicitPointer { value, byte_offset } => {
                let location = Location::ImplicitPointer { value, byte_offset };
                return Ok(OperationEvaluationResult::Complete { location });
            }

            Operation::EntryValue { ref expression } => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::EntryValue,
                    EvaluationResult::RequiresEntryValue(Expression(expression.clone())),
                ));
            }

            Operation::ParameterRef { offset } => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::ParameterRef,
                    EvaluationResult::RequiresParameterRef(offset),
                ));
            }

            Operation::Address { address } => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::RelocatedAddress,
                    EvaluationResult::RequiresRelocatedAddress(address),
                ));
            }

            Operation::AddressIndex { index } => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::IndexedAddress,
                    EvaluationResult::RequiresIndexedAddress {
                        index,
                        relocate: true,
                    },
                ));
            }

            Operation::ConstantIndex { index } => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::IndexedAddress,
                    EvaluationResult::RequiresIndexedAddress {
                        index,
                        relocate: false,
                    },
                ));
            }

            Operation::Piece {
                size_in_bits,
                bit_offset,
            } => {
                let location = if self.stack.is_empty() {
                    Location::Empty
                } else {
                    let entry = self.pop()?;
                    let address = entry.to_u64(self.addr_mask)?;
                    Location::Address { address }
                };
                self.result
                    .try_push(Piece {
                        size_in_bits: Some(size_in_bits),
                        bit_offset,
                        location,
                    })
                    .map_err(|_| Error::StackFull)?;
                return Ok(OperationEvaluationResult::Piece);
            }

            Operation::TypedLiteral { base_type, value } => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::TypedLiteral { value },
                    EvaluationResult::RequiresBaseType(base_type),
                ));
            }
            Operation::Convert { base_type } => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::Convert,
                    EvaluationResult::RequiresBaseType(base_type),
                ));
            }
            Operation::Reinterpret { base_type } => {
                return Ok(OperationEvaluationResult::Waiting(
                    EvaluationWaiting::Reinterpret,
                    EvaluationResult::RequiresBaseType(base_type),
                ));
            }
            Operation::WasmLocal { .. }
            | Operation::WasmGlobal { .. }
            | Operation::WasmStack { .. } => {
                return Err(Error::UnsupportedEvaluation);
            }
        }

        Ok(OperationEvaluationResult::Incomplete)
    }

    /// Get the result if this is an evaluation for a value.
    ///
    /// Returns `None` if the evaluation contained operations that are only
    /// valid for location descriptions.
    ///
    /// # Panics
    /// Panics if this `Evaluation` has not been driven to completion.
    pub fn value_result(&self) -> Option<Value> {
        match self.state {
            EvaluationState::Complete => self.value_result,
            _ => {
                panic!("Called `Evaluation::value_result` on an `Evaluation` that has not been completed")
            }
        }
    }

    /// Get the result of this `Evaluation`.
    ///
    /// # Panics
    /// Panics if this `Evaluation` has not been driven to completion.
    pub fn as_result(&self) -> &[Piece<R>] {
        match self.state {
            EvaluationState::Complete => &self.result,
            _ => {
                panic!(
                    "Called `Evaluation::as_result` on an `Evaluation` that has not been completed"
                )
            }
        }
    }

    /// Evaluate a DWARF expression.  This method should only ever be called
    /// once.  If the returned `EvaluationResult` is not
    /// `EvaluationResult::Complete`, the caller should provide the required
    /// value and resume the evaluation by calling the appropriate resume_with
    /// method on `Evaluation`.
    pub fn evaluate(&mut self) -> Result<EvaluationResult<R>> {
        match self.state {
            EvaluationState::Start(initial_value) => {
                if let Some(value) = initial_value {
                    self.push(Value::Generic(value))?;
                }
                self.state = EvaluationState::Ready;
            }
            EvaluationState::Ready => {}
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Complete => return Ok(EvaluationResult::Complete),
            EvaluationState::Waiting(_) => panic!(),
        };

        match self.evaluate_internal() {
            Ok(r) => Ok(r),
            Err(e) => {
                self.state = EvaluationState::Error(e);
                Err(e)
            }
        }
    }

    /// Resume the `Evaluation` with the provided memory `value`.  This will apply
    /// the provided memory value to the evaluation and continue evaluating
    /// opcodes until the evaluation is completed, reaches an error, or needs
    /// more information again.
    ///
    /// # Panics
    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresMemory`.
    pub fn resume_with_memory(&mut self, value: Value) -> Result<EvaluationResult<R>> {
        match self.state {
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Waiting(EvaluationWaiting::Memory) => {
                self.push(value)?;
            }
            _ => panic!(
                "Called `Evaluation::resume_with_memory` without a preceding `EvaluationResult::RequiresMemory`"
            ),
        };

        self.evaluate_internal()
    }

    /// Resume the `Evaluation` with the provided `register` value.  This will apply
    /// the provided register value to the evaluation and continue evaluating
    /// opcodes until the evaluation is completed, reaches an error, or needs
    /// more information again.
    ///
    /// # Panics
    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresRegister`.
    pub fn resume_with_register(&mut self, value: Value) -> Result<EvaluationResult<R>> {
        match self.state {
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Waiting(EvaluationWaiting::Register { offset }) => {
                let offset = Value::from_u64(value.value_type(), offset as u64)?;
                let value = value.add(offset, self.addr_mask)?;
                self.push(value)?;
            }
            _ => panic!(
                "Called `Evaluation::resume_with_register` without a preceding `EvaluationResult::RequiresRegister`"
            ),
        };

        self.evaluate_internal()
    }

    /// Resume the `Evaluation` with the provided `frame_base`.  This will
    /// apply the provided frame base value to the evaluation and continue
    /// evaluating opcodes until the evaluation is completed, reaches an error,
    /// or needs more information again.
    ///
    /// # Panics
    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresFrameBase`.
    pub fn resume_with_frame_base(&mut self, frame_base: u64) -> Result<EvaluationResult<R>> {
        match self.state {
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Waiting(EvaluationWaiting::FrameBase { offset }) => {
                self.push(Value::Generic(frame_base.wrapping_add(offset as u64)))?;
            }
            _ => panic!(
                "Called `Evaluation::resume_with_frame_base` without a preceding `EvaluationResult::RequiresFrameBase`"
            ),
        };

        self.evaluate_internal()
    }

    /// Resume the `Evaluation` with the provided `value`.  This will apply
    /// the provided TLS value to the evaluation and continue evaluating
    /// opcodes until the evaluation is completed, reaches an error, or needs
    /// more information again.
    ///
    /// # Panics
    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresTls`.
    pub fn resume_with_tls(&mut self, value: u64) -> Result<EvaluationResult<R>> {
        match self.state {
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Waiting(EvaluationWaiting::Tls) => {
                self.push(Value::Generic(value))?;
            }
            _ => panic!(
                "Called `Evaluation::resume_with_tls` without a preceding `EvaluationResult::RequiresTls`"
            ),
        };

        self.evaluate_internal()
    }

    /// Resume the `Evaluation` with the provided `cfa`.  This will
    /// apply the provided CFA value to the evaluation and continue evaluating
    /// opcodes until the evaluation is completed, reaches an error, or needs
    /// more information again.
    ///
    /// # Panics
    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresCallFrameCfa`.
    pub fn resume_with_call_frame_cfa(&mut self, cfa: u64) -> Result<EvaluationResult<R>> {
        match self.state {
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Waiting(EvaluationWaiting::Cfa) => {
                self.push(Value::Generic(cfa))?;
            }
            _ => panic!(
                "Called `Evaluation::resume_with_call_frame_cfa` without a preceding `EvaluationResult::RequiresCallFrameCfa`"
            ),
        };

        self.evaluate_internal()
    }

    /// Resume the `Evaluation` with the provided `bytes`.  This will
    /// continue processing the evaluation with the new expression provided
    /// until the evaluation is completed, reaches an error, or needs more
    /// information again.
    ///
    /// # Panics
    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresAtLocation`.
    pub fn resume_with_at_location(&mut self, mut bytes: R) -> Result<EvaluationResult<R>> {
        match self.state {
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Waiting(EvaluationWaiting::AtLocation) => {
                if !bytes.is_empty() {
                    let mut pc = bytes.clone();
                    mem::swap(&mut pc, &mut self.pc);
                    mem::swap(&mut bytes, &mut self.bytecode);
                    self.expression_stack.try_push((pc, bytes)).map_err(|_| Error::StackFull)?;
                }
            }
            _ => panic!(
                "Called `Evaluation::resume_with_at_location` without a precedeing `EvaluationResult::RequiresAtLocation`"
            ),
        };

        self.evaluate_internal()
    }

    /// Resume the `Evaluation` with the provided `entry_value`.  This will
    /// apply the provided entry value to the evaluation and continue evaluating
    /// opcodes until the evaluation is completed, reaches an error, or needs
    /// more information again.
    ///
    /// # Panics
    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresEntryValue`.
    pub fn resume_with_entry_value(&mut self, entry_value: Value) -> Result<EvaluationResult<R>> {
        match self.state {
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Waiting(EvaluationWaiting::EntryValue) => {
                self.push(entry_value)?;
            }
            _ => panic!(
                "Called `Evaluation::resume_with_entry_value` without a preceding `EvaluationResult::RequiresEntryValue`"
            ),
        };

        self.evaluate_internal()
    }

    /// Resume the `Evaluation` with the provided `parameter_value`.  This will
    /// apply the provided parameter value to the evaluation and continue evaluating
    /// opcodes until the evaluation is completed, reaches an error, or needs
    /// more information again.
    ///
    /// # Panics
    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresParameterRef`.
    pub fn resume_with_parameter_ref(
        &mut self,
        parameter_value: u64,
    ) -> Result<EvaluationResult<R>> {
        match self.state {
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Waiting(EvaluationWaiting::ParameterRef) => {
                self.push(Value::Generic(parameter_value))?;
            }
            _ => panic!(
                "Called `Evaluation::resume_with_parameter_ref` without a preceding `EvaluationResult::RequiresParameterRef`"
            ),
        };

        self.evaluate_internal()
    }

    /// Resume the `Evaluation` with the provided relocated `address`.  This will use the
    /// provided relocated address for the operation that required it, and continue evaluating
    /// opcodes until the evaluation is completed, reaches an error, or needs
    /// more information again.
    ///
    /// # Panics
    /// Panics if this `Evaluation` did not previously stop with
    /// `EvaluationResult::RequiresRelocatedAddress`.
    pub fn resume_with_relocated_address(&mut self, address: u64) -> Result<EvaluationResult<R>> {
        match self.state {
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Waiting(EvaluationWaiting::RelocatedAddress) => {
                self.push(Value::Generic(address))?;
            }
            _ => panic!(
                "Called `Evaluation::resume_with_relocated_address` without a preceding `EvaluationResult::RequiresRelocatedAddress`"
            ),
        };

        self.evaluate_internal()
    }

    /// Resume the `Evaluation` with the provided indexed `address`.  This will use the
    /// provided indexed address for the operation that required it, and continue evaluating
    /// opcodes until the evaluation is completed, reaches an error, or needs
    /// more information again.
    ///
    /// # Panics
    /// Panics if this `Evaluation` did not previously stop with
    /// `EvaluationResult::RequiresIndexedAddress`.
    pub fn resume_with_indexed_address(&mut self, address: u64) -> Result<EvaluationResult<R>> {
        match self.state {
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Waiting(EvaluationWaiting::IndexedAddress) => {
                self.push(Value::Generic(address))?;
            }
            _ => panic!(
                "Called `Evaluation::resume_with_indexed_address` without a preceding `EvaluationResult::RequiresIndexedAddress`"
            ),
        };

        self.evaluate_internal()
    }

    /// Resume the `Evaluation` with the provided `base_type`.  This will use the
    /// provided base type for the operation that required it, and continue evaluating
    /// opcodes until the evaluation is completed, reaches an error, or needs
    /// more information again.
    ///
    /// # Panics
    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresBaseType`.
    pub fn resume_with_base_type(&mut self, base_type: ValueType) -> Result<EvaluationResult<R>> {
        let value = match self.state {
            EvaluationState::Error(err) => return Err(err),
            EvaluationState::Waiting(EvaluationWaiting::TypedLiteral { ref value }) => {
                Value::parse(base_type, value.clone())?
            }
            EvaluationState::Waiting(EvaluationWaiting::Convert) => {
                let entry = self.pop()?;
                entry.convert(base_type, self.addr_mask)?
            }
            EvaluationState::Waiting(EvaluationWaiting::Reinterpret) => {
                let entry = self.pop()?;
                entry.reinterpret(base_type, self.addr_mask)?
            }
            _ => panic!(
                "Called `Evaluation::resume_with_base_type` without a preceding `EvaluationResult::RequiresBaseType`"
            ),
        };
        self.push(value)?;
        self.evaluate_internal()
    }

    fn end_of_expression(&mut self) -> bool {
        while self.pc.is_empty() {
            match self.expression_stack.pop() {
                Some((newpc, newbytes)) => {
                    self.pc = newpc;
                    self.bytecode = newbytes;
                }
                None => return true,
            }
        }
        false
    }

    fn evaluate_internal(&mut self) -> Result<EvaluationResult<R>> {
        while !self.end_of_expression() {
            self.iteration += 1;
            if let Some(max_iterations) = self.max_iterations {
                if self.iteration > max_iterations {
                    return Err(Error::TooManyIterations);
                }
            }

            let op_result = self.evaluate_one_operation()?;
            match op_result {
                OperationEvaluationResult::Piece => {}
                OperationEvaluationResult::Incomplete => {
                    if self.end_of_expression() && !self.result.is_empty() {
                        // We saw a piece earlier and then some
                        // unterminated piece.  It's not clear this is
                        // well-defined.
                        return Err(Error::InvalidPiece);
                    }
                }
                OperationEvaluationResult::Complete { location } => {
                    if self.end_of_expression() {
                        if !self.result.is_empty() {
                            // We saw a piece earlier and then some
                            // unterminated piece.  It's not clear this is
                            // well-defined.
                            return Err(Error::InvalidPiece);
                        }
                        self.result
                            .try_push(Piece {
                                size_in_bits: None,
                                bit_offset: None,
                                location,
                            })
                            .map_err(|_| Error::StackFull)?;
                    } else {
                        // If there are more operations, then the next operation must
                        // be a Piece.
                        match Operation::parse(&mut self.pc, self.encoding)? {
                            Operation::Piece {
                                size_in_bits,
                                bit_offset,
                            } => {
                                self.result
                                    .try_push(Piece {
                                        size_in_bits: Some(size_in_bits),
                                        bit_offset,
                                        location,
                                    })
                                    .map_err(|_| Error::StackFull)?;
                            }
                            _ => {
                                let value =
                                    self.bytecode.len().into_u64() - self.pc.len().into_u64() - 1;
                                return Err(Error::InvalidExpressionTerminator(value));
                            }
                        }
                    }
                }
                OperationEvaluationResult::Waiting(waiting, result) => {
                    self.state = EvaluationState::Waiting(waiting);
                    return Ok(result);
                }
            }
        }

        // If no pieces have been seen, use the stack top as the
        // result.
        if self.result.is_empty() {
            let entry = self.pop()?;
            self.value_result = Some(entry);
            let addr = entry.to_u64(self.addr_mask)?;
            self.result
                .try_push(Piece {
                    size_in_bits: None,
                    bit_offset: None,
                    location: Location::Address { address: addr },
                })
                .map_err(|_| Error::StackFull)?;
        }

        self.state = EvaluationState::Complete;
        Ok(EvaluationResult::Complete)
    }
}

#[cfg(test)]
// Tests require leb128::write.
#[cfg(feature = "write")]
mod tests {
    use super::*;
    use crate::common::Format;
    use crate::constants;
    use crate::endianity::LittleEndian;
    use crate::leb128;
    use crate::read::{EndianSlice, Error, Result, UnitOffset};
    use crate::test_util::GimliSectionMethods;
    use core::usize;
    use test_assembler::{Endian, Section};

    fn encoding4() -> Encoding {
        Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        }
    }

    fn encoding8() -> Encoding {
        Encoding {
            format: Format::Dwarf64,
            version: 4,
            address_size: 8,
        }
    }

    #[test]
    fn test_compute_pc() {
        // Contents don't matter for this test, just length.
        let bytes = [0, 1, 2, 3, 4];
        let bytecode = &bytes[..];
        let ebuf = &EndianSlice::new(bytecode, LittleEndian);

        assert_eq!(compute_pc(ebuf, ebuf, 0), Ok(*ebuf));
        assert_eq!(
            compute_pc(ebuf, ebuf, -1),
            Err(Error::BadBranchTarget(usize::MAX as u64))
        );
        assert_eq!(compute_pc(ebuf, ebuf, 5), Ok(ebuf.range_from(5..)));
        assert_eq!(
            compute_pc(&ebuf.range_from(3..), ebuf, -2),
            Ok(ebuf.range_from(1..))
        );
        assert_eq!(
            compute_pc(&ebuf.range_from(2..), ebuf, 2),
            Ok(ebuf.range_from(4..))
        );
    }

    fn check_op_parse_simple<'input>(
        input: &'input [u8],
        expect: &Operation<EndianSlice<'input, LittleEndian>>,
        encoding: Encoding,
    ) {
        let buf = EndianSlice::new(input, LittleEndian);
        let mut pc = buf;
        let value = Operation::parse(&mut pc, encoding);
        match value {
            Ok(val) => {
                assert_eq!(val, *expect);
                assert_eq!(pc.len(), 0);
            }
            _ => panic!("Unexpected result"),
        }
    }

    fn check_op_parse_eof(input: &[u8], encoding: Encoding) {
        let buf = EndianSlice::new(input, LittleEndian);
        let mut pc = buf;
        match Operation::parse(&mut pc, encoding) {
            Err(Error::UnexpectedEof(id)) => {
                assert!(buf.lookup_offset_id(id).is_some());
            }

            _ => panic!("Unexpected result"),
        }
    }

    fn check_op_parse<F>(
        input: F,
        expect: &Operation<EndianSlice<LittleEndian>>,
        encoding: Encoding,
    ) where
        F: Fn(Section) -> Section,
    {
        let input = input(Section::with_endian(Endian::Little))
            .get_contents()
            .unwrap();
        for i in 1..input.len() {
            check_op_parse_eof(&input[..i], encoding);
        }
        check_op_parse_simple(&input, expect, encoding);
    }

    #[test]
    fn test_op_parse_onebyte() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        // Test all single-byte opcodes.
        #[rustfmt::skip]
        let inputs = [
            (
                constants::DW_OP_deref,
                Operation::Deref {
                    base_type: generic_type(),
                    size: encoding.address_size,
                    space: false,
                },
            ),
            (constants::DW_OP_dup, Operation::Pick { index: 0 }),
            (constants::DW_OP_drop, Operation::Drop),
            (constants::DW_OP_over, Operation::Pick { index: 1 }),
            (constants::DW_OP_swap, Operation::Swap),
            (constants::DW_OP_rot, Operation::Rot),
            (
                constants::DW_OP_xderef,
                Operation::Deref {
                    base_type: generic_type(),
                    size: encoding.address_size,
                    space: true,
                },
            ),
            (constants::DW_OP_abs, Operation::Abs),
            (constants::DW_OP_and, Operation::And),
            (constants::DW_OP_div, Operation::Div),
            (constants::DW_OP_minus, Operation::Minus),
            (constants::DW_OP_mod, Operation::Mod),
            (constants::DW_OP_mul, Operation::Mul),
            (constants::DW_OP_neg, Operation::Neg),
            (constants::DW_OP_not, Operation::Not),
            (constants::DW_OP_or, Operation::Or),
            (constants::DW_OP_plus, Operation::Plus),
            (constants::DW_OP_shl, Operation::Shl),
            (constants::DW_OP_shr, Operation::Shr),
            (constants::DW_OP_shra, Operation::Shra),
            (constants::DW_OP_xor, Operation::Xor),
            (constants::DW_OP_eq, Operation::Eq),
            (constants::DW_OP_ge, Operation::Ge),
            (constants::DW_OP_gt, Operation::Gt),
            (constants::DW_OP_le, Operation::Le),
            (constants::DW_OP_lt, Operation::Lt),
            (constants::DW_OP_ne, Operation::Ne),
            (constants::DW_OP_lit0, Operation::UnsignedConstant { value: 0 }),
            (constants::DW_OP_lit1, Operation::UnsignedConstant { value: 1 }),
            (constants::DW_OP_lit2, Operation::UnsignedConstant { value: 2 }),
            (constants::DW_OP_lit3, Operation::UnsignedConstant { value: 3 }),
            (constants::DW_OP_lit4, Operation::UnsignedConstant { value: 4 }),
            (constants::DW_OP_lit5, Operation::UnsignedConstant { value: 5 }),
            (constants::DW_OP_lit6, Operation::UnsignedConstant { value: 6 }),
            (constants::DW_OP_lit7, Operation::UnsignedConstant { value: 7 }),
            (constants::DW_OP_lit8, Operation::UnsignedConstant { value: 8 }),
            (constants::DW_OP_lit9, Operation::UnsignedConstant { value: 9 }),
            (constants::DW_OP_lit10, Operation::UnsignedConstant { value: 10 }),
            (constants::DW_OP_lit11, Operation::UnsignedConstant { value: 11 }),
            (constants::DW_OP_lit12, Operation::UnsignedConstant { value: 12 }),
            (constants::DW_OP_lit13, Operation::UnsignedConstant { value: 13 }),
            (constants::DW_OP_lit14, Operation::UnsignedConstant { value: 14 }),
            (constants::DW_OP_lit15, Operation::UnsignedConstant { value: 15 }),
            (constants::DW_OP_lit16, Operation::UnsignedConstant { value: 16 }),
            (constants::DW_OP_lit17, Operation::UnsignedConstant { value: 17 }),
            (constants::DW_OP_lit18, Operation::UnsignedConstant { value: 18 }),
            (constants::DW_OP_lit19, Operation::UnsignedConstant { value: 19 }),
            (constants::DW_OP_lit20, Operation::UnsignedConstant { value: 20 }),
            (constants::DW_OP_lit21, Operation::UnsignedConstant { value: 21 }),
            (constants::DW_OP_lit22, Operation::UnsignedConstant { value: 22 }),
            (constants::DW_OP_lit23, Operation::UnsignedConstant { value: 23 }),
            (constants::DW_OP_lit24, Operation::UnsignedConstant { value: 24 }),
            (constants::DW_OP_lit25, Operation::UnsignedConstant { value: 25 }),
            (constants::DW_OP_lit26, Operation::UnsignedConstant { value: 26 }),
            (constants::DW_OP_lit27, Operation::UnsignedConstant { value: 27 }),
            (constants::DW_OP_lit28, Operation::UnsignedConstant { value: 28 }),
            (constants::DW_OP_lit29, Operation::UnsignedConstant { value: 29 }),
            (constants::DW_OP_lit30, Operation::UnsignedConstant { value: 30 }),
            (constants::DW_OP_lit31, Operation::UnsignedConstant { value: 31 }),
            (constants::DW_OP_reg0, Operation::Register { register: Register(0) }),
            (constants::DW_OP_reg1, Operation::Register { register: Register(1) }),
            (constants::DW_OP_reg2, Operation::Register { register: Register(2) }),
            (constants::DW_OP_reg3, Operation::Register { register: Register(3) }),
            (constants::DW_OP_reg4, Operation::Register { register: Register(4) }),
            (constants::DW_OP_reg5, Operation::Register { register: Register(5) }),
            (constants::DW_OP_reg6, Operation::Register { register: Register(6) }),
            (constants::DW_OP_reg7, Operation::Register { register: Register(7) }),
            (constants::DW_OP_reg8, Operation::Register { register: Register(8) }),
            (constants::DW_OP_reg9, Operation::Register { register: Register(9) }),
            (constants::DW_OP_reg10, Operation::Register { register: Register(10) }),
            (constants::DW_OP_reg11, Operation::Register { register: Register(11) }),
            (constants::DW_OP_reg12, Operation::Register { register: Register(12) }),
            (constants::DW_OP_reg13, Operation::Register { register: Register(13) }),
            (constants::DW_OP_reg14, Operation::Register { register: Register(14) }),
            (constants::DW_OP_reg15, Operation::Register { register: Register(15) }),
            (constants::DW_OP_reg16, Operation::Register { register: Register(16) }),
            (constants::DW_OP_reg17, Operation::Register { register: Register(17) }),
            (constants::DW_OP_reg18, Operation::Register { register: Register(18) }),
            (constants::DW_OP_reg19, Operation::Register { register: Register(19) }),
            (constants::DW_OP_reg20, Operation::Register { register: Register(20) }),
            (constants::DW_OP_reg21, Operation::Register { register: Register(21) }),
            (constants::DW_OP_reg22, Operation::Register { register: Register(22) }),
            (constants::DW_OP_reg23, Operation::Register { register: Register(23) }),
            (constants::DW_OP_reg24, Operation::Register { register: Register(24) }),
            (constants::DW_OP_reg25, Operation::Register { register: Register(25) }),
            (constants::DW_OP_reg26, Operation::Register { register: Register(26) }),
            (constants::DW_OP_reg27, Operation::Register { register: Register(27) }),
            (constants::DW_OP_reg28, Operation::Register { register: Register(28) }),
            (constants::DW_OP_reg29, Operation::Register { register: Register(29) }),
            (constants::DW_OP_reg30, Operation::Register { register: Register(30) }),
            (constants::DW_OP_reg31, Operation::Register { register: Register(31) }),
            (constants::DW_OP_nop, Operation::Nop),
            (constants::DW_OP_push_object_address, Operation::PushObjectAddress),
            (constants::DW_OP_form_tls_address, Operation::TLS),
            (constants::DW_OP_GNU_push_tls_address, Operation::TLS),
            (constants::DW_OP_call_frame_cfa, Operation::CallFrameCFA),
            (constants::DW_OP_stack_value, Operation::StackValue),
        ];

        let input = [];
        check_op_parse_eof(&input[..], encoding);

        for item in inputs.iter() {
            let (opcode, ref result) = *item;
            check_op_parse(|s| s.D8(opcode.0), result, encoding);
        }
    }

    #[test]
    fn test_op_parse_twobyte() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        let inputs = [
            (
                constants::DW_OP_const1u,
                23,
                Operation::UnsignedConstant { value: 23 },
            ),
            (
                constants::DW_OP_const1s,
                (-23i8) as u8,
                Operation::SignedConstant { value: -23 },
            ),
            (constants::DW_OP_pick, 7, Operation::Pick { index: 7 }),
            (
                constants::DW_OP_deref_size,
                19,
                Operation::Deref {
                    base_type: generic_type(),
                    size: 19,
                    space: false,
                },
            ),
            (
                constants::DW_OP_xderef_size,
                19,
                Operation::Deref {
                    base_type: generic_type(),
                    size: 19,
                    space: true,
                },
            ),
        ];

        for item in inputs.iter() {
            let (opcode, arg, ref result) = *item;
            check_op_parse(|s| s.D8(opcode.0).D8(arg), result, encoding);
        }
    }

    #[test]
    fn test_op_parse_threebyte() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        // While bra and skip are 3-byte opcodes, they aren't tested here,
        // but rather specially in their own function.
        let inputs = [
            (
                constants::DW_OP_const2u,
                23,
                Operation::UnsignedConstant { value: 23 },
            ),
            (
                constants::DW_OP_const2s,
                (-23i16) as u16,
                Operation::SignedConstant { value: -23 },
            ),
            (
                constants::DW_OP_call2,
                1138,
                Operation::Call {
                    offset: DieReference::UnitRef(UnitOffset(1138)),
                },
            ),
            (
                constants::DW_OP_bra,
                (-23i16) as u16,
                Operation::Bra { target: -23 },
            ),
            (
                constants::DW_OP_skip,
                (-23i16) as u16,
                Operation::Skip { target: -23 },
            ),
        ];

        for item in inputs.iter() {
            let (opcode, arg, ref result) = *item;
            check_op_parse(|s| s.D8(opcode.0).L16(arg), result, encoding);
        }
    }

    #[test]
    fn test_op_parse_fivebyte() {
        // There are some tests here that depend on address size.
        let encoding = encoding4();

        let inputs = [
            (
                constants::DW_OP_addr,
                0x1234_5678,
                Operation::Address {
                    address: 0x1234_5678,
                },
            ),
            (
                constants::DW_OP_const4u,
                0x1234_5678,
                Operation::UnsignedConstant { value: 0x1234_5678 },
            ),
            (
                constants::DW_OP_const4s,
                (-23i32) as u32,
                Operation::SignedConstant { value: -23 },
            ),
            (
                constants::DW_OP_call4,
                0x1234_5678,
                Operation::Call {
                    offset: DieReference::UnitRef(UnitOffset(0x1234_5678)),
                },
            ),
            (
                constants::DW_OP_call_ref,
                0x1234_5678,
                Operation::Call {
                    offset: DieReference::DebugInfoRef(DebugInfoOffset(0x1234_5678)),
                },
            ),
        ];

        for item in inputs.iter() {
            let (op, arg, ref expect) = *item;
            check_op_parse(|s| s.D8(op.0).L32(arg), expect, encoding);
        }
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_op_parse_ninebyte() {
        // There are some tests here that depend on address size.
        let encoding = encoding8();

        let inputs = [
            (
                constants::DW_OP_addr,
                0x1234_5678_1234_5678,
                Operation::Address {
                    address: 0x1234_5678_1234_5678,
                },
            ),
            (
                constants::DW_OP_const8u,
                0x1234_5678_1234_5678,
                Operation::UnsignedConstant {
                    value: 0x1234_5678_1234_5678,
                },
            ),
            (
                constants::DW_OP_const8s,
                (-23i64) as u64,
                Operation::SignedConstant { value: -23 },
            ),
            (
                constants::DW_OP_call_ref,
                0x1234_5678_1234_5678,
                Operation::Call {
                    offset: DieReference::DebugInfoRef(DebugInfoOffset(0x1234_5678_1234_5678)),
                },
            ),
        ];

        for item in inputs.iter() {
            let (op, arg, ref expect) = *item;
            check_op_parse(|s| s.D8(op.0).L64(arg), expect, encoding);
        }
    }

    #[test]
    fn test_op_parse_sleb() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        let values = [
            -1i64,
            0,
            1,
            0x100,
            0x1eee_eeee,
            0x7fff_ffff_ffff_ffff,
            -0x100,
            -0x1eee_eeee,
            -0x7fff_ffff_ffff_ffff,
        ];
        for value in values.iter() {
            let mut inputs = vec![
                (
                    constants::DW_OP_consts.0,
                    Operation::SignedConstant { value: *value },
                ),
                (
                    constants::DW_OP_fbreg.0,
                    Operation::FrameOffset { offset: *value },
                ),
            ];

            for i in 0..32 {
                inputs.push((
                    constants::DW_OP_breg0.0 + i,
                    Operation::RegisterOffset {
                        register: Register(i.into()),
                        offset: *value,
                        base_type: UnitOffset(0),
                    },
                ));
            }

            for item in inputs.iter() {
                let (op, ref expect) = *item;
                check_op_parse(|s| s.D8(op).sleb(*value), expect, encoding);
            }
        }
    }

    #[test]
    fn test_op_parse_uleb() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        let values = [
            0,
            1,
            0x100,
            (!0u16).into(),
            0x1eee_eeee,
            0x7fff_ffff_ffff_ffff,
            !0u64,
        ];
        for value in values.iter() {
            let mut inputs = vec![
                (
                    constants::DW_OP_constu,
                    Operation::UnsignedConstant { value: *value },
                ),
                (
                    constants::DW_OP_plus_uconst,
                    Operation::PlusConstant { value: *value },
                ),
            ];

            if *value <= (!0u16).into() {
                inputs.push((
                    constants::DW_OP_regx,
                    Operation::Register {
                        register: Register::from_u64(*value).unwrap(),
                    },
                ));
            }

            if *value <= (!0u32).into() {
                inputs.extend(&[
                    (
                        constants::DW_OP_addrx,
                        Operation::AddressIndex {
                            index: DebugAddrIndex(*value as usize),
                        },
                    ),
                    (
                        constants::DW_OP_constx,
                        Operation::ConstantIndex {
                            index: DebugAddrIndex(*value as usize),
                        },
                    ),
                ]);
            }

            // FIXME
            if *value < !0u64 / 8 {
                inputs.push((
                    constants::DW_OP_piece,
                    Operation::Piece {
                        size_in_bits: 8 * value,
                        bit_offset: None,
                    },
                ));
            }

            for item in inputs.iter() {
                let (op, ref expect) = *item;
                let input = Section::with_endian(Endian::Little)
                    .D8(op.0)
                    .uleb(*value)
                    .get_contents()
                    .unwrap();
                check_op_parse_simple(&input, expect, encoding);
            }
        }
    }

    #[test]
    fn test_op_parse_bregx() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        let uvalues = [0, 1, 0x100, !0u16];
        let svalues = [
            -1i64,
            0,
            1,
            0x100,
            0x1eee_eeee,
            0x7fff_ffff_ffff_ffff,
            -0x100,
            -0x1eee_eeee,
            -0x7fff_ffff_ffff_ffff,
        ];

        for v1 in uvalues.iter() {
            for v2 in svalues.iter() {
                check_op_parse(
                    |s| s.D8(constants::DW_OP_bregx.0).uleb((*v1).into()).sleb(*v2),
                    &Operation::RegisterOffset {
                        register: Register(*v1),
                        offset: *v2,
                        base_type: UnitOffset(0),
                    },
                    encoding,
                );
            }
        }
    }

    #[test]
    fn test_op_parse_bit_piece() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        let values = [0, 1, 0x100, 0x1eee_eeee, 0x7fff_ffff_ffff_ffff, !0u64];

        for v1 in values.iter() {
            for v2 in values.iter() {
                let input = Section::with_endian(Endian::Little)
                    .D8(constants::DW_OP_bit_piece.0)
                    .uleb(*v1)
                    .uleb(*v2)
                    .get_contents()
                    .unwrap();
                check_op_parse_simple(
                    &input,
                    &Operation::Piece {
                        size_in_bits: *v1,
                        bit_offset: Some(*v2),
                    },
                    encoding,
                );
            }
        }
    }

    #[test]
    fn test_op_parse_implicit_value() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        let data = b"hello";

        check_op_parse(
            |s| {
                s.D8(constants::DW_OP_implicit_value.0)
                    .uleb(data.len() as u64)
                    .append_bytes(&data[..])
            },
            &Operation::ImplicitValue {
                data: EndianSlice::new(&data[..], LittleEndian),
            },
            encoding,
        );
    }

    #[test]
    fn test_op_parse_const_type() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        let data = b"hello";

        check_op_parse(
            |s| {
                s.D8(constants::DW_OP_const_type.0)
                    .uleb(100)
                    .D8(data.len() as u8)
                    .append_bytes(&data[..])
            },
            &Operation::TypedLiteral {
                base_type: UnitOffset(100),
                value: EndianSlice::new(&data[..], LittleEndian),
            },
            encoding,
        );
        check_op_parse(
            |s| {
                s.D8(constants::DW_OP_GNU_const_type.0)
                    .uleb(100)
                    .D8(data.len() as u8)
                    .append_bytes(&data[..])
            },
            &Operation::TypedLiteral {
                base_type: UnitOffset(100),
                value: EndianSlice::new(&data[..], LittleEndian),
            },
            encoding,
        );
    }

    #[test]
    fn test_op_parse_regval_type() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        check_op_parse(
            |s| s.D8(constants::DW_OP_regval_type.0).uleb(1).uleb(100),
            &Operation::RegisterOffset {
                register: Register(1),
                offset: 0,
                base_type: UnitOffset(100),
            },
            encoding,
        );
        check_op_parse(
            |s| s.D8(constants::DW_OP_GNU_regval_type.0).uleb(1).uleb(100),
            &Operation::RegisterOffset {
                register: Register(1),
                offset: 0,
                base_type: UnitOffset(100),
            },
            encoding,
        );
    }

    #[test]
    fn test_op_parse_deref_type() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        check_op_parse(
            |s| s.D8(constants::DW_OP_deref_type.0).D8(8).uleb(100),
            &Operation::Deref {
                base_type: UnitOffset(100),
                size: 8,
                space: false,
            },
            encoding,
        );
        check_op_parse(
            |s| s.D8(constants::DW_OP_GNU_deref_type.0).D8(8).uleb(100),
            &Operation::Deref {
                base_type: UnitOffset(100),
                size: 8,
                space: false,
            },
            encoding,
        );
        check_op_parse(
            |s| s.D8(constants::DW_OP_xderef_type.0).D8(8).uleb(100),
            &Operation::Deref {
                base_type: UnitOffset(100),
                size: 8,
                space: true,
            },
            encoding,
        );
    }

    #[test]
    fn test_op_convert() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        check_op_parse(
            |s| s.D8(constants::DW_OP_convert.0).uleb(100),
            &Operation::Convert {
                base_type: UnitOffset(100),
            },
            encoding,
        );
        check_op_parse(
            |s| s.D8(constants::DW_OP_GNU_convert.0).uleb(100),
            &Operation::Convert {
                base_type: UnitOffset(100),
            },
            encoding,
        );
    }

    #[test]
    fn test_op_reinterpret() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        check_op_parse(
            |s| s.D8(constants::DW_OP_reinterpret.0).uleb(100),
            &Operation::Reinterpret {
                base_type: UnitOffset(100),
            },
            encoding,
        );
        check_op_parse(
            |s| s.D8(constants::DW_OP_GNU_reinterpret.0).uleb(100),
            &Operation::Reinterpret {
                base_type: UnitOffset(100),
            },
            encoding,
        );
    }

    #[test]
    fn test_op_parse_implicit_pointer() {
        for op in &[
            constants::DW_OP_implicit_pointer,
            constants::DW_OP_GNU_implicit_pointer,
        ] {
            check_op_parse(
                |s| s.D8(op.0).D32(0x1234_5678).sleb(0x123),
                &Operation::ImplicitPointer {
                    value: DebugInfoOffset(0x1234_5678),
                    byte_offset: 0x123,
                },
                encoding4(),
            );

            check_op_parse(
                |s| s.D8(op.0).D64(0x1234_5678).sleb(0x123),
                &Operation::ImplicitPointer {
                    value: DebugInfoOffset(0x1234_5678),
                    byte_offset: 0x123,
                },
                encoding8(),
            );

            check_op_parse(
                |s| s.D8(op.0).D64(0x1234_5678).sleb(0x123),
                &Operation::ImplicitPointer {
                    value: DebugInfoOffset(0x1234_5678),
                    byte_offset: 0x123,
                },
                Encoding {
                    format: Format::Dwarf32,
                    version: 2,
                    address_size: 8,
                },
            )
        }
    }

    #[test]
    fn test_op_parse_entry_value() {
        for op in &[
            constants::DW_OP_entry_value,
            constants::DW_OP_GNU_entry_value,
        ] {
            let data = b"hello";
            check_op_parse(
                |s| s.D8(op.0).uleb(data.len() as u64).append_bytes(&data[..]),
                &Operation::EntryValue {
                    expression: EndianSlice::new(&data[..], LittleEndian),
                },
                encoding4(),
            );
        }
    }

    #[test]
    fn test_op_parse_gnu_parameter_ref() {
        check_op_parse(
            |s| s.D8(constants::DW_OP_GNU_parameter_ref.0).D32(0x1234_5678),
            &Operation::ParameterRef {
                offset: UnitOffset(0x1234_5678),
            },
            encoding4(),
        )
    }

    #[test]
    fn test_op_wasm() {
        // Doesn't matter for this test.
        let encoding = encoding4();

        check_op_parse(
            |s| s.D8(constants::DW_OP_WASM_location.0).D8(0).uleb(1000),
            &Operation::WasmLocal { index: 1000 },
            encoding,
        );
        check_op_parse(
            |s| s.D8(constants::DW_OP_WASM_location.0).D8(1).uleb(1000),
            &Operation::WasmGlobal { index: 1000 },
            encoding,
        );
        check_op_parse(
            |s| s.D8(constants::DW_OP_WASM_location.0).D8(2).uleb(1000),
            &Operation::WasmStack { index: 1000 },
            encoding,
        );
        check_op_parse(
            |s| s.D8(constants::DW_OP_WASM_location.0).D8(3).D32(1000),
            &Operation::WasmGlobal { index: 1000 },
            encoding,
        );
    }

    enum AssemblerEntry {
        Op(constants::DwOp),
        Mark(u8),
        Branch(u8),
        U8(u8),
        U16(u16),
        U32(u32),
        U64(u64),
        Uleb(u64),
        Sleb(u64),
    }

    fn assemble(entries: &[AssemblerEntry]) -> Vec<u8> {
        let mut result = Vec::new();

        struct Marker(Option<usize>, Vec<usize>);

        let mut markers = Vec::new();
        for _ in 0..256 {
            markers.push(Marker(None, Vec::new()));
        }

        fn write(stack: &mut Vec<u8>, index: usize, mut num: u64, nbytes: u8) {
            for i in 0..nbytes as usize {
                stack[index + i] = (num & 0xff) as u8;
                num >>= 8;
            }
        }

        fn push(stack: &mut Vec<u8>, num: u64, nbytes: u8) {
            let index = stack.len();
            for _ in 0..nbytes {
                stack.push(0);
            }
            write(stack, index, num, nbytes);
        }

        for item in entries {
            match *item {
                AssemblerEntry::Op(op) => result.push(op.0),
                AssemblerEntry::Mark(num) => {
                    assert!(markers[num as usize].0.is_none());
                    markers[num as usize].0 = Some(result.len());
                }
                AssemblerEntry::Branch(num) => {
                    markers[num as usize].1.push(result.len());
                    push(&mut result, 0, 2);
                }
                AssemblerEntry::U8(num) => result.push(num),
                AssemblerEntry::U16(num) => push(&mut result, u64::from(num), 2),
                AssemblerEntry::U32(num) => push(&mut result, u64::from(num), 4),
                AssemblerEntry::U64(num) => push(&mut result, num, 8),
                AssemblerEntry::Uleb(num) => {
                    leb128::write::unsigned(&mut result, num).unwrap();
                }
                AssemblerEntry::Sleb(num) => {
                    leb128::write::signed(&mut result, num as i64).unwrap();
                }
            }
        }

        // Update all the branches.
        for marker in markers {
            if let Some(offset) = marker.0 {
                for branch_offset in marker.1 {
                    let delta = offset.wrapping_sub(branch_offset + 2) as u64;
                    write(&mut result, branch_offset, delta, 2);
                }
            }
        }

        result
    }

    fn check_eval_with_args<F>(
        program: &[AssemblerEntry],
        expect: Result<&[Piece<EndianSlice<LittleEndian>>]>,
        encoding: Encoding,
        object_address: Option<u64>,
        initial_value: Option<u64>,
        max_iterations: Option<u32>,
        f: F,
    ) where
        for<'a> F: Fn(
            &mut Evaluation<EndianSlice<'a, LittleEndian>>,
            EvaluationResult<EndianSlice<'a, LittleEndian>>,
        ) -> Result<EvaluationResult<EndianSlice<'a, LittleEndian>>>,
    {
        let bytes = assemble(program);
        let bytes = EndianSlice::new(&bytes, LittleEndian);

        let mut eval = Evaluation::new(bytes, encoding);

        if let Some(val) = object_address {
            eval.set_object_address(val);
        }
        if let Some(val) = initial_value {
            eval.set_initial_value(val);
        }
        if let Some(val) = max_iterations {
            eval.set_max_iterations(val);
        }

        let result = match eval.evaluate() {
            Err(e) => Err(e),
            Ok(r) => f(&mut eval, r),
        };

        match (result, expect) {
            (Ok(EvaluationResult::Complete), Ok(pieces)) => {
                let vec = eval.result();
                assert_eq!(vec.len(), pieces.len());
                for i in 0..pieces.len() {
                    assert_eq!(vec[i], pieces[i]);
                }
            }
            (Err(f1), Err(f2)) => {
                assert_eq!(f1, f2);
            }
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        }
    }

    fn check_eval(
        program: &[AssemblerEntry],
        expect: Result<&[Piece<EndianSlice<LittleEndian>>]>,
        encoding: Encoding,
    ) {
        check_eval_with_args(program, expect, encoding, None, None, None, |_, result| {
            Ok(result)
        });
    }

    #[test]
    fn test_eval_arith() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        // Indices of marks in the assembly.
        let done = 0;
        let fail = 1;

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_const1u), U8(23),
            Op(DW_OP_const1s), U8((-23i8) as u8),
            Op(DW_OP_plus),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const2u), U16(23),
            Op(DW_OP_const2s), U16((-23i16) as u16),
            Op(DW_OP_plus),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const4u), U32(0x1111_2222),
            Op(DW_OP_const4s), U32((-0x1111_2222i32) as u32),
            Op(DW_OP_plus),
            Op(DW_OP_bra), Branch(fail),

            // Plus should overflow.
            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_const1u), U8(1),
            Op(DW_OP_plus),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_plus_uconst), Uleb(1),
            Op(DW_OP_bra), Branch(fail),

            // Minus should underflow.
            Op(DW_OP_const1s), U8(0),
            Op(DW_OP_const1u), U8(1),
            Op(DW_OP_minus),
            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_abs),
            Op(DW_OP_const1u), U8(1),
            Op(DW_OP_minus),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const4u), U32(0xf078_fffe),
            Op(DW_OP_const4u), U32(0x0f87_0001),
            Op(DW_OP_and),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const4u), U32(0xf078_fffe),
            Op(DW_OP_const4u), U32(0xf000_00fe),
            Op(DW_OP_and),
            Op(DW_OP_const4u), U32(0xf000_00fe),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            // Division is signed.
            Op(DW_OP_const1s), U8(0xfe),
            Op(DW_OP_const1s), U8(2),
            Op(DW_OP_div),
            Op(DW_OP_plus_uconst), Uleb(1),
            Op(DW_OP_bra), Branch(fail),

            // Mod is unsigned.
            Op(DW_OP_const1s), U8(0xfd),
            Op(DW_OP_const1s), U8(2),
            Op(DW_OP_mod),
            Op(DW_OP_neg),
            Op(DW_OP_plus_uconst), Uleb(1),
            Op(DW_OP_bra), Branch(fail),

            // Overflow is defined for multiplication.
            Op(DW_OP_const4u), U32(0x8000_0001),
            Op(DW_OP_lit2),
            Op(DW_OP_mul),
            Op(DW_OP_lit2),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const4u), U32(0xf0f0_f0f0),
            Op(DW_OP_const4u), U32(0xf0f0_f0f0),
            Op(DW_OP_xor),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const4u), U32(0xf0f0_f0f0),
            Op(DW_OP_const4u), U32(0x0f0f_0f0f),
            Op(DW_OP_or),
            Op(DW_OP_not),
            Op(DW_OP_bra), Branch(fail),

            // In 32 bit mode, values are truncated.
            Op(DW_OP_const8u), U64(0xffff_ffff_0000_0000),
            Op(DW_OP_lit2),
            Op(DW_OP_div),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1u), U8(0xff),
            Op(DW_OP_lit1),
            Op(DW_OP_shl),
            Op(DW_OP_const2u), U16(0x1fe),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1u), U8(0xff),
            Op(DW_OP_const1u), U8(50),
            Op(DW_OP_shl),
            Op(DW_OP_bra), Branch(fail),

            // Absurd shift.
            Op(DW_OP_const1u), U8(0xff),
            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_shl),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_lit1),
            Op(DW_OP_shr),
            Op(DW_OP_const4u), U32(0x7fff_ffff),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_const1u), U8(0xff),
            Op(DW_OP_shr),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_lit1),
            Op(DW_OP_shra),
            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_const1u), U8(0xff),
            Op(DW_OP_shra),
            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            // Success.
            Op(DW_OP_lit0),
            Op(DW_OP_nop),
            Op(DW_OP_skip), Branch(done),

            Mark(fail),
            Op(DW_OP_lit1),

            Mark(done),
            Op(DW_OP_stack_value),
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Value {
                value: Value::Generic(0),
            },
        }];

        check_eval(&program, Ok(&result), encoding4());
    }

    #[test]
    fn test_eval_arith64() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        // Indices of marks in the assembly.
        let done = 0;
        let fail = 1;

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_const8u), U64(0x1111_2222_3333_4444),
            Op(DW_OP_const8s), U64((-0x1111_2222_3333_4444i64) as u64),
            Op(DW_OP_plus),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_constu), Uleb(0x1111_2222_3333_4444),
            Op(DW_OP_consts), Sleb((-0x1111_2222_3333_4444i64) as u64),
            Op(DW_OP_plus),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_lit1),
            Op(DW_OP_plus_uconst), Uleb(!0u64),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_lit1),
            Op(DW_OP_neg),
            Op(DW_OP_not),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const8u), U64(0x8000_0000_0000_0000),
            Op(DW_OP_const1u), U8(63),
            Op(DW_OP_shr),
            Op(DW_OP_lit1),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const8u), U64(0x8000_0000_0000_0000),
            Op(DW_OP_const1u), U8(62),
            Op(DW_OP_shra),
            Op(DW_OP_plus_uconst), Uleb(2),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_lit1),
            Op(DW_OP_const1u), U8(63),
            Op(DW_OP_shl),
            Op(DW_OP_const8u), U64(0x8000_0000_0000_0000),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            // Success.
            Op(DW_OP_lit0),
            Op(DW_OP_nop),
            Op(DW_OP_skip), Branch(done),

            Mark(fail),
            Op(DW_OP_lit1),

            Mark(done),
            Op(DW_OP_stack_value),
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Value {
                value: Value::Generic(0),
            },
        }];

        check_eval(&program, Ok(&result), encoding8());
    }

    #[test]
    fn test_eval_compare() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        // Indices of marks in the assembly.
        let done = 0;
        let fail = 1;

        #[rustfmt::skip]
        let program = [
            // Comparisons are signed.
            Op(DW_OP_const1s), U8(1),
            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_lt),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_const1s), U8(1),
            Op(DW_OP_gt),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1s), U8(1),
            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_le),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_const1s), U8(1),
            Op(DW_OP_ge),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const1s), U8(0xff),
            Op(DW_OP_const1s), U8(1),
            Op(DW_OP_eq),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_const4s), U32(1),
            Op(DW_OP_const1s), U8(1),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            // Success.
            Op(DW_OP_lit0),
            Op(DW_OP_nop),
            Op(DW_OP_skip), Branch(done),

            Mark(fail),
            Op(DW_OP_lit1),

            Mark(done),
            Op(DW_OP_stack_value),
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Value {
                value: Value::Generic(0),
            },
        }];

        check_eval(&program, Ok(&result), encoding4());
    }

    #[test]
    fn test_eval_stack() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_lit17),                // -- 17
            Op(DW_OP_dup),                  // -- 17 17
            Op(DW_OP_over),                 // -- 17 17 17
            Op(DW_OP_minus),                // -- 17 0
            Op(DW_OP_swap),                 // -- 0 17
            Op(DW_OP_dup),                  // -- 0 17 17
            Op(DW_OP_plus_uconst), Uleb(1), // -- 0 17 18
            Op(DW_OP_rot),                  // -- 18 0 17
            Op(DW_OP_pick), U8(2),          // -- 18 0 17 18
            Op(DW_OP_pick), U8(3),          // -- 18 0 17 18 18
            Op(DW_OP_minus),                // -- 18 0 17 0
            Op(DW_OP_drop),                 // -- 18 0 17
            Op(DW_OP_swap),                 // -- 18 17 0
            Op(DW_OP_drop),                 // -- 18 17
            Op(DW_OP_minus),                // -- 1
            Op(DW_OP_stack_value),
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Value {
                value: Value::Generic(1),
            },
        }];

        check_eval(&program, Ok(&result), encoding4());
    }

    #[test]
    fn test_eval_lit_and_reg() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        let mut program = Vec::new();
        program.push(Op(DW_OP_lit0));
        for i in 0..32 {
            program.push(Op(DwOp(DW_OP_lit0.0 + i)));
            program.push(Op(DwOp(DW_OP_breg0.0 + i)));
            program.push(Sleb(u64::from(i)));
            program.push(Op(DW_OP_plus));
            program.push(Op(DW_OP_plus));
        }

        program.push(Op(DW_OP_bregx));
        program.push(Uleb(0x1234));
        program.push(Sleb(0x1234));
        program.push(Op(DW_OP_plus));

        program.push(Op(DW_OP_stack_value));

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Value {
                value: Value::Generic(496),
            },
        }];

        check_eval_with_args(
            &program,
            Ok(&result),
            encoding4(),
            None,
            None,
            None,
            |eval, mut result| {
                while result != EvaluationResult::Complete {
                    result = eval.resume_with_register(match result {
                        EvaluationResult::RequiresRegister {
                            register,
                            base_type,
                        } => {
                            assert_eq!(base_type, UnitOffset(0));
                            Value::Generic(u64::from(register.0).wrapping_neg())
                        }
                        _ => panic!(),
                    })?;
                }
                Ok(result)
            },
        );
    }

    #[test]
    fn test_eval_memory() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        // Indices of marks in the assembly.
        let done = 0;
        let fail = 1;

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_addr), U32(0x7fff_ffff),
            Op(DW_OP_deref),
            Op(DW_OP_const4u), U32(0xffff_fffc),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_addr), U32(0x7fff_ffff),
            Op(DW_OP_deref_size), U8(2),
            Op(DW_OP_const4u), U32(0xfffc),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_lit1),
            Op(DW_OP_addr), U32(0x7fff_ffff),
            Op(DW_OP_xderef),
            Op(DW_OP_const4u), U32(0xffff_fffd),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_lit1),
            Op(DW_OP_addr), U32(0x7fff_ffff),
            Op(DW_OP_xderef_size), U8(2),
            Op(DW_OP_const4u), U32(0xfffd),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_lit17),
            Op(DW_OP_form_tls_address),
            Op(DW_OP_constu), Uleb(!17),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_lit17),
            Op(DW_OP_GNU_push_tls_address),
            Op(DW_OP_constu), Uleb(!17),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_addrx), Uleb(0x10),
            Op(DW_OP_deref),
            Op(DW_OP_const4u), U32(0x4040),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            Op(DW_OP_constx), Uleb(17),
            Op(DW_OP_form_tls_address),
            Op(DW_OP_constu), Uleb(!27),
            Op(DW_OP_ne),
            Op(DW_OP_bra), Branch(fail),

            // Success.
            Op(DW_OP_lit0),
            Op(DW_OP_nop),
            Op(DW_OP_skip), Branch(done),

            Mark(fail),
            Op(DW_OP_lit1),

            Mark(done),
            Op(DW_OP_stack_value),
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Value {
                value: Value::Generic(0),
            },
        }];

        check_eval_with_args(
            &program,
            Ok(&result),
            encoding4(),
            None,
            None,
            None,
            |eval, mut result| {
                while result != EvaluationResult::Complete {
                    result = match result {
                        EvaluationResult::RequiresMemory {
                            address,
                            size,
                            space,
                            base_type,
                        } => {
                            assert_eq!(base_type, UnitOffset(0));
                            let mut v = address << 2;
                            if let Some(value) = space {
                                v += value;
                            }
                            v &= (1u64 << (8 * size)) - 1;
                            eval.resume_with_memory(Value::Generic(v))?
                        }
                        EvaluationResult::RequiresTls(slot) => eval.resume_with_tls(!slot)?,
                        EvaluationResult::RequiresRelocatedAddress(address) => {
                            eval.resume_with_relocated_address(address)?
                        }
                        EvaluationResult::RequiresIndexedAddress { index, relocate } => {
                            if relocate {
                                eval.resume_with_indexed_address(0x1000 + index.0 as u64)?
                            } else {
                                eval.resume_with_indexed_address(10 + index.0 as u64)?
                            }
                        }
                        _ => panic!(),
                    };
                }

                Ok(result)
            },
        );
    }

    #[test]
    fn test_eval_register() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        for i in 0..32 {
            #[rustfmt::skip]
            let program = [
                Op(DwOp(DW_OP_reg0.0 + i)),
                // Included only in the "bad" run.
                Op(DW_OP_lit23),
            ];
            let ok_result = [Piece {
                size_in_bits: None,
                bit_offset: None,
                location: Location::Register {
                    register: Register(i.into()),
                },
            }];

            check_eval(&program[..1], Ok(&ok_result), encoding4());

            check_eval(
                &program,
                Err(Error::InvalidExpressionTerminator(1)),
                encoding4(),
            );
        }

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_regx), Uleb(0x1234)
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Register {
                register: Register(0x1234),
            },
        }];

        check_eval(&program, Ok(&result), encoding4());
    }

    #[test]
    fn test_eval_context() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        // Test `frame_base` and `call_frame_cfa` callbacks.
        #[rustfmt::skip]
        let program = [
            Op(DW_OP_fbreg), Sleb((-8i8) as u64),
            Op(DW_OP_call_frame_cfa),
            Op(DW_OP_plus),
            Op(DW_OP_neg),
            Op(DW_OP_stack_value)
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Value {
                value: Value::Generic(9),
            },
        }];

        check_eval_with_args(
            &program,
            Ok(&result),
            encoding8(),
            None,
            None,
            None,
            |eval, result| {
                match result {
                    EvaluationResult::RequiresFrameBase => {}
                    _ => panic!(),
                };
                match eval.resume_with_frame_base(0x0123_4567_89ab_cdef)? {
                    EvaluationResult::RequiresCallFrameCfa => {}
                    _ => panic!(),
                };
                eval.resume_with_call_frame_cfa(0xfedc_ba98_7654_3210)
            },
        );

        // Test `evaluate_entry_value` callback.
        #[rustfmt::skip]
        let program = [
            Op(DW_OP_entry_value), Uleb(8), U64(0x1234_5678),
            Op(DW_OP_stack_value)
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Value {
                value: Value::Generic(0x1234_5678),
            },
        }];

        check_eval_with_args(
            &program,
            Ok(&result),
            encoding8(),
            None,
            None,
            None,
            |eval, result| {
                let entry_value = match result {
                    EvaluationResult::RequiresEntryValue(mut expression) => {
                        expression.0.read_u64()?
                    }
                    _ => panic!(),
                };
                eval.resume_with_entry_value(Value::Generic(entry_value))
            },
        );

        // Test missing `object_address` field.
        #[rustfmt::skip]
        let program = [
            Op(DW_OP_push_object_address),
        ];

        check_eval_with_args(
            &program,
            Err(Error::InvalidPushObjectAddress),
            encoding4(),
            None,
            None,
            None,
            |_, _| panic!(),
        );

        // Test `object_address` field.
        #[rustfmt::skip]
        let program = [
            Op(DW_OP_push_object_address),
            Op(DW_OP_stack_value),
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Value {
                value: Value::Generic(0xff),
            },
        }];

        check_eval_with_args(
            &program,
            Ok(&result),
            encoding8(),
            Some(0xff),
            None,
            None,
            |_, result| Ok(result),
        );

        // Test `initial_value` field.
        #[rustfmt::skip]
        let program = [
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Address {
                address: 0x1234_5678,
            },
        }];

        check_eval_with_args(
            &program,
            Ok(&result),
            encoding8(),
            None,
            Some(0x1234_5678),
            None,
            |_, result| Ok(result),
        );
    }

    #[test]
    fn test_eval_empty_stack() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_stack_value)
        ];

        check_eval(&program, Err(Error::NotEnoughStackItems), encoding4());
    }

    #[test]
    fn test_eval_call() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_lit23),
            Op(DW_OP_call2), U16(0x7755),
            Op(DW_OP_call4), U32(0x7755_aaee),
            Op(DW_OP_call_ref), U32(0x7755_aaee),
            Op(DW_OP_stack_value)
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Value {
                value: Value::Generic(23),
            },
        }];

        check_eval_with_args(
            &program,
            Ok(&result),
            encoding4(),
            None,
            None,
            None,
            |eval, result| {
                let buf = EndianSlice::new(&[], LittleEndian);
                match result {
                    EvaluationResult::RequiresAtLocation(_) => {}
                    _ => panic!(),
                };

                eval.resume_with_at_location(buf)?;

                match result {
                    EvaluationResult::RequiresAtLocation(_) => {}
                    _ => panic!(),
                };

                eval.resume_with_at_location(buf)?;

                match result {
                    EvaluationResult::RequiresAtLocation(_) => {}
                    _ => panic!(),
                };

                eval.resume_with_at_location(buf)
            },
        );

        // DW_OP_lit2 DW_OP_mul
        const SUBR: &[u8] = &[0x32, 0x1e];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Value {
                value: Value::Generic(184),
            },
        }];

        check_eval_with_args(
            &program,
            Ok(&result),
            encoding4(),
            None,
            None,
            None,
            |eval, result| {
                let buf = EndianSlice::new(SUBR, LittleEndian);
                match result {
                    EvaluationResult::RequiresAtLocation(_) => {}
                    _ => panic!(),
                };

                eval.resume_with_at_location(buf)?;

                match result {
                    EvaluationResult::RequiresAtLocation(_) => {}
                    _ => panic!(),
                };

                eval.resume_with_at_location(buf)?;

                match result {
                    EvaluationResult::RequiresAtLocation(_) => {}
                    _ => panic!(),
                };

                eval.resume_with_at_location(buf)
            },
        );
    }

    #[test]
    fn test_eval_pieces() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        // Example from DWARF 2.6.1.3.
        #[rustfmt::skip]
        let program = [
            Op(DW_OP_reg3),
            Op(DW_OP_piece), Uleb(4),
            Op(DW_OP_reg4),
            Op(DW_OP_piece), Uleb(2),
        ];

        let result = [
            Piece {
                size_in_bits: Some(32),
                bit_offset: None,
                location: Location::Register {
                    register: Register(3),
                },
            },
            Piece {
                size_in_bits: Some(16),
                bit_offset: None,
                location: Location::Register {
                    register: Register(4),
                },
            },
        ];

        check_eval(&program, Ok(&result), encoding4());

        // Example from DWARF 2.6.1.3 (but hacked since dealing with fbreg
        // in the tests is a pain).
        #[rustfmt::skip]
        let program = [
            Op(DW_OP_reg0),
            Op(DW_OP_piece), Uleb(4),
            Op(DW_OP_piece), Uleb(4),
            Op(DW_OP_addr), U32(0x7fff_ffff),
            Op(DW_OP_piece), Uleb(4),
        ];

        let result = [
            Piece {
                size_in_bits: Some(32),
                bit_offset: None,
                location: Location::Register {
                    register: Register(0),
                },
            },
            Piece {
                size_in_bits: Some(32),
                bit_offset: None,
                location: Location::Empty,
            },
            Piece {
                size_in_bits: Some(32),
                bit_offset: None,
                location: Location::Address {
                    address: 0x7fff_ffff,
                },
            },
        ];

        check_eval_with_args(
            &program,
            Ok(&result),
            encoding4(),
            None,
            None,
            None,
            |eval, mut result| {
                while result != EvaluationResult::Complete {
                    result = match result {
                        EvaluationResult::RequiresRelocatedAddress(address) => {
                            eval.resume_with_relocated_address(address)?
                        }
                        _ => panic!(),
                    };
                }

                Ok(result)
            },
        );

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_implicit_value), Uleb(5),
            U8(23), U8(24), U8(25), U8(26), U8(0),
        ];

        const BYTES: &[u8] = &[23, 24, 25, 26, 0];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Bytes {
                value: EndianSlice::new(BYTES, LittleEndian),
            },
        }];

        check_eval(&program, Ok(&result), encoding4());

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_lit7),
            Op(DW_OP_stack_value),
            Op(DW_OP_bit_piece), Uleb(5), Uleb(0),
            Op(DW_OP_bit_piece), Uleb(3), Uleb(0),
        ];

        let result = [
            Piece {
                size_in_bits: Some(5),
                bit_offset: Some(0),
                location: Location::Value {
                    value: Value::Generic(7),
                },
            },
            Piece {
                size_in_bits: Some(3),
                bit_offset: Some(0),
                location: Location::Empty,
            },
        ];

        check_eval(&program, Ok(&result), encoding4());

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_lit7),
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::Address { address: 7 },
        }];

        check_eval(&program, Ok(&result), encoding4());

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_implicit_pointer), U32(0x1234_5678), Sleb(0x123),
        ];

        let result = [Piece {
            size_in_bits: None,
            bit_offset: None,
            location: Location::ImplicitPointer {
                value: DebugInfoOffset(0x1234_5678),
                byte_offset: 0x123,
            },
        }];

        check_eval(&program, Ok(&result), encoding4());

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_reg3),
            Op(DW_OP_piece), Uleb(4),
            Op(DW_OP_reg4),
        ];

        check_eval(&program, Err(Error::InvalidPiece), encoding4());

        #[rustfmt::skip]
        let program = [
            Op(DW_OP_reg3),
            Op(DW_OP_piece), Uleb(4),
            Op(DW_OP_lit0),
        ];

        check_eval(&program, Err(Error::InvalidPiece), encoding4());
    }

    #[test]
    fn test_eval_max_iterations() {
        // It's nice if an operation and its arguments can fit on a single
        // line in the test program.
        use self::AssemblerEntry::*;
        use crate::constants::*;

        #[rustfmt::skip]
        let program = [
            Mark(1),
            Op(DW_OP_skip), Branch(1),
        ];

        check_eval_with_args(
            &program,
            Err(Error::TooManyIterations),
            encoding4(),
            None,
            None,
            Some(150),
            |_, _| panic!(),
        );
    }

    #[test]
    fn test_eval_typed_stack() {
        use self::AssemblerEntry::*;
        use crate::constants::*;

        let base_types = [
            ValueType::Generic,
            ValueType::U16,
            ValueType::U32,
            ValueType::F32,
        ];

        // TODO: convert, reinterpret
        #[rustfmt::skip]
        let tests = [
            (
                &[
                    Op(DW_OP_const_type), Uleb(1), U8(2), U16(0x1234),
                    Op(DW_OP_stack_value),
                ][..],
                Value::U16(0x1234),
            ),
            (
                &[
                    Op(DW_OP_regval_type), Uleb(0x1234), Uleb(1),
                    Op(DW_OP_stack_value),
                ][..],
                Value::U16(0x2340),
            ),
            (
                &[
                    Op(DW_OP_addr), U32(0x7fff_ffff),
                    Op(DW_OP_deref_type), U8(2), Uleb(1),
                    Op(DW_OP_stack_value),
                ][..],
                Value::U16(0xfff0),
            ),
            (
                &[
                    Op(DW_OP_lit1),
                    Op(DW_OP_addr), U32(0x7fff_ffff),
                    Op(DW_OP_xderef_type), U8(2), Uleb(1),
                    Op(DW_OP_stack_value),
                ][..],
                Value::U16(0xfff1),
            ),
            (
                &[
                    Op(DW_OP_const_type), Uleb(1), U8(2), U16(0x1234),
                    Op(DW_OP_convert), Uleb(2),
                    Op(DW_OP_stack_value),
                ][..],
                Value::U32(0x1234),
            ),
            (
                &[
                    Op(DW_OP_const_type), Uleb(2), U8(4), U32(0x3f80_0000),
                    Op(DW_OP_reinterpret), Uleb(3),
                    Op(DW_OP_stack_value),
                ][..],
                Value::F32(1.0),
            ),
        ];
        for &(program, value) in &tests {
            let result = [Piece {
                size_in_bits: None,
                bit_offset: None,
                location: Location::Value { value },
            }];

            check_eval_with_args(
                program,
                Ok(&result),
                encoding4(),
                None,
                None,
                None,
                |eval, mut result| {
                    while result != EvaluationResult::Complete {
                        result = match result {
                            EvaluationResult::RequiresMemory {
                                address,
                                size,
                                space,
                                base_type,
                            } => {
                                let mut v = address << 4;
                                if let Some(value) = space {
                                    v += value;
                                }
                                v &= (1u64 << (8 * size)) - 1;
                                let v = Value::from_u64(base_types[base_type.0], v)?;
                                eval.resume_with_memory(v)?
                            }
                            EvaluationResult::RequiresRegister {
                                register,
                                base_type,
                            } => {
                                let v = Value::from_u64(
                                    base_types[base_type.0],
                                    u64::from(register.0) << 4,
                                )?;
                                eval.resume_with_register(v)?
                            }
                            EvaluationResult::RequiresBaseType(offset) => {
                                eval.resume_with_base_type(base_types[offset.0])?
                            }
                            EvaluationResult::RequiresRelocatedAddress(address) => {
                                eval.resume_with_relocated_address(address)?
                            }
                            _ => panic!("Unexpected result {:?}", result),
                        }
                    }
                    Ok(result)
                },
            );
        }
    }
}
