Merge branch 'main' into pch/wasi_error_handling

This commit is contained in:
Pat Hickey
2020-08-26 17:26:03 -07:00
committed by GitHub
6 changed files with 404 additions and 50 deletions

4
Cargo.lock generated
View File

@@ -2287,9 +2287,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-smith" name = "wasm-smith"
version = "0.1.1" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ec52a2524c15abcc827e59c1eef9cdb742b4ba57a6db6a1ccd914e357326edd" checksum = "2e09385df967070eaaf1c959f0c506a6df4a4a05ccab79d23651dcfd31e642df"
dependencies = [ dependencies = [
"arbitrary", "arbitrary",
"leb128", "leb128",

View File

@@ -179,10 +179,8 @@ impl<'a> Lexer<'a> {
// Starting from `lookahead`, are we looking at a number? // Starting from `lookahead`, are we looking at a number?
fn looking_at_numeric(&self) -> bool { fn looking_at_numeric(&self) -> bool {
if let Some(c) = self.lookahead { if let Some(c) = self.lookahead {
if c.is_digit(10) {
return true;
}
match c { match c {
'0'..='9' => return true,
'-' => return true, '-' => return true,
'+' => return true, '+' => return true,
'.' => return true, '.' => return true,
@@ -291,7 +289,7 @@ impl<'a> Lexer<'a> {
match self.next_ch() { match self.next_ch() {
Some('-') | Some('_') => {} Some('-') | Some('_') => {}
Some('.') => is_float = true, Some('.') => is_float = true,
Some(ch) if ch.is_alphanumeric() => {} Some('0'..='9') | Some('a'..='z') | Some('A'..='Z') => {}
_ => break, _ => break,
} }
} }
@@ -309,11 +307,10 @@ impl<'a> Lexer<'a> {
let begin = self.pos; let begin = self.pos;
let loc = self.loc(); let loc = self.loc();
assert!(self.lookahead == Some('_') || self.lookahead.unwrap().is_alphabetic()); assert!(self.lookahead == Some('_') || self.lookahead.unwrap().is_ascii_alphabetic());
loop { loop {
match self.next_ch() { match self.next_ch() {
Some('_') => {} Some('_') | Some('0'..='9') | Some('a'..='z') | Some('A'..='Z') => {}
Some(ch) if ch.is_alphanumeric() => {}
_ => break, _ => break,
} }
} }
@@ -398,9 +395,10 @@ impl<'a> Lexer<'a> {
assert_eq!(self.lookahead, Some('%')); assert_eq!(self.lookahead, Some('%'));
while let Some(c) = self.next_ch() { loop {
if !(c.is_ascii() && c.is_alphanumeric() || c == '_') { match self.next_ch() {
break; Some('_') | Some('0'..='9') | Some('a'..='z') | Some('A'..='Z') => {}
_ => break,
} }
} }
@@ -490,8 +488,8 @@ impl<'a> Lexer<'a> {
Some(self.scan_number()) Some(self.scan_number())
} }
} }
Some(ch) if ch.is_digit(10) => Some(self.scan_number()), Some('0'..='9') => Some(self.scan_number()),
Some(ch) if ch.is_alphabetic() => { Some('a'..='z') | Some('A'..='Z') => {
if self.looking_at("NaN") || self.looking_at("Inf") { if self.looking_at("NaN") || self.looking_at("Inf") {
Some(self.scan_number()) Some(self.scan_number())
} else { } else {
@@ -502,7 +500,8 @@ impl<'a> Lexer<'a> {
Some('"') => Some(self.scan_string()), Some('"') => Some(self.scan_string()),
Some('#') => Some(self.scan_hex_sequence()), Some('#') => Some(self.scan_hex_sequence()),
Some('@') => Some(self.scan_srcloc()), Some('@') => Some(self.scan_srcloc()),
Some(ch) if ch.is_whitespace() => { // all ascii whitespace
Some(' ') | Some('\x09'..='\x0d') => {
self.next_ch(); self.next_ch();
continue; continue;
} }

View File

@@ -445,7 +445,7 @@ impl<'a> Parser<'a> {
// running. I don't think this is true - self.lookahead is mutated in the loop body - so // running. I don't think this is true - self.lookahead is mutated in the loop body - so
// maybe this is a clippy bug? Either way, disable clippy for this. // maybe this is a clippy bug? Either way, disable clippy for this.
#[cfg_attr(feature = "cargo-clippy", allow(clippy::while_immutable_condition))] #[cfg_attr(feature = "cargo-clippy", allow(clippy::while_immutable_condition))]
while self.lookahead == None { while self.lookahead.is_none() {
match self.lex.next() { match self.lex.next() {
Some(Ok(LocatedToken { token, location })) => { Some(Ok(LocatedToken { token, location })) => {
match token { match token {

View File

@@ -2,7 +2,10 @@ use super::address_transform::AddressTransform;
use anyhow::{Context, Error, Result}; use anyhow::{Context, Error, Result};
use gimli::{self, write, Expression, Operation, Reader, ReaderOffset, X86_64}; use gimli::{self, write, Expression, Operation, Reader, ReaderOffset, X86_64};
use more_asserts::{assert_le, assert_lt}; use more_asserts::{assert_le, assert_lt};
use std::cmp::PartialEq;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::hash::{Hash, Hasher};
use std::rc::Rc;
use wasmtime_environ::entity::EntityRef; use wasmtime_environ::entity::EntityRef;
use wasmtime_environ::ir::{StackSlots, ValueLabel, ValueLabelsRanges, ValueLoc}; use wasmtime_environ::ir::{StackSlots, ValueLabel, ValueLabelsRanges, ValueLoc};
use wasmtime_environ::isa::TargetIsa; use wasmtime_environ::isa::TargetIsa;
@@ -88,9 +91,19 @@ enum CompiledExpressionPart {
// The wasm-local DWARF operator. The label points to `ValueLabel`. // The wasm-local DWARF operator. The label points to `ValueLabel`.
// The trailing field denotes that the operator was last in sequence, // The trailing field denotes that the operator was last in sequence,
// and it is the DWARF location (not a pointer). // and it is the DWARF location (not a pointer).
Local { label: ValueLabel, trailing: bool }, Local {
label: ValueLabel,
trailing: bool,
},
// Dereference is needed. // Dereference is needed.
Deref, Deref,
// Jumping in the expression.
Jump {
conditionally: bool,
target: JumpTargetMarker,
},
// Floating landing pad.
LandingPad(JumpTargetMarker),
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@@ -288,7 +301,9 @@ impl CompiledExpression {
let mut ranges_builder = ValueLabelRangesBuilder::new(scope, addr_tr, frame_info); let mut ranges_builder = ValueLabelRangesBuilder::new(scope, addr_tr, frame_info);
for p in self.parts.iter() { for p in self.parts.iter() {
match p { match p {
CompiledExpressionPart::Code(_) => (), CompiledExpressionPart::Code(_)
| CompiledExpressionPart::Jump { .. }
| CompiledExpressionPart::LandingPad { .. } => (),
CompiledExpressionPart::Local { label, .. } => ranges_builder.process_label(*label), CompiledExpressionPart::Local { label, .. } => ranges_builder.process_label(*label),
CompiledExpressionPart::Deref => ranges_builder.process_label(vmctx_label), CompiledExpressionPart::Deref => ranges_builder.process_label(vmctx_label),
} }
@@ -310,6 +325,9 @@ impl CompiledExpression {
}| { }| {
// build expression // build expression
let mut code_buf = Vec::new(); let mut code_buf = Vec::new();
let mut jump_positions = Vec::new();
let mut landing_positions = HashMap::new();
macro_rules! deref { macro_rules! deref {
() => { () => {
if let (Some(vmctx_loc), Some(frame_info)) = if let (Some(vmctx_loc), Some(frame_info)) =
@@ -333,6 +351,24 @@ impl CompiledExpression {
CompiledExpressionPart::Code(c) => { CompiledExpressionPart::Code(c) => {
code_buf.extend_from_slice(c.as_slice()) code_buf.extend_from_slice(c.as_slice())
} }
CompiledExpressionPart::LandingPad(marker) => {
landing_positions.insert(marker.clone(), code_buf.len());
}
CompiledExpressionPart::Jump {
conditionally,
target,
} => {
code_buf.push(
match conditionally {
true => gimli::constants::DW_OP_bra,
false => gimli::constants::DW_OP_skip,
}
.0 as u8,
);
code_buf.push(!0);
code_buf.push(!0); // these will be relocated below
jump_positions.push((target.clone(), code_buf.len()));
}
CompiledExpressionPart::Local { label, trailing } => { CompiledExpressionPart::Local { label, trailing } => {
let loc = let loc =
*label_location.get(&label).context("label_location")?; *label_location.get(&label).context("label_location")?;
@@ -350,6 +386,15 @@ impl CompiledExpression {
if self.need_deref { if self.need_deref {
deref!(); deref!();
} }
for (marker, new_from) in jump_positions {
// relocate jump targets
let new_to = landing_positions[&marker];
let new_diff = new_to as isize - new_from as isize;
// FIXME: use encoding? LittleEndian for now...
&code_buf[new_from - 2..new_from]
.copy_from_slice(&(new_diff as i16).to_le_bytes());
}
Ok(Some((func_index, start, end, code_buf))) Ok(Some((func_index, start, end, code_buf)))
}, },
) )
@@ -376,9 +421,35 @@ pub fn compile_expression<R>(
where where
R: Reader, R: Reader,
{ {
// Bail when `frame_base` is complicated.
if let Some(expr) = frame_base {
if expr.parts.iter().any(|p| match p {
CompiledExpressionPart::Jump { .. } => true,
_ => false,
}) {
return Ok(None);
}
}
// jump_targets key is offset in buf starting from the end
// (see also `unread_bytes` below)
let mut jump_targets: HashMap<u64, JumpTargetMarker> = HashMap::new();
let mut pc = expr.0.clone(); let mut pc = expr.0.clone();
let buf = expr.0.to_slice()?; let buf = expr.0.to_slice()?;
let mut parts = Vec::new(); let mut parts = Vec::new();
macro_rules! push {
($part:expr) => {{
let part = $part;
if let (CompiledExpressionPart::Code(cc2), Some(CompiledExpressionPart::Code(cc1))) =
(&part, parts.last_mut())
{
cc1.extend_from_slice(cc2);
} else {
parts.push(part)
}
}};
}
let mut need_deref = false; let mut need_deref = false;
if is_old_expression_format(&buf) && frame_base.is_some() { if is_old_expression_format(&buf) && frame_base.is_some() {
// Still supporting old DWARF variable expressions without fbreg. // Still supporting old DWARF variable expressions without fbreg.
@@ -388,17 +459,41 @@ where
} }
need_deref = frame_base.unwrap().need_deref; need_deref = frame_base.unwrap().need_deref;
} }
let base_len = parts.len();
let mut code_chunk = Vec::new(); let mut code_chunk = Vec::new();
macro_rules! flush_code_chunk { macro_rules! flush_code_chunk {
() => { () => {
if !code_chunk.is_empty() { if !code_chunk.is_empty() {
parts.push(CompiledExpressionPart::Code(code_chunk)); push!(CompiledExpressionPart::Code(code_chunk));
code_chunk = Vec::new(); code_chunk = Vec::new();
let _ = code_chunk; // suppresses warning for final flush
} }
}; };
}; };
// Find all landing pads by scanning bytes, do not care about
// false location at this moment.
// Looks hacky but it is fast; does not need to be really exact.
for i in 0..buf.len() - 2 {
let op = buf[i];
if op == gimli::constants::DW_OP_bra.0 || op == gimli::constants::DW_OP_skip.0 {
// TODO fix for big-endian
let offset = i16::from_le_bytes([buf[i + 1], buf[i + 2]]);
let origin = i + 3;
// Discarding out-of-bounds jumps (also some of falsely detected ops)
if (offset >= 0 && offset as usize + origin <= buf.len())
|| (offset < 0 && -offset as usize <= origin)
{
let target = buf.len() as isize - origin as isize - offset as isize;
jump_targets.insert(target as u64, JumpTargetMarker::new());
}
}
}
while !pc.is_empty() { while !pc.is_empty() {
let unread_bytes = pc.len().into_u64();
if let Some(marker) = jump_targets.get(&unread_bytes) {
flush_code_chunk!();
parts.push(CompiledExpressionPart::LandingPad(marker.clone()));
}
let next = buf[pc.offset_from(&expr.0).into_u64() as usize]; let next = buf[pc.offset_from(&expr.0).into_u64() as usize];
need_deref = true; need_deref = true;
if next == 0xED { if next == 0xED {
@@ -413,7 +508,7 @@ where
let index = pc.read_sleb128()?; let index = pc.read_sleb128()?;
flush_code_chunk!(); flush_code_chunk!();
let label = ValueLabel::from_u32(index as u32); let label = ValueLabel::from_u32(index as u32);
parts.push(CompiledExpressionPart::Local { push!(CompiledExpressionPart::Local {
label, label,
trailing: false, trailing: false,
}); });
@@ -439,10 +534,58 @@ where
code_chunk.extend(writer.into_vec()); code_chunk.extend(writer.into_vec());
continue; continue;
} }
Operation::UnsignedConstant { .. } Operation::Drop { .. }
| Operation::Pick { .. }
| Operation::Swap { .. }
| Operation::Rot { .. }
| Operation::Nop { .. }
| Operation::UnsignedConstant { .. }
| Operation::SignedConstant { .. } | Operation::SignedConstant { .. }
| Operation::ConstantIndex { .. }
| Operation::PlusConstant { .. } | Operation::PlusConstant { .. }
| Operation::Abs { .. }
| Operation::And { .. }
| Operation::Or { .. }
| Operation::Xor { .. }
| Operation::Shr { .. }
| Operation::Shra { .. }
| Operation::Shl { .. }
| Operation::Plus { .. }
| Operation::Minus { .. }
| Operation::Div { .. }
| Operation::Mod { .. }
| Operation::Mul { .. }
| Operation::Neg { .. }
| Operation::Not { .. }
| Operation::Lt { .. }
| Operation::Gt { .. }
| Operation::Le { .. }
| Operation::Ge { .. }
| Operation::Eq { .. }
| Operation::Ne { .. }
| Operation::TypedLiteral { .. }
| Operation::Convert { .. }
| Operation::Reinterpret { .. }
| Operation::Piece { .. } => (), | Operation::Piece { .. } => (),
Operation::Bra { target } | Operation::Skip { target } => {
flush_code_chunk!();
let arc_to = (pc.len().into_u64() as isize - target as isize) as u64;
let marker = match jump_targets.get(&arc_to) {
Some(m) => m.clone(),
None => {
// Marker not found: probably out of bounds.
return Ok(None);
}
};
push!(CompiledExpressionPart::Jump {
conditionally: match op {
Operation::Bra { .. } => true,
_ => false,
},
target: marker,
});
continue;
}
Operation::StackValue => { Operation::StackValue => {
need_deref = false; need_deref = false;
@@ -457,11 +600,22 @@ where
} }
Operation::Deref { .. } => { Operation::Deref { .. } => {
flush_code_chunk!(); flush_code_chunk!();
parts.push(CompiledExpressionPart::Deref); push!(CompiledExpressionPart::Deref);
// Don't re-enter the loop here (i.e. continue), because the // Don't re-enter the loop here (i.e. continue), because the
// DW_OP_deref still needs to be kept. // DW_OP_deref still needs to be kept.
} }
_ => { Operation::Address { .. }
| Operation::AddressIndex { .. }
| Operation::Call { .. }
| Operation::Register { .. }
| Operation::RegisterOffset { .. }
| Operation::CallFrameCFA
| Operation::PushObjectAddress
| Operation::TLS
| Operation::ImplicitValue { .. }
| Operation::ImplicitPointer { .. }
| Operation::EntryValue { .. }
| Operation::ParameterRef { .. } => {
return Ok(None); return Ok(None);
} }
} }
@@ -470,20 +624,9 @@ where
} }
} }
if !code_chunk.is_empty() { flush_code_chunk!();
parts.push(CompiledExpressionPart::Code(code_chunk)); if let Some(marker) = jump_targets.get(&0) {
} parts.push(CompiledExpressionPart::LandingPad(marker.clone()));
if base_len > 0 && base_len + 1 < parts.len() {
// see if we can glue two code chunks
if let [CompiledExpressionPart::Code(cc1), CompiledExpressionPart::Code(cc2)] =
&parts[base_len..=base_len]
{
let mut combined = cc1.clone();
combined.extend_from_slice(cc2);
parts[base_len] = CompiledExpressionPart::Code(combined);
parts.remove(base_len + 1);
}
} }
Ok(Some(CompiledExpression { parts, need_deref })) Ok(Some(CompiledExpression { parts, need_deref }))
@@ -602,10 +745,49 @@ impl<'a, 'b> ValueLabelRangesBuilder<'a, 'b> {
} }
} }
/// Marker for tracking incoming jumps.
/// Different when created new, and the same when cloned.
#[derive(Clone, Eq)]
struct JumpTargetMarker(Rc<u32>);
impl JumpTargetMarker {
fn new() -> JumpTargetMarker {
// Create somewhat unique hash data -- using part of
// the pointer of the RcBox.
let mut rc = Rc::new(0);
let hash_data = rc.as_ref() as *const u32 as usize as u32;
*Rc::get_mut(&mut rc).unwrap() = hash_data;
JumpTargetMarker(rc)
}
}
impl PartialEq for JumpTargetMarker {
fn eq(&self, other: &JumpTargetMarker) -> bool {
Rc::ptr_eq(&self.0, &other.0)
}
}
impl Hash for JumpTargetMarker {
fn hash<H: Hasher>(&self, hasher: &mut H) {
hasher.write_u32(*self.0);
}
}
impl std::fmt::Debug for JumpTargetMarker {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
write!(
f,
"JumpMarker<{:08x}>",
self.0.as_ref() as *const u32 as usize
)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::compile_expression; use super::{
use super::{AddressTransform, FunctionFrameInfo, ValueLabel, ValueLabelsRanges}; compile_expression, AddressTransform, CompiledExpression, CompiledExpressionPart,
FunctionFrameInfo, JumpTargetMarker, ValueLabel, ValueLabelsRanges,
};
use gimli::{self, constants, Encoding, EndianSlice, Expression, RunTimeEndian}; use gimli::{self, constants, Encoding, EndianSlice, Expression, RunTimeEndian};
use wasmtime_environ::CompiledFunction; use wasmtime_environ::CompiledFunction;
@@ -619,6 +801,9 @@ mod tests {
($d:ident) => { ($d:ident) => {
constants::$d.0 as u8 constants::$d.0 as u8
}; };
($e:expr) => {
$e as u8
};
} }
macro_rules! expression { macro_rules! expression {
@@ -630,15 +815,38 @@ mod tests {
} }
} }
fn find_jump_targets<'a>(ce: &'a CompiledExpression) -> Vec<&'a JumpTargetMarker> {
ce.parts
.iter()
.filter_map(|p| {
if let CompiledExpressionPart::LandingPad(t) = p {
Some(t)
} else {
None
}
})
.collect::<Vec<_>>()
}
static DWARF_ENCODING: Encoding = Encoding { static DWARF_ENCODING: Encoding = Encoding {
address_size: 4, address_size: 4,
format: gimli::Format::Dwarf32, format: gimli::Format::Dwarf32,
version: 4, version: 4,
}; };
#[test]
fn test_debug_expression_jump_target() {
let m1 = JumpTargetMarker::new();
let m2 = JumpTargetMarker::new();
assert!(m1 != m2);
assert!(m1 == m1.clone());
// Internal hash_data test (theoretically can fail intermittently).
assert!(m1.0 != m2.0);
}
#[test] #[test]
fn test_debug_parse_expressions() { fn test_debug_parse_expressions() {
use super::{CompiledExpression, CompiledExpressionPart};
use wasmtime_environ::entity::EntityRef; use wasmtime_environ::entity::EntityRef;
let (val1, val3, val20) = (ValueLabel::new(1), ValueLabel::new(3), ValueLabel::new(20)); let (val1, val3, val20) = (ValueLabel::new(1), ValueLabel::new(3), ValueLabel::new(20));
@@ -654,7 +862,7 @@ mod tests {
label: val20, label: val20,
trailing: true trailing: true
}], }],
need_deref: false need_deref: false,
} }
); );
@@ -679,7 +887,7 @@ mod tests {
}, },
CompiledExpressionPart::Code(vec![35, 16, 159]) CompiledExpressionPart::Code(vec![35, 16, 159])
], ],
need_deref: false need_deref: false,
} }
); );
@@ -699,7 +907,7 @@ mod tests {
}, },
CompiledExpressionPart::Code(vec![35, 18]) CompiledExpressionPart::Code(vec![35, 18])
], ],
need_deref: true need_deref: true,
} }
); );
@@ -727,7 +935,158 @@ mod tests {
CompiledExpressionPart::Deref, CompiledExpressionPart::Deref,
CompiledExpressionPart::Code(vec![6, 159]) CompiledExpressionPart::Code(vec![6, 159])
], ],
need_deref: false need_deref: false,
}
);
let e = expression!(
DW_OP_lit1,
DW_OP_dup,
DW_OP_WASM_location,
0x0,
1,
DW_OP_and,
DW_OP_bra,
5,
0, // --> pointer
DW_OP_swap,
DW_OP_shr,
DW_OP_skip,
2,
0, // --> done
// pointer:
DW_OP_plus,
DW_OP_deref,
// done:
DW_OP_stack_value
);
let ce = compile_expression(&e, DWARF_ENCODING, None)
.expect("non-error")
.expect("expression");
let targets = find_jump_targets(&ce);
assert_eq!(targets.len(), 2);
assert_eq!(
ce,
CompiledExpression {
parts: vec![
CompiledExpressionPart::Code(vec![49, 18]),
CompiledExpressionPart::Local {
label: val1,
trailing: false
},
CompiledExpressionPart::Code(vec![26]),
CompiledExpressionPart::Jump {
conditionally: true,
target: targets[0].clone(),
},
CompiledExpressionPart::Code(vec![22, 37]),
CompiledExpressionPart::Jump {
conditionally: false,
target: targets[1].clone(),
},
CompiledExpressionPart::LandingPad(targets[0].clone()), // capture from
CompiledExpressionPart::Code(vec![34]),
CompiledExpressionPart::Deref,
CompiledExpressionPart::Code(vec![6]),
CompiledExpressionPart::LandingPad(targets[1].clone()), // capture to
CompiledExpressionPart::Code(vec![159])
],
need_deref: false,
}
);
let e = expression!(
DW_OP_lit1,
DW_OP_dup,
DW_OP_bra,
2,
0, // --> target
DW_OP_deref,
DW_OP_lit0,
// target:
DW_OP_stack_value
);
let ce = compile_expression(&e, DWARF_ENCODING, None)
.expect("non-error")
.expect("expression");
let targets = find_jump_targets(&ce);
assert_eq!(targets.len(), 1);
assert_eq!(
ce,
CompiledExpression {
parts: vec![
CompiledExpressionPart::Code(vec![49, 18]),
CompiledExpressionPart::Jump {
conditionally: true,
target: targets[0].clone(),
},
CompiledExpressionPart::Deref,
CompiledExpressionPart::Code(vec![6, 48]),
CompiledExpressionPart::LandingPad(targets[0].clone()), // capture to
CompiledExpressionPart::Code(vec![159])
],
need_deref: false,
}
);
let e = expression!(
DW_OP_lit1,
/* loop */ DW_OP_dup,
DW_OP_lit25,
DW_OP_ge,
DW_OP_bra,
5,
0, // --> done
DW_OP_plus_uconst,
1,
DW_OP_skip,
(-11 as i8),
(!0), // --> loop
/* done */ DW_OP_stack_value
);
let ce = compile_expression(&e, DWARF_ENCODING, None)
.expect("non-error")
.expect("expression");
let targets = find_jump_targets(&ce);
assert_eq!(targets.len(), 2);
assert_eq!(
ce,
CompiledExpression {
parts: vec![
CompiledExpressionPart::Code(vec![49]),
CompiledExpressionPart::LandingPad(targets[0].clone()),
CompiledExpressionPart::Code(vec![18, 73, 42]),
CompiledExpressionPart::Jump {
conditionally: true,
target: targets[1].clone(),
},
CompiledExpressionPart::Code(vec![35, 1]),
CompiledExpressionPart::Jump {
conditionally: false,
target: targets[0].clone(),
},
CompiledExpressionPart::LandingPad(targets[1].clone()),
CompiledExpressionPart::Code(vec![159])
],
need_deref: false,
}
);
let e = expression!(DW_OP_WASM_location, 0x0, 1, DW_OP_plus_uconst, 5);
let ce = compile_expression(&e, DWARF_ENCODING, None)
.expect("non-error")
.expect("expression");
assert_eq!(
ce,
CompiledExpression {
parts: vec![
CompiledExpressionPart::Local {
label: val1,
trailing: false
},
CompiledExpressionPart::Code(vec![35, 5])
],
need_deref: true,
} }
); );
} }

View File

@@ -171,10 +171,6 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
fn fd_filestat_set_size(&self, fd: types::Fd, size: types::Filesize) -> Result<()> { fn fd_filestat_set_size(&self, fd: types::Fd, size: types::Filesize) -> Result<()> {
let required_rights = HandleRights::from_base(types::Rights::FD_FILESTAT_SET_SIZE); let required_rights = HandleRights::from_base(types::Rights::FD_FILESTAT_SET_SIZE);
let entry = self.get_entry(fd)?; let entry = self.get_entry(fd)?;
// This check will be unnecessary when rust-lang/rust#63326 is fixed
if size > i64::max_value() as u64 {
return Err(Error::TooBig);
}
entry.as_handle(&required_rights)?.filestat_set_size(size) entry.as_handle(&required_rights)?.filestat_set_size(size)
} }

View File

@@ -17,7 +17,7 @@ target-lexicon = "0.10"
peepmatic-fuzzing = { path = "../cranelift/peepmatic/crates/fuzzing", optional = true } peepmatic-fuzzing = { path = "../cranelift/peepmatic/crates/fuzzing", optional = true }
wasmtime = { path = "../crates/wasmtime" } wasmtime = { path = "../crates/wasmtime" }
wasmtime-fuzzing = { path = "../crates/fuzzing" } wasmtime-fuzzing = { path = "../crates/fuzzing" }
wasm-smith = "0.1.1" wasm-smith = "0.1.2"
[[bin]] [[bin]]
name = "compile" name = "compile"