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)) };
|
||||
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 {
|
||||
|
@ -205,6 +229,7 @@ struct TypeIds {
|
|||
i64_t: u32,
|
||||
f32_t: u32,
|
||||
f64_t: u32,
|
||||
v128_t: u32,
|
||||
}
|
||||
|
||||
impl TypeIds {
|
||||
|
@ -215,6 +240,7 @@ impl TypeIds {
|
|||
i64_t: unsafe { BinaryenTypeInt64() },
|
||||
f32_t: unsafe { BinaryenTypeFloat32() },
|
||||
f64_t: unsafe { BinaryenTypeFloat64() },
|
||||
v128_t: unsafe { BinaryenTypeVec128() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -230,6 +256,7 @@ pub enum Type {
|
|||
I64,
|
||||
F32,
|
||||
F64,
|
||||
V128,
|
||||
}
|
||||
|
||||
impl Type {
|
||||
|
@ -250,7 +277,7 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
fn to_kind(&self) -> u32 {
|
||||
pub(crate) fn to_kind(&self) -> BinaryenType {
|
||||
let tys = &*TYPE_IDS;
|
||||
match self {
|
||||
&Type::None => tys.none_t,
|
||||
|
@ -258,10 +285,29 @@ impl Type {
|
|||
&Type::I64 => tys.i64_t,
|
||||
&Type::F32 => tys.f32_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> {
|
||||
if name.is_null() {
|
||||
None
|
||||
|
@ -517,11 +563,14 @@ extern "C" {
|
|||
fn BinaryenUnreachableId() -> u32;
|
||||
fn BinaryenPopId() -> u32;
|
||||
|
||||
fn BinaryenTypeNone() -> u32;
|
||||
fn BinaryenTypeInt32() -> u32;
|
||||
fn BinaryenTypeInt64() -> u32;
|
||||
fn BinaryenTypeFloat32() -> u32;
|
||||
fn BinaryenTypeFloat64() -> u32;
|
||||
fn BinaryenTypeNone() -> BinaryenType;
|
||||
fn BinaryenTypeInt32() -> BinaryenType;
|
||||
fn BinaryenTypeInt64() -> BinaryenType;
|
||||
fn BinaryenTypeFloat32() -> BinaryenType;
|
||||
fn BinaryenTypeFloat64() -> BinaryenType;
|
||||
fn BinaryenTypeVec128() -> BinaryenType;
|
||||
|
||||
fn BinaryenTypeCreate(tys: *const BinaryenType, n_tys: BinaryenIndex) -> BinaryenType;
|
||||
|
||||
fn BinaryenAddInt32() -> u32;
|
||||
fn BinaryenSubInt32() -> u32;
|
||||
|
@ -543,6 +592,16 @@ extern "C" {
|
|||
ty: BinaryenType,
|
||||
) -> 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 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>> {
|
||||
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 {
|
||||
if let Some(body) = self.func(func).body() {
|
||||
let mut binaryen_func = binaryen_module.func(func);
|
||||
|
|
Loading…
Reference in a new issue