Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update wasmparser to 0.59 #172

Merged
merged 1 commit into from Jul 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -29,7 +29,7 @@ leb128 = "0.2.4"
log = "0.4.8"
rayon = { version = "1.1.0", optional = true }
walrus-macro = { path = './crates/macro', version = '=0.17.0' }
wasmparser = "0.55.0"
wasmparser = "0.59.0"

[features]
parallel = ['rayon', 'id-arena/rayon']
Expand Down
2 changes: 1 addition & 1 deletion crates/fuzz-utils/Cargo.toml
Expand Up @@ -10,7 +10,7 @@ anyhow = "1.0"
env_logger = "0.7.0"
rand = { version = "0.7.0", features = ['small_rng'] }
tempfile = "3.1.0"
wasmparser = "0.55"
wasmparser = "0.59"
wat = "1.0"

[dependencies.walrus]
Expand Down
2 changes: 1 addition & 1 deletion crates/fuzz-utils/src/lib.rs
Expand Up @@ -417,7 +417,7 @@ impl TestCaseGenerator for WasmOptTtf {

// Only generate programs that wat2wasm can handle.
if let Ok(bytes) = wat::parse_bytes(&wat) {
if wasmparser::validate(&bytes, None).is_ok() {
if wasmparser::validate(&bytes).is_ok() {
return String::from_utf8(wat).unwrap();
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/tests/tests/round_trip/anyref1.wat
@@ -1,6 +1,6 @@
(module
(import "x" "y" (func (param anyref)))
(func (export "a") (param anyref)
(import "x" "y" (func (param externref)))
(func (export "a") (param externref)
local.get 0
call 0))

Expand Down
4 changes: 2 additions & 2 deletions crates/tests/tests/round_trip/anyref2.wat
@@ -1,6 +1,6 @@
(module
(table 1 anyref)
(func (export "a") (param i32) (result anyref)
(table 1 externref)
(func (export "a") (param i32) (result externref)
local.get 0
table.get 0))

Expand Down
6 changes: 3 additions & 3 deletions crates/tests/tests/round_trip/anyref3.wat
@@ -1,8 +1,8 @@
(module
(type (func))
(table 1 anyfunc)
(table 1 anyref)
(func (export "a") (param i32) (result anyref)
(table 1 funcref)
(table 1 externref)
(func (export "a") (param i32) (result externref)
local.get 0
call_indirect (type 0)
local.get 0
Expand Down
11 changes: 5 additions & 6 deletions src/ir/mod.rs
Expand Up @@ -527,12 +527,8 @@ pub enum Instr {
ty: ValType,
},

/// `ref.is_null $ty`
RefIsNull {
/// The type of value we're testing for null
#[walrus(skip_visit)]
ty: ValType,
},
/// `ref.is_null`
RefIsNull {},

/// `ref.func`
RefFunc {
Expand Down Expand Up @@ -946,14 +942,17 @@ pub enum UnaryOp {
I8x16Neg,
I8x16AnyTrue,
I8x16AllTrue,
I8x16Bitmask,
I16x8Abs,
I16x8Neg,
I16x8AnyTrue,
I16x8AllTrue,
I16x8Bitmask,
I32x4Abs,
I32x4Neg,
I32x4AnyTrue,
I32x4AllTrue,
I32x4Bitmask,
I64x2Neg,

F32x4Abs,
Expand Down
9 changes: 2 additions & 7 deletions src/module/data.rs
Expand Up @@ -185,20 +185,15 @@ impl Module {
&mut self,
section: wasmparser::DataSectionReader,
ids: &IndicesToIds,
data_count: Option<u32>,
) -> Result<()> {
log::debug!("parse data section");
if let Some(count) = data_count {
if count != section.get_count() {
bail!("data count section mismatches actual data section");
}
}
let preallocated = self.data.arena.len() > 0;
for (i, segment) in section.into_iter().enumerate() {
let segment = segment?;

// If we had the `DataCount` section, then we already pre-allocated
// a data segment. Otherwise, allocate one now.
let id = if data_count.is_some() {
let id = if preallocated {
ids.get_data(i as u32)?
} else {
self.data.arena.alloc_with_id(|id| Data {
Expand Down
3 changes: 3 additions & 0 deletions src/module/exports.rs
Expand Up @@ -142,6 +142,9 @@ impl Module {
Table => ExportItem::Table(ids.get_table(entry.index)?),
Memory => ExportItem::Memory(ids.get_memory(entry.index)?),
Global => ExportItem::Global(ids.get_global(entry.index)?),
Type | Module | Instance => {
unimplemented!("module linking not supported");
}
};
self.exports.arena.alloc_with_id(|id| Export {
id,
Expand Down
6 changes: 4 additions & 2 deletions src/module/functions/local_function/emit.rs
Expand Up @@ -498,11 +498,13 @@ impl<'instr> Visitor<'instr> for Emit<'_, '_> {
I8x16Neg => self.simd(0x61),
I8x16AnyTrue => self.simd(0x62),
I8x16AllTrue => self.simd(0x63),
I8x16Bitmask => self.simd(0x64),

I16x8Abs => self.simd(0x80),
I16x8Neg => self.simd(0x81),
I16x8AnyTrue => self.simd(0x82),
I16x8AllTrue => self.simd(0x83),
I16x8Bitmask => self.simd(0x84),
I16x8WidenLowI8x16S => self.simd(0x87),
I16x8WidenHighI8x16S => self.simd(0x88),
I16x8WidenLowI8x16U => self.simd(0x89),
Expand All @@ -512,6 +514,7 @@ impl<'instr> Visitor<'instr> for Emit<'_, '_> {
I32x4Neg => self.simd(0xa1),
I32x4AnyTrue => self.simd(0xa2),
I32x4AllTrue => self.simd(0xa3),
I32x4Bitmask => self.simd(0xa4),
I32x4WidenLowI16x8S => self.simd(0xa7),
I32x4WidenHighI16x8S => self.simd(0xa8),
I32x4WidenLowI16x8U => self.simd(0xa9),
Expand Down Expand Up @@ -802,9 +805,8 @@ impl<'instr> Visitor<'instr> for Emit<'_, '_> {
self.encoder.byte(0xd0);
e.ty.emit(self.encoder);
}
RefIsNull(e) => {
RefIsNull(_e) => {
self.encoder.byte(0xd1);
e.ty.emit(self.encoder);
}
RefFunc(e) => {
self.encoder.byte(0xd2);
Expand Down
15 changes: 11 additions & 4 deletions src/module/functions/local_function/mod.rs
Expand Up @@ -1198,10 +1198,9 @@ fn validate_instruction<'context>(
ctx.alloc_instr(RefNull { ty }, loc);
ctx.push_operand(Some(ty));
}
Operator::RefIsNull { ty } => {
let ty = ValType::parse(&ty)?;
ctx.pop_operand_expected(Some(ty))?;
ctx.alloc_instr(RefIsNull { ty }, loc);
Operator::RefIsNull => {
// ctx.pop_operand_expected(Some(ty))?;
ctx.alloc_instr(RefIsNull {}, loc);
ctx.push_operand(Some(I32));
}
Operator::RefFunc { function_index } => {
Expand Down Expand Up @@ -1462,6 +1461,10 @@ fn validate_instruction<'context>(
Operator::I32x4MaxS => binop(ctx, V128, BinaryOp::I32x4MaxS)?,
Operator::I32x4MaxU => binop(ctx, V128, BinaryOp::I32x4MaxU)?,

Operator::I8x16Bitmask => one_op(ctx, V128, I32, UnaryOp::I8x16Bitmask)?,
Operator::I16x8Bitmask => one_op(ctx, V128, I32, UnaryOp::I16x8Bitmask)?,
Operator::I32x4Bitmask => one_op(ctx, V128, I32, UnaryOp::I32x4Bitmask)?,

Operator::TableCopy {
src_table,
dst_table,
Expand Down Expand Up @@ -1497,6 +1500,10 @@ fn validate_instruction<'context>(
let elem = ctx.indices.get_element(segment)?;
ctx.alloc_instr(ElemDrop { elem }, loc);
}

Operator::ReturnCall { .. } | Operator::ReturnCallIndirect { .. } => {
unimplemented!("not supported");
}
}
Ok(())
}
33 changes: 7 additions & 26 deletions src/module/functions/mod.rs
Expand Up @@ -12,8 +12,8 @@ use crate::parse::IndicesToIds;
use crate::tombstone_arena::{Id, Tombstone, TombstoneArena};
use crate::ty::TypeId;
use crate::ty::ValType;
use anyhow::bail;
use std::cmp;
use wasmparser::{FuncValidator, FunctionBody, OperatorsReader};

#[cfg(feature = "parallel")]
use rayon::prelude::*;
Expand Down Expand Up @@ -323,25 +323,19 @@ impl Module {
/// Add the locally defined functions in the wasm module to this instance.
pub(crate) fn parse_local_functions(
&mut self,
section: wasmparser::CodeSectionReader,
function_section_count: u32,
functions: Vec<(FunctionBody<'_>, FuncValidator, OperatorsReader<'_>)>,
indices: &mut IndicesToIds,
on_instr_pos: Option<&(dyn Fn(&usize) -> InstrLocId + Sync + Send + 'static)>,
) -> Result<()> {
log::debug!("parse code section");
let amt = section.get_count();
if amt != function_section_count {
bail!("code and function sections must have same number of entries")
}
let num_imports = self.funcs.arena.len() - (amt as usize);
let num_imports = self.funcs.arena.len() - functions.len();

// First up serially create corresponding `LocalId` instances for all
// functions as well as extract the operators parser for each function.
// This is pretty tough to parallelize, but we can look into it later if
// necessary and it's a bottleneck!
let mut bodies = Vec::with_capacity(amt as usize);
for (i, body) in section.into_iter().enumerate() {
let body = body?;
let mut bodies = Vec::with_capacity(functions.len());
for (i, (body, _validator, ops)) in functions.into_iter().enumerate() {
let index = (num_imports + i) as u32;
let id = indices.get_func(index)?;
let ty = match self.funcs.arena[id].kind {
Expand Down Expand Up @@ -370,19 +364,7 @@ impl Module {
let results = type_.results().to_vec();
self.types.add_entry_ty(&results);

// WebAssembly local indices are 32 bits, so it's a validation error to
// have more than 2^32 locals. Sure enough there's a spec test for this!
let mut total = 0u32;
for local in body.get_locals_reader()? {
let (count, _) = local?;
total = match total.checked_add(count) {
Some(n) => n,
None => bail!("can't have more than 2^32 locals"),
};
}

// Now that we know we have a reasonable amount of locals, put them in
// our map.
// Next up comes all the locals of the function.
for local in body.get_locals_reader()? {
let (count, ty) = local?;
let ty = ValType::parse(&ty)?;
Expand All @@ -396,8 +378,7 @@ impl Module {
}
}

let body = body.get_operators_reader()?;
bodies.push((id, body, args, ty));
bodies.push((id, ops, args, ty));
}

// Wasm modules can often have a lot of functions and this operation can
Expand Down
16 changes: 12 additions & 4 deletions src/module/imports.rs
Expand Up @@ -117,14 +117,18 @@ impl Module {
match entry.ty {
wasmparser::ImportSectionEntryType::Function(idx) => {
let ty = ids.get_type(idx)?;
let id = self.add_import_func(entry.module, entry.field, ty);
let id = self.add_import_func(
entry.module,
entry.field.expect("module linking not supported"),
ty,
);
ids.push_func(id.0);
}
wasmparser::ImportSectionEntryType::Table(t) => {
let ty = ValType::parse(&t.element_type)?;
let id = self.add_import_table(
entry.module,
entry.field,
entry.field.expect("module linking not supported"),
t.limits.initial,
t.limits.maximum,
ty,
Expand All @@ -134,7 +138,7 @@ impl Module {
wasmparser::ImportSectionEntryType::Memory(m) => {
let id = self.add_import_memory(
entry.module,
entry.field,
entry.field.expect("module linking not supported"),
m.shared,
m.limits.initial,
m.limits.maximum,
Expand All @@ -144,12 +148,16 @@ impl Module {
wasmparser::ImportSectionEntryType::Global(g) => {
let id = self.add_import_global(
entry.module,
entry.field,
entry.field.expect("module linking not supported"),
ValType::parse(&g.content_type)?,
g.mutable,
);
ids.push_global(id.0);
}
wasmparser::ImportSectionEntryType::Module(_)
| wasmparser::ImportSectionEntryType::Instance(_) => {
unimplemented!("module linking not implemented");
}
}
}

Expand Down