WIP.
This commit is contained in:
parent
8e8464f76a
commit
676ee3a1d2
|
@ -115,6 +115,30 @@ impl Function {
|
||||||
let s = unsafe { CStr::from_ptr(BinaryenFunctionGetName(self.1)) };
|
let s = unsafe { CStr::from_ptr(BinaryenFunctionGetName(self.1)) };
|
||||||
s.to_str().unwrap()
|
s.to_str().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create(
|
||||||
|
module: &mut Module,
|
||||||
|
params: impl Iterator<Item = wasmparser::Type>,
|
||||||
|
results: impl Iterator<Item = wasmparser::Type>,
|
||||||
|
locals: impl Iterator<Item = wasmparser::Type>,
|
||||||
|
body: Expression,
|
||||||
|
) -> Function {
|
||||||
|
let params = tys_to_binaryen(params);
|
||||||
|
let results = tys_to_binaryen(results);
|
||||||
|
let locals: Vec<BinaryenType> = locals.map(|&ty| Type::from(ty).to_kind()).collect();
|
||||||
|
let ptr = unsafe {
|
||||||
|
BinaryenAddFunc(
|
||||||
|
module.0,
|
||||||
|
/* name = */ std::ptr::null(),
|
||||||
|
params,
|
||||||
|
results,
|
||||||
|
locals.as_ptr(),
|
||||||
|
locals.len() as BinaryenIndex,
|
||||||
|
body.1,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
Function(module.0, ptr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Export {
|
impl Export {
|
||||||
|
@ -205,6 +229,7 @@ struct TypeIds {
|
||||||
i64_t: u32,
|
i64_t: u32,
|
||||||
f32_t: u32,
|
f32_t: u32,
|
||||||
f64_t: u32,
|
f64_t: u32,
|
||||||
|
v128_t: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeIds {
|
impl TypeIds {
|
||||||
|
@ -215,6 +240,7 @@ impl TypeIds {
|
||||||
i64_t: unsafe { BinaryenTypeInt64() },
|
i64_t: unsafe { BinaryenTypeInt64() },
|
||||||
f32_t: unsafe { BinaryenTypeFloat32() },
|
f32_t: unsafe { BinaryenTypeFloat32() },
|
||||||
f64_t: unsafe { BinaryenTypeFloat64() },
|
f64_t: unsafe { BinaryenTypeFloat64() },
|
||||||
|
v128_t: unsafe { BinaryenTypeVec128() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,6 +256,7 @@ pub enum Type {
|
||||||
I64,
|
I64,
|
||||||
F32,
|
F32,
|
||||||
F64,
|
F64,
|
||||||
|
V128,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Type {
|
impl Type {
|
||||||
|
@ -250,7 +277,7 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_kind(&self) -> u32 {
|
pub(crate) fn to_kind(&self) -> BinaryenType {
|
||||||
let tys = &*TYPE_IDS;
|
let tys = &*TYPE_IDS;
|
||||||
match self {
|
match self {
|
||||||
&Type::None => tys.none_t,
|
&Type::None => tys.none_t,
|
||||||
|
@ -258,10 +285,29 @@ impl Type {
|
||||||
&Type::I64 => tys.i64_t,
|
&Type::I64 => tys.i64_t,
|
||||||
&Type::F32 => tys.f32_t,
|
&Type::F32 => tys.f32_t,
|
||||||
&Type::F64 => tys.f64_t,
|
&Type::F64 => tys.f64_t,
|
||||||
|
&Type::V128 => tys.v128_t,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<wasmparser::Type> for Type {
|
||||||
|
fn from(ty: wasmparser::Type) -> Self {
|
||||||
|
match ty {
|
||||||
|
wasmparser::Type::I32 => Type::I32,
|
||||||
|
wasmparser::Type::I64 => Type::I64,
|
||||||
|
wasmparser::Type::F32 => Type::F32,
|
||||||
|
wasmparser::Type::F64 => Type::F64,
|
||||||
|
wasmparser::Type::V128 => Type::V128,
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tys_to_binaryen(tys: impl Iterator<Item = wasmparser::Type>) -> BinaryenType {
|
||||||
|
let tys: Vec<BinaryenType> = tys.map(|&ty| Type::from(ty).to_kind()).collect();
|
||||||
|
unsafe { BinaryenTypeCreate(tys.as_ptr(), tys.len() as BinaryenIndex) }
|
||||||
|
}
|
||||||
|
|
||||||
fn name_to_string(name: *const c_char) -> Option<String> {
|
fn name_to_string(name: *const c_char) -> Option<String> {
|
||||||
if name.is_null() {
|
if name.is_null() {
|
||||||
None
|
None
|
||||||
|
@ -517,11 +563,14 @@ extern "C" {
|
||||||
fn BinaryenUnreachableId() -> u32;
|
fn BinaryenUnreachableId() -> u32;
|
||||||
fn BinaryenPopId() -> u32;
|
fn BinaryenPopId() -> u32;
|
||||||
|
|
||||||
fn BinaryenTypeNone() -> u32;
|
fn BinaryenTypeNone() -> BinaryenType;
|
||||||
fn BinaryenTypeInt32() -> u32;
|
fn BinaryenTypeInt32() -> BinaryenType;
|
||||||
fn BinaryenTypeInt64() -> u32;
|
fn BinaryenTypeInt64() -> BinaryenType;
|
||||||
fn BinaryenTypeFloat32() -> u32;
|
fn BinaryenTypeFloat32() -> BinaryenType;
|
||||||
fn BinaryenTypeFloat64() -> u32;
|
fn BinaryenTypeFloat64() -> BinaryenType;
|
||||||
|
fn BinaryenTypeVec128() -> BinaryenType;
|
||||||
|
|
||||||
|
fn BinaryenTypeCreate(tys: *const BinaryenType, n_tys: BinaryenIndex) -> BinaryenType;
|
||||||
|
|
||||||
fn BinaryenAddInt32() -> u32;
|
fn BinaryenAddInt32() -> u32;
|
||||||
fn BinaryenSubInt32() -> u32;
|
fn BinaryenSubInt32() -> u32;
|
||||||
|
@ -543,6 +592,16 @@ extern "C" {
|
||||||
ty: BinaryenType,
|
ty: BinaryenType,
|
||||||
) -> BinaryenExpression;
|
) -> BinaryenExpression;
|
||||||
|
|
||||||
|
fn BinaryenAddFunc(
|
||||||
|
module: BinaryenModule,
|
||||||
|
name: *const c_char,
|
||||||
|
params: BinaryenType,
|
||||||
|
results: BinaryenType,
|
||||||
|
vars: *const BinaryenType,
|
||||||
|
n_vars: BinaryenIndex,
|
||||||
|
body: BinaryenExpression,
|
||||||
|
) -> BinaryenFunction;
|
||||||
|
|
||||||
fn BinaryenUndefined() -> BinaryenType;
|
fn BinaryenUndefined() -> BinaryenType;
|
||||||
|
|
||||||
fn BinaryenLiteralInt32(x: i32) -> BinaryenLiteral;
|
fn BinaryenLiteralInt32(x: i32) -> BinaryenLiteral;
|
||||||
|
|
86
src/backend/lower.rs
Normal file
86
src/backend/lower.rs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
use crate::backend::binaryen;
|
||||||
|
use crate::ir::*;
|
||||||
|
use fxhash::FxHashMap;
|
||||||
|
|
||||||
|
pub(crate) fn generate_body(
|
||||||
|
body: &FunctionBody,
|
||||||
|
into_mod: &mut binaryen::Module,
|
||||||
|
) -> binaryen::Expression {
|
||||||
|
// For each block, generate an expr.
|
||||||
|
let mut block_exprs: FxHashMap<BlockId, binaryen::Expression> = FxHashMap::default();
|
||||||
|
let mut ctx = ElabCtx::default();
|
||||||
|
for block in body.blocks() {
|
||||||
|
let exprs = body[block]
|
||||||
|
.insts
|
||||||
|
.iter()
|
||||||
|
.map(|&inst| {
|
||||||
|
let inst = body.resolve_alias(inst);
|
||||||
|
elaborate_value(body, into_mod, &mut ctx, inst)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
block_exprs.insert(block, binaryen::Expression::block(into_mod, &exprs[..]));
|
||||||
|
}
|
||||||
|
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
struct ElabCtx {
|
||||||
|
value_to_expr: FxHashMap<Value, binaryen::Expression>,
|
||||||
|
block_params: FxHashMap<Value, LocalId>,
|
||||||
|
args: FxHashMap<Value, LocalId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElabCtx {
|
||||||
|
fn for_func(module: &Module, func: FuncId) -> ElabCtx {
|
||||||
|
let sig = module.func(func).sig();
|
||||||
|
let sig = module.signature(sig);
|
||||||
|
let body = module.func(func).body().unwrap();
|
||||||
|
|
||||||
|
let mut ctx = ElabCtx::default();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn elaborate_value(
|
||||||
|
body: &FunctionBody,
|
||||||
|
into_mod: &binaryen::Module,
|
||||||
|
ctx: &mut ElabCtx,
|
||||||
|
value: Value,
|
||||||
|
) -> binaryen::Expression {
|
||||||
|
let value = body.resolve_alias(value);
|
||||||
|
if let Some(expr) = ctx.value_to_expr.get(&value) {
|
||||||
|
return *expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
match &body[value] {
|
||||||
|
&ValueDef::BlockParam(block, idx) => {}
|
||||||
|
&ValueDef::Arg(idx) => {}
|
||||||
|
&ValueDef::PickOutput(value, idx) => {}
|
||||||
|
&ValueDef::Operator(op, ref args) => {}
|
||||||
|
|
||||||
|
&ValueDef::Alias(_) => unreachable!(),
|
||||||
|
&ValueDef::Placeholder => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn create_new_func(
|
||||||
|
module: &Module,
|
||||||
|
sig: SignatureId,
|
||||||
|
body: &FunctionBody,
|
||||||
|
into_mod: &mut binaryen::Module,
|
||||||
|
body_expr: binaryen::Expression,
|
||||||
|
) {
|
||||||
|
// Create param types.
|
||||||
|
let sig = module.signature(sig);
|
||||||
|
let _func = binaryen::Function::create(
|
||||||
|
into_mod,
|
||||||
|
sig.params.iter().copied(),
|
||||||
|
sig.returns.iter().copied(),
|
||||||
|
body.locals.iter().copied(),
|
||||||
|
body_expr,
|
||||||
|
);
|
||||||
|
}
|
|
@ -521,6 +521,12 @@ impl<'a> Module<'a> {
|
||||||
|
|
||||||
pub fn to_wasm_bytes(&self) -> Result<Vec<u8>> {
|
pub fn to_wasm_bytes(&self) -> Result<Vec<u8>> {
|
||||||
let mut binaryen_module = binaryen::Module::read(self.orig_bytes)?;
|
let mut binaryen_module = binaryen::Module::read(self.orig_bytes)?;
|
||||||
|
for new_func_idx in self.funcs.len()..binaryen_module.num_funcs() {
|
||||||
|
let sig = self.func(new_func_idx).sig();
|
||||||
|
let body = self.func(new_func_idx).body().unwrap();
|
||||||
|
let binaryen_expr = backend::lower::generate_body(body, &mut binaryen_module);
|
||||||
|
backend::lower::create_new_func(self, sig, body, &mut binaryen_module, binaryen_expr);
|
||||||
|
}
|
||||||
for &func in &self.dirty_funcs {
|
for &func in &self.dirty_funcs {
|
||||||
if let Some(body) = self.func(func).body() {
|
if let Some(body) = self.func(func).body() {
|
||||||
let mut binaryen_func = binaryen_module.func(func);
|
let mut binaryen_func = binaryen_module.func(func);
|
||||||
|
|
Loading…
Reference in a new issue