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"
dynasm = "0.3"
dynasmrt = "0.3"
wasmparser = { path = "./wasmparser.rs" }
wasmparser = "0.29"
memoffset = "0.2"
itertools = "0.8"
capstone = "0.5.0"

View File

@@ -1,5 +1,5 @@
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 cranelift_codegen::{binemit, ir};
use dynasm::dynasm;
@@ -459,11 +459,11 @@ impl ValueLocation {
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)
}
fn imm_f64(self) -> Option<wasmparser::Ieee64> {
fn imm_f64(self) -> Option<Ieee64> {
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) => {{
let (left, right, this) = ($left, $right, $self);
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())
} else {
ValueLocation::Immediate(0i32.into())
@@ -1410,8 +1410,8 @@ macro_rules! binop_f32 {
binop!(
$name,
$instr,
|a: wasmparser::Ieee32, b: wasmparser::Ieee32| wasmparser::Ieee32(
$const_fallback(f32::from_bits(a.bits()), f32::from_bits(b.bits())).to_bits()
|a: Ieee32, b: Ieee32| Ieee32::from_bits(
$const_fallback(f32::from_bits(a.to_bits()), f32::from_bits(b.to_bits())).to_bits()
),
Rx,
rx,
@@ -1427,8 +1427,8 @@ macro_rules! commutative_binop_f32 {
commutative_binop!(
$name,
$instr,
|a: wasmparser::Ieee32, b: wasmparser::Ieee32| wasmparser::Ieee32(
$const_fallback(f32::from_bits(a.bits()), f32::from_bits(b.bits())).to_bits()
|a: Ieee32, b: Ieee32| Ieee32::from_bits(
$const_fallback(f32::from_bits(a.to_bits()), f32::from_bits(b.to_bits())).to_bits()
),
Rx,
rx,
@@ -1444,8 +1444,8 @@ macro_rules! binop_f64 {
binop!(
$name,
$instr,
|a: wasmparser::Ieee64, b: wasmparser::Ieee64| wasmparser::Ieee64(
$const_fallback(f64::from_bits(a.bits()), f64::from_bits(b.bits())).to_bits()
|a: Ieee64, b: Ieee64| Ieee64::from_bits(
$const_fallback(f64::from_bits(a.to_bits()), f64::from_bits(b.to_bits())).to_bits()
),
Rx,
rx,
@@ -1461,8 +1461,8 @@ macro_rules! commutative_binop_f64 {
commutative_binop!(
$name,
$instr,
|a: wasmparser::Ieee64, b: wasmparser::Ieee64| wasmparser::Ieee64(
$const_fallback(f64::from_bits(a.bits()), f64::from_bits(b.bits())).to_bits()
|a: Ieee64, b: Ieee64| Ieee64::from_bits(
$const_fallback(f64::from_bits(a.to_bits()), f64::from_bits(b.to_bits())).to_bits()
),
Rx,
rx,
@@ -1998,13 +1998,13 @@ impl<'this, M: ModuleContext> Context<'this, M> {
f32_eq,
cmpeqss,
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!(
f32_ne,
cmpneqss,
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);
@@ -2013,13 +2013,13 @@ impl<'this, M: ModuleContext> Context<'this, M> {
f64_eq,
cmpeqsd,
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!(
f64_ne,
cmpneqsd,
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`?
@@ -2866,7 +2866,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = if let Some(i) = val.imm_f32() {
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 {
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() {
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 {
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() {
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 {
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() {
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 {
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() {
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 {
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() {
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 {
let reg = self.into_temp_reg(GPRType::Rx, val);
@@ -2991,8 +2991,10 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = if let (Some(left), Some(right)) = (left.imm_f32(), right.imm_f32()) {
ValueLocation::Immediate(
wasmparser::Ieee32((left.bits() & REST_MASK_F32) | (right.bits() & SIGN_MASK_F32))
.into(),
Ieee32::from_bits(
(left.to_bits() & REST_MASK_F32) | (right.to_bits() & SIGN_MASK_F32),
)
.into(),
)
} else {
let left = self.into_temp_reg(GPRType::Rx, left);
@@ -3020,8 +3022,10 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = if let (Some(left), Some(right)) = (left.imm_f64(), right.imm_f64()) {
ValueLocation::Immediate(
wasmparser::Ieee64((left.bits() & REST_MASK_F64) | (right.bits() & SIGN_MASK_F64))
.into(),
Ieee64::from_bits(
(left.to_bits() & REST_MASK_F64) | (right.to_bits() & SIGN_MASK_F64),
)
.into(),
)
} else {
let left = self.into_temp_reg(GPRType::Rx, left);
@@ -3134,7 +3138,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
f32,
f64,
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!(
f32_from_f64,
@@ -3146,14 +3150,14 @@ impl<'this, M: ModuleContext> Context<'this, M> {
f64,
f32,
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) {
let mut val = self.pop();
let out_val = match val {
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 => {
let reg = self.into_reg(F32, other);
@@ -3192,7 +3196,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val {
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 => {
let reg = self.into_temp_reg(F32, other);
@@ -3234,7 +3238,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val {
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 => {
let reg = self.into_reg(F32, other);
@@ -3274,7 +3278,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val {
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 => {
let reg = self.into_temp_reg(F32, other);
@@ -3322,7 +3326,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
i32,
f32,
as_i32,
|a| wasmparser::Ieee32((a as f32).to_bits())
|a| Ieee32::from_bits((a as f32).to_bits())
);
conversion!(
f64_convert_from_i32_s,
@@ -3334,7 +3338,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
i32,
f64,
as_i32,
|a| wasmparser::Ieee64((a as f64).to_bits())
|a| Ieee64::from_bits((a as f64).to_bits())
);
conversion!(
f32_convert_from_i64_s,
@@ -3346,7 +3350,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
i64,
f32,
as_i32,
|a| wasmparser::Ieee32((a as f32).to_bits())
|a| Ieee32::from_bits((a as f32).to_bits())
);
conversion!(
f64_convert_from_i64_s,
@@ -3358,7 +3362,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
i64,
f64,
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) {
@@ -3366,7 +3370,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val {
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 => {
let reg = self.into_temp_reg(F32, other);
@@ -3405,7 +3409,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val {
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 => {
let reg = self.into_reg(F32, other);
@@ -3445,7 +3449,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val {
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);
@@ -3487,7 +3491,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val {
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);
@@ -3530,7 +3534,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val {
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);
@@ -3557,7 +3561,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val {
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);
@@ -3584,7 +3588,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val {
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);
@@ -3624,7 +3628,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out_val = match val {
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);
@@ -3664,7 +3668,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = match val {
ValueLocation::Immediate(imm) => {
ValueLocation::Immediate(imm.as_f32().unwrap().bits().into())
ValueLocation::Immediate(imm.as_f32().unwrap().to_bits().into())
}
val => val,
};
@@ -3677,7 +3681,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = match val {
ValueLocation::Immediate(imm) => {
ValueLocation::Immediate(imm.as_f64().unwrap().bits().into())
ValueLocation::Immediate(imm.as_f64().unwrap().to_bits().into())
}
val => val,
};
@@ -3690,7 +3694,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = match val {
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,
};
@@ -3703,7 +3707,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
let out = match val {
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,
};
@@ -3736,8 +3740,10 @@ impl<'this, M: ModuleContext> Context<'this, M> {
addss,
orps,
as_f32,
|a: wasmparser::Ieee32, b: wasmparser::Ieee32| wasmparser::Ieee32(
f32::from_bits(a.0).min(f32::from_bits(b.0)).to_bits()
|a: Ieee32, b: Ieee32| Ieee32::from_bits(
f32::from_bits(a.to_bits())
.min(f32::from_bits(b.to_bits()))
.to_bits()
)
);
minmax_float!(
@@ -3747,8 +3753,10 @@ impl<'this, M: ModuleContext> Context<'this, M> {
addss,
andps,
as_f32,
|a: wasmparser::Ieee32, b: wasmparser::Ieee32| wasmparser::Ieee32(
f32::from_bits(a.0).max(f32::from_bits(b.0)).to_bits()
|a: Ieee32, b: Ieee32| Ieee32::from_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);
@@ -3799,8 +3807,10 @@ impl<'this, M: ModuleContext> Context<'this, M> {
addsd,
orpd,
as_f64,
|a: wasmparser::Ieee64, b: wasmparser::Ieee64| wasmparser::Ieee64(
f64::from_bits(a.0).min(f64::from_bits(b.0)).to_bits()
|a: Ieee64, b: Ieee64| Ieee64::from_bits(
f64::from_bits(a.to_bits())
.min(f64::from_bits(b.to_bits()))
.to_bits()
)
);
minmax_float!(
@@ -3810,8 +3820,10 @@ impl<'this, M: ModuleContext> Context<'this, M> {
addsd,
andpd,
as_f64,
|a: wasmparser::Ieee64, b: wasmparser::Ieee64| wasmparser::Ieee64(
f64::from_bits(a.0).max(f64::from_bits(b.0)).to_bits()
|a: Ieee64, b: Ieee64| Ieee64::from_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);

View File

@@ -7,7 +7,8 @@ use std::{
ops::RangeInclusive,
};
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>(
@@ -49,8 +50,8 @@ impl fmt::Display for Value {
match self {
Value::I32(v) => write!(f, "{}i32", v),
Value::I64(v) => write!(f, "{}i64", v),
Value::F32(v) => write!(f, "{}f32", f32::from_bits(v.bits())),
Value::F64(v) => write!(f, "{}f64", f64::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.to_bits())),
}
}
}
@@ -304,13 +305,6 @@ pub enum 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>;
#[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?
#[derive(Debug, Clone)]
pub enum Operator<Label> {
@@ -1750,79 +1796,105 @@ where
smallvec![Operator::SetGlobal(global_index)]
}
WasmOperator::I32Load { memarg } => smallvec![Operator::Load { ty: I32, memarg }],
WasmOperator::I64Load { memarg } => smallvec![Operator::Load { ty: I64, memarg }],
WasmOperator::F32Load { memarg } => smallvec![Operator::Load { ty: F32, memarg }],
WasmOperator::F64Load { memarg } => smallvec![Operator::Load { ty: F64, memarg }],
WasmOperator::I32Load { memarg } => smallvec![Operator::Load {
ty: I32,
memarg: memarg.into()
}],
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 {
ty: sint::I32,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I32Load8U { memarg } => smallvec![Operator::Load8 {
ty: sint::U32,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I32Load16S { memarg } => smallvec![Operator::Load16 {
ty: sint::I32,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I32Load16U { memarg } => smallvec![Operator::Load16 {
ty: sint::U32,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I64Load8S { memarg } => smallvec![Operator::Load8 {
ty: sint::I64,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I64Load8U { memarg } => smallvec![Operator::Load8 {
ty: sint::U64,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I64Load16S { memarg } => smallvec![Operator::Load16 {
ty: sint::I64,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I64Load16U { memarg } => smallvec![Operator::Load16 {
ty: sint::U64,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I64Load32S { memarg } => smallvec![Operator::Load32 {
sign: Signedness::Signed,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I64Load32U { memarg } => smallvec![Operator::Load32 {
sign: Signedness::Unsigned,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I32Store { memarg } => smallvec![Operator::Store { ty: I32, memarg }],
WasmOperator::I64Store { memarg } => smallvec![Operator::Store { ty: I64, memarg }],
WasmOperator::F32Store { memarg } => smallvec![Operator::Store { ty: F32, memarg }],
WasmOperator::F64Store { memarg } => smallvec![Operator::Store { ty: F64, memarg }],
WasmOperator::I32Store { memarg } => smallvec![Operator::Store {
ty: I32,
memarg: memarg.into()
}],
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 {
ty: Size::_32,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I32Store16 { memarg } => smallvec![Operator::Store16 {
ty: Size::_32,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I64Store8 { memarg } => smallvec![Operator::Store8 {
ty: Size::_64,
memarg,
memarg: memarg.into(),
}],
WasmOperator::I64Store16 { memarg } => smallvec![Operator::Store16 {
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::MemoryGrow { reserved } => smallvec![Operator::MemoryGrow { reserved }],
WasmOperator::I32Const { value } => smallvec![Operator::Const(Value::I32(value))],
WasmOperator::I64Const { value } => smallvec![Operator::Const(Value::I64(value))],
WasmOperator::F32Const { value } => smallvec![Operator::Const(Value::F32(value))],
WasmOperator::F64Const { value } => smallvec![Operator::Const(Value::F64(value))],
WasmOperator::F32Const { value } => smallvec![Operator::Const(Value::F32(value.into()))],
WasmOperator::F64Const { value } => smallvec![Operator::Const(Value::F64(value.into()))],
WasmOperator::RefNull => unimplemented!("{:?}", op),
WasmOperator::RefIsNull => unimplemented!("{:?}", op),
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},
isa,
};
use std::{
convert::TryInto,
hash::{Hash, Hasher},
mem,
};
use wasmparser::{FuncType, MemoryType, ModuleReader, SectionCode, TableType, Type};
use std::{convert::TryInto, mem};
use wasmparser::{FuncType, MemoryType, ModuleReader, SectionCode, Type};
pub trait AsValueType {
const TYPE: Type;
@@ -105,70 +101,18 @@ pub struct TranslatedModule {
ctx: SimpleContext,
// TODO: Should we wrap this in a `Mutex` so that calling functions from multiple
// threads doesn't cause data races?
table: Option<(TableType, Vec<u32>)>,
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 {
pub fn instantiate(mut 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,
})
};
pub fn instantiate(self) -> ExecutableModule {
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]
.into_boxed_slice()
.into();
let ctx = if mem.len > 0 || table.len > 0 {
let hashes = self.ctx.types.iter().map(quickhash).collect::<Vec<_>>();
// 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>)
let ctx = if mem.len > 0 {
Some(Box::new(VmCtx { mem }) as Box<VmCtx>)
} else {
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> {
len: usize,
ptr: *mut T,
@@ -293,44 +217,22 @@ impl<T> Drop for BoxSlice<T> {
}
}
pub type VmCtx = GVmCtx<[u64]>;
pub struct GVmCtx<T: ?Sized> {
table: BoxSlice<RuntimeFunc>,
pub struct VmCtx {
mem: BoxSlice<u8>,
hashes: T,
}
impl<T: ?Sized> GVmCtx<T> {
impl VmCtx {
pub fn offset_of_memory_ptr() -> u32 {
offset_of!(GVmCtx<[u64; 0]>, mem.ptr)
offset_of!(VmCtx, mem.ptr)
.try_into()
.expect("Offset exceeded size of u32")
}
pub fn offset_of_memory_len() -> u32 {
offset_of!(GVmCtx<[u64; 0]>, mem.len)
offset_of!(VmCtx, mem.len)
.try_into()
.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)]
@@ -545,19 +447,16 @@ impl ModuleContext for SimpleContext {
VmCtx::offset_of_memory_len()
}
fn vmctx_vmtable_definition(&self, defined_table_index: u32) -> u32 {
assert_eq!(defined_table_index, 0);
VmCtx::offset_of_funcs_ptr() as _
fn vmctx_vmtable_definition(&self, _defined_table_index: u32) -> u32 {
unimplemented!()
}
fn vmctx_vmtable_definition_base(&self, defined_table_index: u32) -> u32 {
assert_eq!(defined_table_index, 0);
VmCtx::offset_of_funcs_ptr() as _
fn vmctx_vmtable_definition_base(&self, _defined_table_index: u32) -> u32 {
unimplemented!()
}
fn vmctx_vmtable_definition_current_elements(&self, defined_table_index: u32) -> u32 {
assert_eq!(defined_table_index, 0);
VmCtx::offset_of_funcs_len() as _
fn vmctx_vmtable_definition_current_elements(&self, _defined_table_index: u32) -> u32 {
unimplemented!()
}
fn vmtable_definition_base(&self) -> u8 {
@@ -573,19 +472,19 @@ impl ModuleContext for SimpleContext {
}
fn vmcaller_checked_anyfunc_type_index(&self) -> u8 {
RuntimeFunc::offset_of_sig_hash() as _
unimplemented!()
}
fn vmcaller_checked_anyfunc_func_ptr(&self) -> u8 {
RuntimeFunc::offset_of_func_start() as _
unimplemented!()
}
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 {
VmCtx::offset_of_hashes() as u32 + signature_idx * std::mem::size_of::<u64>() as u32
fn vmctx_vmshared_signature_id(&self, _signature_idx: u32) -> u32 {
unimplemented!()
}
// 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> {
let mut reader = ModuleReader::new(data)?;
let mut output = TranslatedModule::default();
let mut table = None;
reader.skip_custom_sections()?;
if reader.eof() {
@@ -642,11 +540,7 @@ pub fn translate_only(data: &[u8]) -> Result<TranslatedModule, Error> {
if let SectionCode::Table = section.code {
let tables = section.get_table_section_reader()?;
let mut tables = translate_sections::table(tables)?;
assert!(tables.len() <= 1);
table = tables.drain(..).next();
translate_sections::table(tables)?;
reader.skip_custom_sections()?;
if reader.eof() {
@@ -712,12 +606,7 @@ pub fn translate_only(data: &[u8]) -> Result<TranslatedModule, Error> {
if let SectionCode::Element = section.code {
let elements = section.get_element_section_reader()?;
let elements = translate_sections::element(elements)?;
output.table = Some((
table.expect("Element section with no table section"),
elements,
));
translate_sections::element(elements)?;
reader.skip_custom_sections()?;
if reader.eof() {

View File

@@ -6,7 +6,7 @@ use cranelift_codegen::{binemit, ir};
use wasmparser::{
CodeSectionReader, DataSectionReader, ElementSectionReader, ExportSectionReader, FuncType,
FunctionSectionReader, GlobalSectionReader, ImportSectionReader, MemorySectionReader,
MemoryType, Operator, TableSectionReader, TableType, TypeSectionReader,
MemoryType, TableSectionReader, TableType, TypeSectionReader,
};
/// 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.
pub fn element(elements: ElementSectionReader) -> Result<Vec<u32>, Error> {
let mut out = Vec::new();
pub fn element(elements: ElementSectionReader) -> Result<(), Error> {
for entry in elements {
let 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);
entry?;
}
Ok(out)
Ok(())
}
struct UnimplementedRelocSink;

Submodule wasmparser.rs deleted from e8bc42b377