WIP.
This commit is contained in:
parent
676ee3a1d2
commit
589729566f
|
@ -125,7 +125,7 @@ impl Function {
|
|||
) -> 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 locals: Vec<BinaryenType> = locals.map(|ty| Type::from(ty).to_kind()).collect();
|
||||
let ptr = unsafe {
|
||||
BinaryenAddFunc(
|
||||
module.0,
|
||||
|
@ -139,6 +139,10 @@ impl Function {
|
|||
};
|
||||
Function(module.0, ptr)
|
||||
}
|
||||
|
||||
pub fn add_local(&mut self, ty: wasmparser::Type) -> usize {
|
||||
(unsafe { BinaryenFunctionAddVar(self.1, Type::from(ty).to_kind()) }) as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl Export {
|
||||
|
@ -224,12 +228,12 @@ lazy_static! {
|
|||
}
|
||||
|
||||
struct TypeIds {
|
||||
none_t: u32,
|
||||
i32_t: u32,
|
||||
i64_t: u32,
|
||||
f32_t: u32,
|
||||
f64_t: u32,
|
||||
v128_t: u32,
|
||||
none_t: BinaryenType,
|
||||
i32_t: BinaryenType,
|
||||
i64_t: BinaryenType,
|
||||
f32_t: BinaryenType,
|
||||
f64_t: BinaryenType,
|
||||
v128_t: BinaryenType,
|
||||
}
|
||||
|
||||
impl TypeIds {
|
||||
|
@ -260,7 +264,7 @@ pub enum Type {
|
|||
}
|
||||
|
||||
impl Type {
|
||||
fn from_kind(kind: u32) -> Option<Type> {
|
||||
fn from_kind(kind: BinaryenType) -> Option<Type> {
|
||||
let tys = &*TYPE_IDS;
|
||||
if kind == tys.none_t {
|
||||
Some(Type::None)
|
||||
|
@ -304,7 +308,7 @@ impl From<wasmparser::Type> for Type {
|
|||
}
|
||||
|
||||
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();
|
||||
let tys: Vec<BinaryenType> = tys.map(|ty| Type::from(ty).to_kind()).collect();
|
||||
unsafe { BinaryenTypeCreate(tys.as_ptr(), tys.len() as BinaryenIndex) }
|
||||
}
|
||||
|
||||
|
@ -450,6 +454,7 @@ extern "C" {
|
|||
fn BinaryenFunctionGetBody(ptr: BinaryenFunction) -> BinaryenExpression;
|
||||
fn BinaryenFunctionSetBody(ptr: BinaryenFunction, body: BinaryenExpression);
|
||||
fn BinaryenFunctionGetName(ptr: BinaryenFunction) -> *const c_char;
|
||||
fn BinaryenFunctionAddVar(ptr: BinaryenFunction, ty: BinaryenType) -> BinaryenIndex;
|
||||
fn BinaryenGetExport(ptr: BinaryenModule, name: *const c_char) -> BinaryenExport;
|
||||
fn BinaryenGetNumExports(ptr: BinaryenModule) -> u32;
|
||||
fn BinaryenGetExportByIndex(ptr: BinaryenModule, index: u32) -> BinaryenExport;
|
||||
|
@ -459,7 +464,7 @@ extern "C" {
|
|||
fn BinaryenExternalFunction() -> u32;
|
||||
|
||||
fn BinaryenExpressionGetId(ptr: BinaryenExpression) -> u32;
|
||||
fn BinaryenExpressionGetType(ptr: BinaryenExpression) -> u32;
|
||||
fn BinaryenExpressionGetType(ptr: BinaryenExpression) -> BinaryenType;
|
||||
fn BinaryenExpressionCopy(
|
||||
ptr: BinaryenExpression,
|
||||
module: BinaryenModule,
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
use crate::backend::binaryen;
|
||||
use crate::ir::*;
|
||||
use fxhash::FxHashMap;
|
||||
use wasmparser::Type;
|
||||
|
||||
/// Creates a body expression for a function. Returns that expression,
|
||||
/// and new locals (as their types) that were created as temporaries
|
||||
/// and need to be appended to `body.locals`.
|
||||
pub(crate) fn generate_body(
|
||||
body: &FunctionBody,
|
||||
into_mod: &mut binaryen::Module,
|
||||
) -> binaryen::Expression {
|
||||
) -> (Vec<Type>, binaryen::Expression) {
|
||||
// For each block, generate an expr.
|
||||
let mut block_exprs: FxHashMap<BlockId, binaryen::Expression> = FxHashMap::default();
|
||||
let mut ctx = ElabCtx::default();
|
||||
let mut ctx = ElabCtx::new(body, into_mod);
|
||||
for block in body.blocks() {
|
||||
let exprs = body[block]
|
||||
.insts
|
||||
|
@ -24,22 +28,33 @@ pub(crate) fn generate_body(
|
|||
todo!()
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[derive(Clone, Debug)]
|
||||
struct ElabCtx {
|
||||
value_to_expr: FxHashMap<Value, binaryen::Expression>,
|
||||
block_params: FxHashMap<Value, LocalId>,
|
||||
args: FxHashMap<Value, LocalId>,
|
||||
block_params: FxHashMap<(Block, usize), LocalId>,
|
||||
new_locals: Vec<Type>,
|
||||
}
|
||||
|
||||
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();
|
||||
fn new(body: &FunctionBody, into_mod: &mut binaryen::Module) -> ElabCtx {
|
||||
// Create locals for each blockparam.
|
||||
let mut block_params = FxHashMap::default();
|
||||
let mut next_local = body.locals.len() as LocalId;
|
||||
let mut new_locals = vec![];
|
||||
for block in body.blocks() {
|
||||
for &(ty, param) in &body[block].params {
|
||||
let new_local = next_local;
|
||||
next_local += 1;
|
||||
block_params.insert((ty, param), new_local);
|
||||
new_locals.push(ty);
|
||||
}
|
||||
}
|
||||
|
||||
let mut ctx = ElabCtx::default();
|
||||
|
||||
// TODO
|
||||
ElabCtx {
|
||||
value_to_expr: FxHashMap::default(),
|
||||
block_params,
|
||||
new_locals,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,6 +88,7 @@ pub(crate) fn create_new_func(
|
|||
body: &FunctionBody,
|
||||
into_mod: &mut binaryen::Module,
|
||||
body_expr: binaryen::Expression,
|
||||
new_locals: Vec<Type>,
|
||||
) {
|
||||
// Create param types.
|
||||
let sig = module.signature(sig);
|
||||
|
@ -80,7 +96,11 @@ pub(crate) fn create_new_func(
|
|||
into_mod,
|
||||
sig.params.iter().copied(),
|
||||
sig.returns.iter().copied(),
|
||||
body.locals.iter().copied(),
|
||||
body.locals
|
||||
.iter()
|
||||
.copied()
|
||||
.skip(body.n_params)
|
||||
.chain(new_locals.into_iter()),
|
||||
body_expr,
|
||||
);
|
||||
}
|
||||
|
|
30
src/ir.rs
30
src/ir.rs
|
@ -99,14 +99,20 @@ impl FuncDecl {
|
|||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct FunctionBody {
|
||||
/// How many parameters the function has. (Their types are the
|
||||
/// first `n_params` values in `locals`.)
|
||||
pub n_params: usize,
|
||||
/// Return types of the function.
|
||||
pub rets: Vec<Type>,
|
||||
/// Local types, *including* args.
|
||||
pub locals: Vec<Type>,
|
||||
/// Block bodies, indexed by `BlockId`.
|
||||
pub blocks: Vec<Block>,
|
||||
/// Value definitions, indexed by `Value`.
|
||||
pub values: Vec<ValueDef>,
|
||||
/// A single value can have multiple types if multi-value (e.g. a
|
||||
/// call).
|
||||
pub types: Vec</* Value, */ Vec<Type>>,
|
||||
/// Types, indexed by `Value`. A single value can have multiple
|
||||
/// types if multi-value (e.g. a call).
|
||||
pub types: Vec<Vec<Type>>,
|
||||
}
|
||||
|
||||
impl FunctionBody {
|
||||
|
@ -524,13 +530,25 @@ impl<'a> Module<'a> {
|
|||
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);
|
||||
let (new_locals, binaryen_expr) =
|
||||
backend::lower::generate_body(body, &mut binaryen_module);
|
||||
backend::lower::create_new_func(
|
||||
self,
|
||||
sig,
|
||||
body,
|
||||
&mut binaryen_module,
|
||||
binaryen_expr,
|
||||
new_locals,
|
||||
);
|
||||
}
|
||||
for &func in &self.dirty_funcs {
|
||||
if let Some(body) = self.func(func).body() {
|
||||
let mut binaryen_func = binaryen_module.func(func);
|
||||
let binaryen_expr = backend::lower::generate_body(body, &mut binaryen_module);
|
||||
let (new_locals, binaryen_expr) =
|
||||
backend::lower::generate_body(body, &mut binaryen_module);
|
||||
for ty in new_locals {
|
||||
binaryen_func.add_local(ty);
|
||||
}
|
||||
binaryen_func.set_body(binaryen_expr);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue