Use latest wasmparser instead of fork

This commit is contained in:
Jef
2019-03-28 10:14:40 +01:00
parent 2a60d76bdc
commit a8bb9fd634
7 changed files with 203 additions and 258 deletions

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "wasmparser.rs"]
path = wasmparser.rs
url = git@github.com:Vurich/wasmparser.rs

View File

@@ -13,7 +13,7 @@ edition = "2018"
smallvec = "0.6" smallvec = "0.6"
dynasm = "0.3" dynasm = "0.3"
dynasmrt = "0.3" dynasmrt = "0.3"
wasmparser = { path = "./wasmparser.rs" } wasmparser = "0.29"
memoffset = "0.2" memoffset = "0.2"
itertools = "0.8" itertools = "0.8"
capstone = "0.5.0" capstone = "0.5.0"

View File

@@ -1,5 +1,5 @@
use crate::error::Error; use crate::error::Error;
use crate::microwasm::{BrTarget, SignlessType, Type, Value, F32, F64, I32, I64}; use crate::microwasm::{BrTarget, Ieee32, Ieee64, SignlessType, Type, Value, F32, F64, I32, I64};
use crate::module::ModuleContext; use crate::module::ModuleContext;
use cranelift_codegen::{binemit, ir}; use cranelift_codegen::{binemit, ir};
use dynasm::dynasm; use dynasm::dynasm;
@@ -459,11 +459,11 @@ impl ValueLocation {
self.immediate().and_then(Value::as_i64) self.immediate().and_then(Value::as_i64)
} }
fn imm_f32(self) -> Option<wasmparser::Ieee32> { fn imm_f32(self) -> Option<Ieee32> {
self.immediate().and_then(Value::as_f32) self.immediate().and_then(Value::as_f32)
} }
fn imm_f64(self) -> Option<wasmparser::Ieee64> { fn imm_f64(self) -> Option<Ieee64> {
self.immediate().and_then(Value::as_f64) self.immediate().and_then(Value::as_f64)
} }
} }
@@ -1257,7 +1257,7 @@ macro_rules! cmp_float {
(@helper $cmp_instr:ident, $ty:ty, $imm_fn:ident, $self:expr, $left:expr, $right:expr, $instr:ident, $const_fallback:expr) => {{ (@helper $cmp_instr:ident, $ty:ty, $imm_fn:ident, $self:expr, $left:expr, $right:expr, $instr:ident, $const_fallback:expr) => {{
let (left, right, this) = ($left, $right, $self); let (left, right, this) = ($left, $right, $self);
if let (Some(left), Some(right)) = (left.$imm_fn(), right.$imm_fn()) { if let (Some(left), Some(right)) = (left.$imm_fn(), right.$imm_fn()) {
if $const_fallback(<$ty>::from_bits(left.bits()), <$ty>::from_bits(right.bits())) { if $const_fallback(<$ty>::from_bits(left.to_bits()), <$ty>::from_bits(right.to_bits())) {
ValueLocation::Immediate(1i32.into()) ValueLocation::Immediate(1i32.into())
} else { } else {
ValueLocation::Immediate(0i32.into()) ValueLocation::Immediate(0i32.into())
@@ -1410,8 +1410,8 @@ macro_rules! binop_f32 {
binop!( binop!(
$name, $name,
$instr, $instr,
|a: wasmparser::Ieee32, b: wasmparser::Ieee32| wasmparser::Ieee32( |a: Ieee32, b: Ieee32| Ieee32::from_bits(
$const_fallback(f32::from_bits(a.bits()), f32::from_bits(b.bits())).to_bits() $const_fallback(f32::from_bits(a.to_bits()), f32::from_bits(b.to_bits())).to_bits()
), ),
Rx, Rx,
rx, rx,
@@ -1427,8 +1427,8 @@ macro_rules! commutative_binop_f32 {
commutative_binop!( commutative_binop!(
$name, $name,
$instr, $instr,
|a: wasmparser::Ieee32, b: wasmparser::Ieee32| wasmparser::Ieee32( |a: Ieee32, b: Ieee32| Ieee32::from_bits(
$const_fallback(f32::from_bits(a.bits()), f32::from_bits(b.bits())).to_bits() $const_fallback(f32::from_bits(a.to_bits()), f32::from_bits(b.to_bits())).to_bits()
), ),
Rx, Rx,
rx, rx,
@@ -1444,8 +1444,8 @@ macro_rules! binop_f64 {
binop!( binop!(
$name, $name,
$instr, $instr,
|a: wasmparser::Ieee64, b: wasmparser::Ieee64| wasmparser::Ieee64( |a: Ieee64, b: Ieee64| Ieee64::from_bits(
$const_fallback(f64::from_bits(a.bits()), f64::from_bits(b.bits())).to_bits() $const_fallback(f64::from_bits(a.to_bits()), f64::from_bits(b.to_bits())).to_bits()
), ),
Rx, Rx,
rx, rx,
@@ -1461,8 +1461,8 @@ macro_rules! commutative_binop_f64 {
commutative_binop!( commutative_binop!(
$name, $name,
$instr, $instr,
|a: wasmparser::Ieee64, b: wasmparser::Ieee64| wasmparser::Ieee64( |a: Ieee64, b: Ieee64| Ieee64::from_bits(
$const_fallback(f64::from_bits(a.bits()), f64::from_bits(b.bits())).to_bits() $const_fallback(f64::from_bits(a.to_bits()), f64::from_bits(b.to_bits())).to_bits()
), ),
Rx, Rx,
rx, rx,
@@ -1998,13 +1998,13 @@ impl<'this, M: ModuleContext> Context<'this, M> {
f32_eq, f32_eq,
cmpeqss, cmpeqss,
as_f32, as_f32,
|a: wasmparser::Ieee32, b: wasmparser::Ieee32| f32::from_bits(a.0) == f32::from_bits(b.0) |a: Ieee32, b: Ieee32| f32::from_bits(a.to_bits()) == f32::from_bits(b.to_bits())
); );
eq_float!( eq_float!(
f32_ne, f32_ne,
cmpneqss, cmpneqss,
as_f32, as_f32,
|a: wasmparser::Ieee32, b: wasmparser::Ieee32| f32::from_bits(a.0) != f32::from_bits(b.0) |a: Ieee32, b: Ieee32| f32::from_bits(a.to_bits()) != f32::from_bits(b.to_bits())
); );
cmp_f64!(f64_gt, f64_lt, seta, |a, b| a > b); cmp_f64!(f64_gt, f64_lt, seta, |a, b| a > b);
@@ -2013,13 +2013,13 @@ impl<'this, M: ModuleContext> Context<'this, M> {
f64_eq, f64_eq,
cmpeqsd, cmpeqsd,
as_f64, as_f64,
|a: wasmparser::Ieee64, b: wasmparser::Ieee64| f64::from_bits(a.0) == f64::from_bits(b.0) |a: Ieee64, b: Ieee64| f64::from_bits(a.to_bits()) == f64::from_bits(b.to_bits())
); );
eq_float!( eq_float!(
f64_ne, f64_ne,
cmpneqsd, cmpneqsd,
as_f64, as_f64,
|a: wasmparser::Ieee64, b: wasmparser::Ieee64| f64::from_bits(a.0) != f64::from_bits(b.0) |a: Ieee64, b: Ieee64| f64::from_bits(a.to_bits()) != f64::from_bits(b.to_bits())
); );
// TODO: Should we do this logic in `eq` and just have this delegate to `eq`? // TODO: Should we do this logic in `eq` and just have this delegate to `eq`?
@@ -2866,7 +2866,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = if let Some(i) = val.imm_f32() { let out = if let Some(i) = val.imm_f32() {
ValueLocation::Immediate( ValueLocation::Immediate(
wasmparser::Ieee32((-f32::from_bits(i.bits())).to_bits()).into(), Ieee32::from_bits((-f32::from_bits(i.to_bits())).to_bits()).into(),
) )
} else { } else {
let reg = self.into_temp_reg(GPRType::Rx, val); let reg = self.into_temp_reg(GPRType::Rx, val);
@@ -2887,7 +2887,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = if let Some(i) = val.imm_f64() { let out = if let Some(i) = val.imm_f64() {
ValueLocation::Immediate( ValueLocation::Immediate(
wasmparser::Ieee64((-f64::from_bits(i.bits())).to_bits()).into(), Ieee64::from_bits((-f64::from_bits(i.to_bits())).to_bits()).into(),
) )
} else { } else {
let reg = self.into_temp_reg(GPRType::Rx, val); let reg = self.into_temp_reg(GPRType::Rx, val);
@@ -2908,7 +2908,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = if let Some(i) = val.imm_f32() { let out = if let Some(i) = val.imm_f32() {
ValueLocation::Immediate( ValueLocation::Immediate(
wasmparser::Ieee32(f32::from_bits(i.bits()).abs().to_bits()).into(), Ieee32::from_bits(f32::from_bits(i.to_bits()).abs().to_bits()).into(),
) )
} else { } else {
let reg = self.into_temp_reg(GPRType::Rx, val); let reg = self.into_temp_reg(GPRType::Rx, val);
@@ -2929,7 +2929,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = if let Some(i) = val.imm_f64() { let out = if let Some(i) = val.imm_f64() {
ValueLocation::Immediate( ValueLocation::Immediate(
wasmparser::Ieee64(f64::from_bits(i.bits()).abs().to_bits()).into(), Ieee64::from_bits(f64::from_bits(i.to_bits()).abs().to_bits()).into(),
) )
} else { } else {
let reg = self.into_temp_reg(GPRType::Rx, val); let reg = self.into_temp_reg(GPRType::Rx, val);
@@ -2950,7 +2950,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = if let Some(i) = val.imm_f32() { let out = if let Some(i) = val.imm_f32() {
ValueLocation::Immediate( ValueLocation::Immediate(
wasmparser::Ieee32(f32::from_bits(i.bits()).sqrt().to_bits()).into(), Ieee32::from_bits(f32::from_bits(i.to_bits()).sqrt().to_bits()).into(),
) )
} else { } else {
let reg = self.into_temp_reg(GPRType::Rx, val); let reg = self.into_temp_reg(GPRType::Rx, val);
@@ -2970,7 +2970,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = if let Some(i) = val.imm_f64() { let out = if let Some(i) = val.imm_f64() {
ValueLocation::Immediate( ValueLocation::Immediate(
wasmparser::Ieee64(f64::from_bits(i.bits()).sqrt().to_bits()).into(), Ieee64::from_bits(f64::from_bits(i.to_bits()).sqrt().to_bits()).into(),
) )
} else { } else {
let reg = self.into_temp_reg(GPRType::Rx, val); let reg = self.into_temp_reg(GPRType::Rx, val);
@@ -2991,7 +2991,9 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = if let (Some(left), Some(right)) = (left.imm_f32(), right.imm_f32()) { let out = if let (Some(left), Some(right)) = (left.imm_f32(), right.imm_f32()) {
ValueLocation::Immediate( ValueLocation::Immediate(
wasmparser::Ieee32((left.bits() & REST_MASK_F32) | (right.bits() & SIGN_MASK_F32)) Ieee32::from_bits(
(left.to_bits() & REST_MASK_F32) | (right.to_bits() & SIGN_MASK_F32),
)
.into(), .into(),
) )
} else { } else {
@@ -3020,7 +3022,9 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = if let (Some(left), Some(right)) = (left.imm_f64(), right.imm_f64()) { let out = if let (Some(left), Some(right)) = (left.imm_f64(), right.imm_f64()) {
ValueLocation::Immediate( ValueLocation::Immediate(
wasmparser::Ieee64((left.bits() & REST_MASK_F64) | (right.bits() & SIGN_MASK_F64)) Ieee64::from_bits(
(left.to_bits() & REST_MASK_F64) | (right.to_bits() & SIGN_MASK_F64),
)
.into(), .into(),
) )
} else { } else {
@@ -3134,7 +3138,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
f32, f32,
f64, f64,
as_f32, as_f32,
|a: wasmparser::Ieee32| wasmparser::Ieee64((f32::from_bits(a.bits()) as f64).to_bits()) |a: Ieee32| Ieee64::from_bits((f32::from_bits(a.to_bits()) as f64).to_bits())
); );
conversion!( conversion!(
f32_from_f64, f32_from_f64,
@@ -3146,14 +3150,14 @@ impl<'this, M: ModuleContext> Context<'this, M> {
f64, f64,
f32, f32,
as_f64, as_f64,
|a: wasmparser::Ieee64| wasmparser::Ieee32((f64::from_bits(a.bits()) as f32).to_bits()) |a: Ieee64| Ieee32::from_bits((f64::from_bits(a.to_bits()) as f32).to_bits())
); );
pub fn i32_truncate_f32_s(&mut self) { pub fn i32_truncate_f32_s(&mut self) {
let mut val = self.pop(); let mut val = self.pop();
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
(f32::from_bits(imm.as_f32().unwrap().bits()) as i32).into(), (f32::from_bits(imm.as_f32().unwrap().to_bits()) as i32).into(),
), ),
other => { other => {
let reg = self.into_reg(F32, other); let reg = self.into_reg(F32, other);
@@ -3192,7 +3196,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
(f32::from_bits(imm.as_f32().unwrap().bits()) as i32).into(), (f32::from_bits(imm.as_f32().unwrap().to_bits()) as i32).into(),
), ),
other => { other => {
let reg = self.into_temp_reg(F32, other); let reg = self.into_temp_reg(F32, other);
@@ -3234,7 +3238,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
(f64::from_bits(imm.as_f64().unwrap().bits()) as i32).into(), (f64::from_bits(imm.as_f64().unwrap().to_bits()) as i32).into(),
), ),
other => { other => {
let reg = self.into_reg(F32, other); let reg = self.into_reg(F32, other);
@@ -3274,7 +3278,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
(f32::from_bits(imm.as_f32().unwrap().bits()) as i32).into(), (f32::from_bits(imm.as_f32().unwrap().to_bits()) as i32).into(),
), ),
other => { other => {
let reg = self.into_temp_reg(F32, other); let reg = self.into_temp_reg(F32, other);
@@ -3322,7 +3326,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
i32, i32,
f32, f32,
as_i32, as_i32,
|a| wasmparser::Ieee32((a as f32).to_bits()) |a| Ieee32::from_bits((a as f32).to_bits())
); );
conversion!( conversion!(
f64_convert_from_i32_s, f64_convert_from_i32_s,
@@ -3334,7 +3338,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
i32, i32,
f64, f64,
as_i32, as_i32,
|a| wasmparser::Ieee64((a as f64).to_bits()) |a| Ieee64::from_bits((a as f64).to_bits())
); );
conversion!( conversion!(
f32_convert_from_i64_s, f32_convert_from_i64_s,
@@ -3346,7 +3350,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
i64, i64,
f32, f32,
as_i32, as_i32,
|a| wasmparser::Ieee32((a as f32).to_bits()) |a| Ieee32::from_bits((a as f32).to_bits())
); );
conversion!( conversion!(
f64_convert_from_i64_s, f64_convert_from_i64_s,
@@ -3358,7 +3362,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
i64, i64,
f64, f64,
as_i32, as_i32,
|a| wasmparser::Ieee64((a as f64).to_bits()) |a| Ieee64::from_bits((a as f64).to_bits())
); );
pub fn i64_truncate_f32_s(&mut self) { pub fn i64_truncate_f32_s(&mut self) {
@@ -3366,7 +3370,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
(f32::from_bits(imm.as_f32().unwrap().bits()) as i32).into(), (f32::from_bits(imm.as_f32().unwrap().to_bits()) as i32).into(),
), ),
other => { other => {
let reg = self.into_temp_reg(F32, other); let reg = self.into_temp_reg(F32, other);
@@ -3405,7 +3409,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
(f64::from_bits(imm.as_f64().unwrap().bits()) as i32).into(), (f64::from_bits(imm.as_f64().unwrap().to_bits()) as i32).into(),
), ),
other => { other => {
let reg = self.into_reg(F32, other); let reg = self.into_reg(F32, other);
@@ -3445,7 +3449,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
(f32::from_bits(imm.as_f32().unwrap().bits()) as u64).into(), (f32::from_bits(imm.as_f32().unwrap().to_bits()) as u64).into(),
), ),
_ => { _ => {
let reg = self.into_reg(F32, val); let reg = self.into_reg(F32, val);
@@ -3487,7 +3491,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
(f64::from_bits(imm.as_f64().unwrap().bits()) as u64).into(), (f64::from_bits(imm.as_f64().unwrap().to_bits()) as u64).into(),
), ),
_ => { _ => {
let reg = self.into_reg(F64, val); let reg = self.into_reg(F64, val);
@@ -3530,7 +3534,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
wasmparser::Ieee32((imm.as_i32().unwrap() as u32 as f32).to_bits()).into(), Ieee32::from_bits((imm.as_i32().unwrap() as u32 as f32).to_bits()).into(),
), ),
_ => { _ => {
let reg = self.into_reg(I32, val); let reg = self.into_reg(I32, val);
@@ -3557,7 +3561,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
wasmparser::Ieee64((imm.as_i32().unwrap() as u32 as f64).to_bits()).into(), Ieee64::from_bits((imm.as_i32().unwrap() as u32 as f64).to_bits()).into(),
), ),
_ => { _ => {
let reg = self.into_reg(I32, val); let reg = self.into_reg(I32, val);
@@ -3584,7 +3588,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
wasmparser::Ieee32((imm.as_i32().unwrap() as u64 as f32).to_bits()).into(), Ieee32::from_bits((imm.as_i32().unwrap() as u64 as f32).to_bits()).into(),
), ),
_ => { _ => {
let reg = self.into_reg(I64, val); let reg = self.into_reg(I64, val);
@@ -3624,7 +3628,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val { let out_val = match val {
ValueLocation::Immediate(imm) => ValueLocation::Immediate( ValueLocation::Immediate(imm) => ValueLocation::Immediate(
wasmparser::Ieee64((imm.as_i64().unwrap() as u64 as f64).to_bits()).into(), Ieee64::from_bits((imm.as_i64().unwrap() as u64 as f64).to_bits()).into(),
), ),
_ => { _ => {
let reg = self.into_reg(I64, val); let reg = self.into_reg(I64, val);
@@ -3664,7 +3668,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = match val { let out = match val {
ValueLocation::Immediate(imm) => { ValueLocation::Immediate(imm) => {
ValueLocation::Immediate(imm.as_f32().unwrap().bits().into()) ValueLocation::Immediate(imm.as_f32().unwrap().to_bits().into())
} }
val => val, val => val,
}; };
@@ -3677,7 +3681,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = match val { let out = match val {
ValueLocation::Immediate(imm) => { ValueLocation::Immediate(imm) => {
ValueLocation::Immediate(imm.as_f64().unwrap().bits().into()) ValueLocation::Immediate(imm.as_f64().unwrap().to_bits().into())
} }
val => val, val => val,
}; };
@@ -3690,7 +3694,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = match val { let out = match val {
ValueLocation::Immediate(imm) => { ValueLocation::Immediate(imm) => {
ValueLocation::Immediate(wasmparser::Ieee32(imm.as_i32().unwrap() as _).into()) ValueLocation::Immediate(Ieee32::from_bits(imm.as_i32().unwrap() as _).into())
} }
val => val, val => val,
}; };
@@ -3703,7 +3707,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = match val { let out = match val {
ValueLocation::Immediate(imm) => { ValueLocation::Immediate(imm) => {
ValueLocation::Immediate(wasmparser::Ieee64(imm.as_i64().unwrap() as _).into()) ValueLocation::Immediate(Ieee64::from_bits(imm.as_i64().unwrap() as _).into())
} }
val => val, val => val,
}; };
@@ -3736,8 +3740,10 @@ impl<'this, M: ModuleContext> Context<'this, M> {
addss, addss,
orps, orps,
as_f32, as_f32,
|a: wasmparser::Ieee32, b: wasmparser::Ieee32| wasmparser::Ieee32( |a: Ieee32, b: Ieee32| Ieee32::from_bits(
f32::from_bits(a.0).min(f32::from_bits(b.0)).to_bits() f32::from_bits(a.to_bits())
.min(f32::from_bits(b.to_bits()))
.to_bits()
) )
); );
minmax_float!( minmax_float!(
@@ -3747,8 +3753,10 @@ impl<'this, M: ModuleContext> Context<'this, M> {
addss, addss,
andps, andps,
as_f32, as_f32,
|a: wasmparser::Ieee32, b: wasmparser::Ieee32| wasmparser::Ieee32( |a: Ieee32, b: Ieee32| Ieee32::from_bits(
f32::from_bits(a.0).max(f32::from_bits(b.0)).to_bits() f32::from_bits(a.to_bits())
.max(f32::from_bits(b.to_bits()))
.to_bits()
) )
); );
binop_f32!(f32_sub, subss, |a, b| a - b); binop_f32!(f32_sub, subss, |a, b| a - b);
@@ -3799,8 +3807,10 @@ impl<'this, M: ModuleContext> Context<'this, M> {
addsd, addsd,
orpd, orpd,
as_f64, as_f64,
|a: wasmparser::Ieee64, b: wasmparser::Ieee64| wasmparser::Ieee64( |a: Ieee64, b: Ieee64| Ieee64::from_bits(
f64::from_bits(a.0).min(f64::from_bits(b.0)).to_bits() f64::from_bits(a.to_bits())
.min(f64::from_bits(b.to_bits()))
.to_bits()
) )
); );
minmax_float!( minmax_float!(
@@ -3810,8 +3820,10 @@ impl<'this, M: ModuleContext> Context<'this, M> {
addsd, addsd,
andpd, andpd,
as_f64, as_f64,
|a: wasmparser::Ieee64, b: wasmparser::Ieee64| wasmparser::Ieee64( |a: Ieee64, b: Ieee64| Ieee64::from_bits(
f64::from_bits(a.0).max(f64::from_bits(b.0)).to_bits() f64::from_bits(a.to_bits())
.max(f64::from_bits(b.to_bits()))
.to_bits()
) )
); );
binop_f64!(f64_sub, subsd, |a, b| a - b); binop_f64!(f64_sub, subsd, |a, b| a - b);

View File

@@ -7,7 +7,8 @@ use std::{
ops::RangeInclusive, ops::RangeInclusive,
}; };
use wasmparser::{ use wasmparser::{
FunctionBody, Ieee32, Ieee64, MemoryImmediate, Operator as WasmOperator, OperatorsReader, FunctionBody, Ieee32 as WasmIeee32, Ieee64 as WasmIeee64, MemoryImmediate as WasmMemoryImmediate, Operator as WasmOperator,
OperatorsReader,
}; };
pub fn dis<L>( pub fn dis<L>(
@@ -49,8 +50,8 @@ impl fmt::Display for Value {
match self { match self {
Value::I32(v) => write!(f, "{}i32", v), Value::I32(v) => write!(f, "{}i32", v),
Value::I64(v) => write!(f, "{}i64", v), Value::I64(v) => write!(f, "{}i64", v),
Value::F32(v) => write!(f, "{}f32", f32::from_bits(v.bits())), Value::F32(v) => write!(f, "{}f32", f32::from_bits(v.to_bits())),
Value::F64(v) => write!(f, "{}f64", f64::from_bits(v.bits())), Value::F64(v) => write!(f, "{}f64", f64::from_bits(v.to_bits())),
} }
} }
} }
@@ -304,13 +305,6 @@ pub enum NameTag {
pub type WasmLabel = (u32, NameTag); pub type WasmLabel = (u32, NameTag);
trait Label {
// TODO
}
// TODO: This is for Wasm blocks - we should have an increasing ID for each block that we hit.
impl Label for (u32, NameTag) {}
type OperatorFromWasm = Operator<WasmLabel>; type OperatorFromWasm = Operator<WasmLabel>;
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
@@ -388,6 +382,58 @@ where
} }
} }
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct Ieee32(u32);
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct Ieee64(u64);
impl Ieee32 {
pub fn to_bits(self) -> u32 {
self.0
}
pub fn from_bits(other: u32) -> Self {
Ieee32(other)
}
}
impl From<WasmIeee32> for Ieee32 {
fn from(other: WasmIeee32) -> Self {
Self::from_bits(other.bits())
}
}
impl Ieee64 {
pub fn to_bits(self) -> u64 {
self.0
}
pub fn from_bits(other: u64) -> Self {
Ieee64(other)
}
}
impl From<WasmIeee64> for Ieee64 {
fn from(other: WasmIeee64) -> Self {
Self::from_bits(other.bits())
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct MemoryImmediate {
pub flags: u32,
pub offset: u32,
}
impl From<WasmMemoryImmediate> for MemoryImmediate {
fn from(other: WasmMemoryImmediate) -> Self {
MemoryImmediate {
flags: other.flags,
offset: other.offset,
}
}
}
// TODO: Explicit VmCtx? // TODO: Explicit VmCtx?
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Operator<Label> { pub enum Operator<Label> {
@@ -1750,79 +1796,105 @@ where
smallvec![Operator::SetGlobal(global_index)] smallvec![Operator::SetGlobal(global_index)]
} }
WasmOperator::I32Load { memarg } => smallvec![Operator::Load { ty: I32, memarg }], WasmOperator::I32Load { memarg } => smallvec![Operator::Load {
WasmOperator::I64Load { memarg } => smallvec![Operator::Load { ty: I64, memarg }], ty: I32,
WasmOperator::F32Load { memarg } => smallvec![Operator::Load { ty: F32, memarg }], memarg: memarg.into()
WasmOperator::F64Load { memarg } => smallvec![Operator::Load { ty: F64, memarg }], }],
WasmOperator::I64Load { memarg } => smallvec![Operator::Load {
ty: I64,
memarg: memarg.into()
}],
WasmOperator::F32Load { memarg } => smallvec![Operator::Load {
ty: F32,
memarg: memarg.into()
}],
WasmOperator::F64Load { memarg } => smallvec![Operator::Load {
ty: F64,
memarg: memarg.into()
}],
WasmOperator::I32Load8S { memarg } => smallvec![Operator::Load8 { WasmOperator::I32Load8S { memarg } => smallvec![Operator::Load8 {
ty: sint::I32, ty: sint::I32,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I32Load8U { memarg } => smallvec![Operator::Load8 { WasmOperator::I32Load8U { memarg } => smallvec![Operator::Load8 {
ty: sint::U32, ty: sint::U32,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I32Load16S { memarg } => smallvec![Operator::Load16 { WasmOperator::I32Load16S { memarg } => smallvec![Operator::Load16 {
ty: sint::I32, ty: sint::I32,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I32Load16U { memarg } => smallvec![Operator::Load16 { WasmOperator::I32Load16U { memarg } => smallvec![Operator::Load16 {
ty: sint::U32, ty: sint::U32,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I64Load8S { memarg } => smallvec![Operator::Load8 { WasmOperator::I64Load8S { memarg } => smallvec![Operator::Load8 {
ty: sint::I64, ty: sint::I64,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I64Load8U { memarg } => smallvec![Operator::Load8 { WasmOperator::I64Load8U { memarg } => smallvec![Operator::Load8 {
ty: sint::U64, ty: sint::U64,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I64Load16S { memarg } => smallvec![Operator::Load16 { WasmOperator::I64Load16S { memarg } => smallvec![Operator::Load16 {
ty: sint::I64, ty: sint::I64,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I64Load16U { memarg } => smallvec![Operator::Load16 { WasmOperator::I64Load16U { memarg } => smallvec![Operator::Load16 {
ty: sint::U64, ty: sint::U64,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I64Load32S { memarg } => smallvec![Operator::Load32 { WasmOperator::I64Load32S { memarg } => smallvec![Operator::Load32 {
sign: Signedness::Signed, sign: Signedness::Signed,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I64Load32U { memarg } => smallvec![Operator::Load32 { WasmOperator::I64Load32U { memarg } => smallvec![Operator::Load32 {
sign: Signedness::Unsigned, sign: Signedness::Unsigned,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I32Store { memarg } => smallvec![Operator::Store { ty: I32, memarg }], WasmOperator::I32Store { memarg } => smallvec![Operator::Store {
WasmOperator::I64Store { memarg } => smallvec![Operator::Store { ty: I64, memarg }], ty: I32,
WasmOperator::F32Store { memarg } => smallvec![Operator::Store { ty: F32, memarg }], memarg: memarg.into()
WasmOperator::F64Store { memarg } => smallvec![Operator::Store { ty: F64, memarg }], }],
WasmOperator::I64Store { memarg } => smallvec![Operator::Store {
ty: I64,
memarg: memarg.into()
}],
WasmOperator::F32Store { memarg } => smallvec![Operator::Store {
ty: F32,
memarg: memarg.into()
}],
WasmOperator::F64Store { memarg } => smallvec![Operator::Store {
ty: F64,
memarg: memarg.into()
}],
WasmOperator::I32Store8 { memarg } => smallvec![Operator::Store8 { WasmOperator::I32Store8 { memarg } => smallvec![Operator::Store8 {
ty: Size::_32, ty: Size::_32,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I32Store16 { memarg } => smallvec![Operator::Store16 { WasmOperator::I32Store16 { memarg } => smallvec![Operator::Store16 {
ty: Size::_32, ty: Size::_32,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I64Store8 { memarg } => smallvec![Operator::Store8 { WasmOperator::I64Store8 { memarg } => smallvec![Operator::Store8 {
ty: Size::_64, ty: Size::_64,
memarg, memarg: memarg.into(),
}], }],
WasmOperator::I64Store16 { memarg } => smallvec![Operator::Store16 { WasmOperator::I64Store16 { memarg } => smallvec![Operator::Store16 {
ty: Size::_64, ty: Size::_64,
memarg, memarg: memarg.into(),
}],
WasmOperator::I64Store32 { memarg } => smallvec![Operator::Store32 {
memarg: memarg.into()
}], }],
WasmOperator::I64Store32 { memarg } => smallvec![Operator::Store32 { memarg }],
WasmOperator::MemorySize { reserved } => smallvec![Operator::MemorySize { reserved }], WasmOperator::MemorySize { reserved } => smallvec![Operator::MemorySize { reserved }],
WasmOperator::MemoryGrow { reserved } => smallvec![Operator::MemoryGrow { reserved }], WasmOperator::MemoryGrow { reserved } => smallvec![Operator::MemoryGrow { reserved }],
WasmOperator::I32Const { value } => smallvec![Operator::Const(Value::I32(value))], WasmOperator::I32Const { value } => smallvec![Operator::Const(Value::I32(value))],
WasmOperator::I64Const { value } => smallvec![Operator::Const(Value::I64(value))], WasmOperator::I64Const { value } => smallvec![Operator::Const(Value::I64(value))],
WasmOperator::F32Const { value } => smallvec![Operator::Const(Value::F32(value))], WasmOperator::F32Const { value } => smallvec![Operator::Const(Value::F32(value.into()))],
WasmOperator::F64Const { value } => smallvec![Operator::Const(Value::F64(value))], WasmOperator::F64Const { value } => smallvec![Operator::Const(Value::F64(value.into()))],
WasmOperator::RefNull => unimplemented!("{:?}", op), WasmOperator::RefNull => unimplemented!("{:?}", op),
WasmOperator::RefIsNull => unimplemented!("{:?}", op), WasmOperator::RefIsNull => unimplemented!("{:?}", op),
WasmOperator::I32Eqz => smallvec![Operator::Eqz(Size::_32)], WasmOperator::I32Eqz => smallvec![Operator::Eqz(Size::_32)],
@@ -2098,3 +2170,4 @@ where
})) }))
} }
} }

View File

@@ -6,12 +6,8 @@ use cranelift_codegen::{
ir::{self, AbiParam, Signature as CraneliftSignature}, ir::{self, AbiParam, Signature as CraneliftSignature},
isa, isa,
}; };
use std::{ use std::{convert::TryInto, mem};
convert::TryInto, use wasmparser::{FuncType, MemoryType, ModuleReader, SectionCode, Type};
hash::{Hash, Hasher},
mem,
};
use wasmparser::{FuncType, MemoryType, ModuleReader, SectionCode, TableType, Type};
pub trait AsValueType { pub trait AsValueType {
const TYPE: Type; const TYPE: Type;
@@ -105,70 +101,18 @@ pub struct TranslatedModule {
ctx: SimpleContext, ctx: SimpleContext,
// TODO: Should we wrap this in a `Mutex` so that calling functions from multiple // TODO: Should we wrap this in a `Mutex` so that calling functions from multiple
// threads doesn't cause data races? // threads doesn't cause data races?
table: Option<(TableType, Vec<u32>)>,
memory: Option<MemoryType>, memory: Option<MemoryType>,
} }
pub fn quickhash<H: Hash>(h: H) -> u64 {
let mut hasher = std::collections::hash_map::DefaultHasher::new();
h.hash(&mut hasher);
hasher.finish()
}
impl TranslatedModule { impl TranslatedModule {
pub fn instantiate(mut self) -> ExecutableModule { pub fn instantiate(self) -> ExecutableModule {
let table = {
let code_section = self
.translated_code_section
.as_ref()
.expect("We don't currently support a table section without a code section");
let ctx = &self.ctx;
self.table
.as_mut()
.map(|&mut (_, ref mut idxs)| {
let initial = idxs
.iter()
.map(|i| {
let start = code_section.func_start(*i as _);
let ty = ctx.func_type(*i);
RuntimeFunc {
func_start: start,
sig_hash: quickhash(ty),
}
})
.collect::<Vec<_>>();
let out = BoxSlice::from(initial.into_boxed_slice());
out
})
.unwrap_or(BoxSlice {
ptr: std::ptr::NonNull::dangling().as_ptr(),
len: 0,
})
};
let mem_size = self.memory.map(|m| m.limits.initial).unwrap_or(0) as usize; let mem_size = self.memory.map(|m| m.limits.initial).unwrap_or(0) as usize;
let mem: BoxSlice<_> = vec![0u8; mem_size * WASM_PAGE_SIZE] let mem: BoxSlice<_> = vec![0u8; mem_size * WASM_PAGE_SIZE]
.into_boxed_slice() .into_boxed_slice()
.into(); .into();
let ctx = if mem.len > 0 || table.len > 0 { let ctx = if mem.len > 0 {
let hashes = self.ctx.types.iter().map(quickhash).collect::<Vec<_>>(); Some(Box::new(VmCtx { mem }) as Box<VmCtx>)
// Hardcoded maximum number of hashes supported for now - we will eventually port all our
// tests over to wasmtime which will make this obsolete so implementing this properly is
// unnecessary.
let mut out = [0; 64];
// This will panic if `hashes.len() > 64`
out[..hashes.len()].copy_from_slice(&hashes[..]);
Some(Box::new(GVmCtx {
table,
mem,
hashes: out,
}) as Box<VmCtx>)
} else { } else {
None None
}; };
@@ -248,26 +192,6 @@ impl ExecutableModule {
} }
} }
type FuncRef = *const u8;
pub struct RuntimeFunc {
sig_hash: u64,
func_start: FuncRef,
}
unsafe impl Send for RuntimeFunc {}
unsafe impl Sync for RuntimeFunc {}
impl RuntimeFunc {
pub fn offset_of_sig_hash() -> usize {
offset_of!(Self, sig_hash)
}
pub fn offset_of_func_start() -> usize {
offset_of!(Self, func_start)
}
}
struct BoxSlice<T> { struct BoxSlice<T> {
len: usize, len: usize,
ptr: *mut T, ptr: *mut T,
@@ -293,44 +217,22 @@ impl<T> Drop for BoxSlice<T> {
} }
} }
pub type VmCtx = GVmCtx<[u64]>; pub struct VmCtx {
pub struct GVmCtx<T: ?Sized> {
table: BoxSlice<RuntimeFunc>,
mem: BoxSlice<u8>, mem: BoxSlice<u8>,
hashes: T,
} }
impl<T: ?Sized> GVmCtx<T> { impl VmCtx {
pub fn offset_of_memory_ptr() -> u32 { pub fn offset_of_memory_ptr() -> u32 {
offset_of!(GVmCtx<[u64; 0]>, mem.ptr) offset_of!(VmCtx, mem.ptr)
.try_into() .try_into()
.expect("Offset exceeded size of u32") .expect("Offset exceeded size of u32")
} }
pub fn offset_of_memory_len() -> u32 { pub fn offset_of_memory_len() -> u32 {
offset_of!(GVmCtx<[u64; 0]>, mem.len) offset_of!(VmCtx, mem.len)
.try_into() .try_into()
.expect("Offset exceeded size of u32") .expect("Offset exceeded size of u32")
} }
pub fn offset_of_funcs_ptr() -> u8 {
offset_of!(GVmCtx<[u64; 0]>, table.ptr)
.try_into()
.expect("Offset exceeded size of u8")
}
pub fn offset_of_funcs_len() -> u8 {
offset_of!(GVmCtx<[u64; 0]>, table.len)
.try_into()
.expect("Offset exceeded size of u8")
}
pub fn offset_of_hashes() -> u8 {
offset_of!(GVmCtx<[u64; 0]>, hashes)
.try_into()
.expect("Offset exceeded size of u8")
}
} }
#[derive(Default, Debug)] #[derive(Default, Debug)]
@@ -545,19 +447,16 @@ impl ModuleContext for SimpleContext {
VmCtx::offset_of_memory_len() VmCtx::offset_of_memory_len()
} }
fn vmctx_vmtable_definition(&self, defined_table_index: u32) -> u32 { fn vmctx_vmtable_definition(&self, _defined_table_index: u32) -> u32 {
assert_eq!(defined_table_index, 0); unimplemented!()
VmCtx::offset_of_funcs_ptr() as _
} }
fn vmctx_vmtable_definition_base(&self, defined_table_index: u32) -> u32 { fn vmctx_vmtable_definition_base(&self, _defined_table_index: u32) -> u32 {
assert_eq!(defined_table_index, 0); unimplemented!()
VmCtx::offset_of_funcs_ptr() as _
} }
fn vmctx_vmtable_definition_current_elements(&self, defined_table_index: u32) -> u32 { fn vmctx_vmtable_definition_current_elements(&self, _defined_table_index: u32) -> u32 {
assert_eq!(defined_table_index, 0); unimplemented!()
VmCtx::offset_of_funcs_len() as _
} }
fn vmtable_definition_base(&self) -> u8 { fn vmtable_definition_base(&self) -> u8 {
@@ -573,19 +472,19 @@ impl ModuleContext for SimpleContext {
} }
fn vmcaller_checked_anyfunc_type_index(&self) -> u8 { fn vmcaller_checked_anyfunc_type_index(&self) -> u8 {
RuntimeFunc::offset_of_sig_hash() as _ unimplemented!()
} }
fn vmcaller_checked_anyfunc_func_ptr(&self) -> u8 { fn vmcaller_checked_anyfunc_func_ptr(&self) -> u8 {
RuntimeFunc::offset_of_func_start() as _ unimplemented!()
} }
fn size_of_vmcaller_checked_anyfunc(&self) -> u8 { fn size_of_vmcaller_checked_anyfunc(&self) -> u8 {
std::mem::size_of::<RuntimeFunc>() as _ unimplemented!()
} }
fn vmctx_vmshared_signature_id(&self, signature_idx: u32) -> u32 { fn vmctx_vmshared_signature_id(&self, _signature_idx: u32) -> u32 {
VmCtx::offset_of_hashes() as u32 + signature_idx * std::mem::size_of::<u64>() as u32 unimplemented!()
} }
// TODO: type of a global // TODO: type of a global
@@ -599,7 +498,6 @@ pub fn translate(data: &[u8]) -> Result<ExecutableModule, Error> {
pub fn translate_only(data: &[u8]) -> Result<TranslatedModule, Error> { pub fn translate_only(data: &[u8]) -> Result<TranslatedModule, Error> {
let mut reader = ModuleReader::new(data)?; let mut reader = ModuleReader::new(data)?;
let mut output = TranslatedModule::default(); let mut output = TranslatedModule::default();
let mut table = None;
reader.skip_custom_sections()?; reader.skip_custom_sections()?;
if reader.eof() { if reader.eof() {
@@ -642,11 +540,7 @@ pub fn translate_only(data: &[u8]) -> Result<TranslatedModule, Error> {
if let SectionCode::Table = section.code { if let SectionCode::Table = section.code {
let tables = section.get_table_section_reader()?; let tables = section.get_table_section_reader()?;
let mut tables = translate_sections::table(tables)?; translate_sections::table(tables)?;
assert!(tables.len() <= 1);
table = tables.drain(..).next();
reader.skip_custom_sections()?; reader.skip_custom_sections()?;
if reader.eof() { if reader.eof() {
@@ -712,12 +606,7 @@ pub fn translate_only(data: &[u8]) -> Result<TranslatedModule, Error> {
if let SectionCode::Element = section.code { if let SectionCode::Element = section.code {
let elements = section.get_element_section_reader()?; let elements = section.get_element_section_reader()?;
let elements = translate_sections::element(elements)?; translate_sections::element(elements)?;
output.table = Some((
table.expect("Element section with no table section"),
elements,
));
reader.skip_custom_sections()?; reader.skip_custom_sections()?;
if reader.eof() { if reader.eof() {

View File

@@ -6,7 +6,7 @@ use cranelift_codegen::{binemit, ir};
use wasmparser::{ use wasmparser::{
CodeSectionReader, DataSectionReader, ElementSectionReader, ExportSectionReader, FuncType, CodeSectionReader, DataSectionReader, ElementSectionReader, ExportSectionReader, FuncType,
FunctionSectionReader, GlobalSectionReader, ImportSectionReader, MemorySectionReader, FunctionSectionReader, GlobalSectionReader, ImportSectionReader, MemorySectionReader,
MemoryType, Operator, TableSectionReader, TableType, TypeSectionReader, MemoryType, TableSectionReader, TableType, TypeSectionReader,
}; };
/// Parses the Type section of the wasm module. /// Parses the Type section of the wasm module.
@@ -69,37 +69,12 @@ pub fn start(_index: u32) -> Result<(), Error> {
} }
/// Parses the Element section of the wasm module. /// Parses the Element section of the wasm module.
pub fn element(elements: ElementSectionReader) -> Result<Vec<u32>, Error> { pub fn element(elements: ElementSectionReader) -> Result<(), Error> {
let mut out = Vec::new();
for entry in elements { for entry in elements {
let entry = entry?; entry?;
assert_eq!(entry.table_index, 0);
let offset = {
let mut reader = entry.init_expr.get_operators_reader();
let out = match reader.read() {
Ok(Operator::I32Const { value }) => value,
_ => panic!("We only support i32.const table init expressions right now"),
};
//reader.ensure_end()?;
out
};
assert_eq!(offset, out.len() as i32);
let elements = entry
.items
.get_items_reader()?
.into_iter()
.collect::<Result<Vec<_>, _>>()?;
out.extend(elements);
} }
Ok(out) Ok(())
} }
struct UnimplementedRelocSink; struct UnimplementedRelocSink;

Submodule wasmparser.rs deleted from e8bc42b377