Skip to content

Commit

Permalink
Update the wasmparser dependency (#138)
Browse files Browse the repository at this point in the history
* Update `wasmparser` dependency

* Enable multi-value spec tests

* Support v128 globals
  • Loading branch information
alexcrichton committed Nov 19, 2019
1 parent f05f89a commit c50e1fd
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 110 deletions.
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.13.0' }
wasmparser = "0.39.1"
wasmparser = "0.42.0"

[features]
parallel = ['rayon', 'id-arena/rayon']
Expand Down
4 changes: 1 addition & 3 deletions crates/tests/tests/spec-tests.rs
Expand Up @@ -26,6 +26,7 @@ fn run(wast: &Path) -> Result<(), anyhow::Error> {
None => &[],
Some("mutable-global") => &[],
Some("sign-extension-ops") => &["--enable-sign-extension"],
Some("multi-value") => &["--enable-multi-value"],
Some("nontrapping-float-to-int-conversions") => &["--enable-saturating-float-to-int"],

// Currently wabt doesn't have support for `ref.host` which is used in
Expand All @@ -35,9 +36,6 @@ fn run(wast: &Path) -> Result<(), anyhow::Error> {
// Currently wabt has broken support for `ref.func` initializers
Some("bulk-memory-operations") => return Ok(()),

// TODO: we should actually implement this proposal!
Some("multi-value") => return Ok(()),

// TODO: should get threads working
Some("threads") => return Ok(()),
// Some("threads") => &["--enable-threads"],
Expand Down
23 changes: 22 additions & 1 deletion src/init_expr.rs
Expand Up @@ -25,7 +25,8 @@ impl InitExpr {
I64Const { value } => InitExpr::Value(Value::I64(value)),
F32Const { value } => InitExpr::Value(Value::F32(f32::from_bits(value.bits()))),
F64Const { value } => InitExpr::Value(Value::F64(f64::from_bits(value.bits()))),
GetGlobal { global_index } => InitExpr::Global(ids.get_global(global_index)?),
V128Const { value } => InitExpr::Value(Value::V128(v128_to_u128(&value))),
GlobalGet { global_index } => InitExpr::Global(ids.get_global(global_index)?),
_ => bail!("invalid constant expression"),
};
match reader.read()? {
Expand All @@ -50,3 +51,23 @@ impl Emit for InitExpr {
cx.encoder.byte(0x0b); // end
}
}

pub(crate) fn v128_to_u128(value: &wasmparser::V128) -> u128 {
let n = value.bytes();
((n[0] as u128) << 0)
| ((n[1] as u128) << 8)
| ((n[2] as u128) << 16)
| ((n[3] as u128) << 24)
| ((n[4] as u128) << 32)
| ((n[5] as u128) << 40)
| ((n[6] as u128) << 48)
| ((n[7] as u128) << 56)
| ((n[8] as u128) << 64)
| ((n[9] as u128) << 72)
| ((n[10] as u128) << 80)
| ((n[11] as u128) << 88)
| ((n[12] as u128) << 96)
| ((n[13] as u128) << 104)
| ((n[14] as u128) << 112)
| ((n[15] as u128) << 120)
}
14 changes: 14 additions & 0 deletions src/ir/mod.rs
Expand Up @@ -508,12 +508,24 @@ pub enum Instr {
table: TableId,
},

/// `table.fill`
TableFill {
/// The table we're filling
table: TableId,
},

/// `ref.null`
RefNull {},

/// `ref.is_null`
RefIsNull {},

/// `ref.func`
RefFunc {
/// The function that this instruction is referencing
func: FunctionId,
},

/// `v128.bitselect`
V128Bitselect {},

Expand Down Expand Up @@ -1127,8 +1139,10 @@ impl Instr {
| Instr::TableSet(..)
| Instr::TableGrow(..)
| Instr::TableSize(..)
| Instr::TableFill(..)
| Instr::RefNull(..)
| Instr::RefIsNull(..)
| Instr::RefFunc(..)
| Instr::V128Bitselect(..)
| Instr::V128Swizzle(..)
| Instr::V128Shuffle(..)
Expand Down
5 changes: 3 additions & 2 deletions src/module/elements.rs
Expand Up @@ -76,12 +76,13 @@ impl Module {
let segment = segment?;

match segment.kind {
wasmparser::ElementKind::Passive(_) => {
wasmparser::ElementKind::Passive { .. } => {
bail!("passive element segments not supported yet");
}
wasmparser::ElementKind::Active {
table_index,
init_expr,
items,
} => {
let table = ids.get_table(table_index)?;
let table = match &mut self.tables.get_mut(table).kind {
Expand All @@ -93,7 +94,7 @@ impl Module {

let offset = InitExpr::eval(&init_expr, ids)
.with_context(|| format!("in segment {}", i))?;
let functions = segment.items.get_items_reader()?.into_iter().map(|func| {
let functions = items.get_items_reader()?.into_iter().map(|func| {
let func = func?;
ids.get_func(func)
});
Expand Down
10 changes: 10 additions & 0 deletions src/module/functions/local_function/emit.rs
Expand Up @@ -752,12 +752,22 @@ impl<'instr> Visitor<'instr> for Emit<'_, '_> {
let idx = self.indices.get_table_index(e.table);
self.encoder.u32(idx);
}
TableFill(e) => {
self.encoder.raw(&[0xfc, 0x11]);
let idx = self.indices.get_table_index(e.table);
self.encoder.u32(idx);
}
RefNull(_e) => {
self.encoder.byte(0xd0);
}
RefIsNull(_e) => {
self.encoder.byte(0xd1);
}
RefFunc(e) => {
self.encoder.byte(0xd2);
let idx = self.indices.get_func_index(e.func);
self.encoder.u32(idx);
}

V128Bitselect(_) => {
self.simd(0x50);
Expand Down

0 comments on commit c50e1fd

Please sign in to comment.