This commit is contained in:
Chris Fallin 2022-11-20 13:54:27 -08:00
parent c2db0ad4b9
commit 2fc5440fa3
No known key found for this signature in database
GPG key ID: 31649E4FE65EB465
3 changed files with 54 additions and 9 deletions

View file

@ -371,6 +371,10 @@ impl Expression {
Expression(module.0, expr) Expression(module.0, expr)
} }
pub fn expr_drop(module: &Module, value: Expression) -> Expression {
Expression(module.0, unsafe { BinaryenDrop(module.0, value.1) })
}
pub fn ret(module: &Module, values: &[Expression]) -> Expression { pub fn ret(module: &Module, values: &[Expression]) -> Expression {
let expr = if values.len() == 0 { let expr = if values.len() == 0 {
unsafe { BinaryenReturn(module.0, std::ptr::null()) } unsafe { BinaryenReturn(module.0, std::ptr::null()) }
@ -713,6 +717,7 @@ extern "C" {
n_operands: BinaryenIndex, n_operands: BinaryenIndex,
) -> BinaryenExpression; ) -> BinaryenExpression;
fn BinaryenReturn(module: BinaryenModule, expr: BinaryenExpression) -> BinaryenExpression; fn BinaryenReturn(module: BinaryenModule, expr: BinaryenExpression) -> BinaryenExpression;
fn BinaryenDrop(module: BinaryenModule, expr: BinaryenExpression) -> BinaryenExpression;
fn BinaryenAddFunc( fn BinaryenAddFunc(
module: BinaryenModule, module: BinaryenModule,

View file

@ -12,7 +12,7 @@ pub(crate) fn generate_body(
body: &FunctionBody, body: &FunctionBody,
into_mod: &mut binaryen::Module, into_mod: &mut binaryen::Module,
) -> (Vec<Type>, binaryen::Expression) { ) -> (Vec<Type>, binaryen::Expression) {
let mut ctx = ElabCtx::new(body, into_mod); let mut ctx = ElabCtx::new(body);
// For each block, generate an expr. // For each block, generate an expr.
let mut block_exprs: BTreeMap<Block, binaryen::Expression> = BTreeMap::default(); let mut block_exprs: BTreeMap<Block, binaryen::Expression> = BTreeMap::default();
@ -146,8 +146,35 @@ struct ElabCtx<'a> {
} }
impl<'a> ElabCtx<'a> { impl<'a> ElabCtx<'a> {
fn new(body: &'a FunctionBody, into_mod: &mut binaryen::Module) -> ElabCtx<'a> { fn new(body: &'a FunctionBody) -> ElabCtx<'a> {
todo!() let mut this = ElabCtx {
body,
op_result_locals: FxHashMap::default(),
block_param_locals: FxHashMap::default(),
block_param_next_locals: FxHashMap::default(),
new_locals: vec![],
};
// Create operator result locals.
for (value, def) in body.values.entries() {
for (i, &ty) in def.tys().iter().enumerate() {
let new_local = this.new_local(ty);
this.op_result_locals.insert((value, i), new_local);
}
}
// Create blockparam cur-value and next-value locals.
for (block, def) in body.blocks.entries() {
for (param, &(ty, _)) in def.params.iter().enumerate() {
let cur_value = this.new_local(ty);
let next_value = this.new_local(ty);
this.block_param_locals.insert((block, param), cur_value);
this.block_param_next_locals
.insert((block, param), next_value);
}
}
this
} }
fn elaborate_value( fn elaborate_value(
@ -155,7 +182,6 @@ impl<'a> ElabCtx<'a> {
into_mod: &binaryen::Module, into_mod: &binaryen::Module,
value: Value, value: Value,
) -> Option<binaryen::Expression> { ) -> Option<binaryen::Expression> {
/*
let value = self.body.resolve_alias(value); let value = self.body.resolve_alias(value);
match &self.body.values[value] { match &self.body.values[value] {
@ -164,7 +190,13 @@ impl<'a> ElabCtx<'a> {
let args = args.iter().map(|&arg| self.get_val_local(arg)); let args = args.iter().map(|&arg| self.get_val_local(arg));
// Create `get_local` expressions for each arg. // Create `get_local` expressions for each arg.
let binaryen_args = args let binaryen_args = args
.map(|arg_local| into_mod.expr_local_get(arg_local, self.local_ty(arg_local))) .map(|arg_local| {
binaryen::Expression::local_get(
into_mod,
arg_local,
self.local_ty(arg_local),
)
})
.collect::<Vec<_>>(); .collect::<Vec<_>>();
// Create operator. // Create operator.
let expr = self.create_binaryen_op(op, binaryen_args, tys); let expr = self.create_binaryen_op(op, binaryen_args, tys);
@ -172,19 +204,17 @@ impl<'a> ElabCtx<'a> {
// Set local(s) as appropriate. // Set local(s) as appropriate.
if tys.len() == 0 { if tys.len() == 0 {
// Nothing. Create a `drop` expr that wraps the actual operator. // Nothing. Create a `drop` expr that wraps the actual operator.
Some(into_mod.expr_drop(expr)) Some(binaryen::Expression::expr_drop(into_mod, expr))
} else if tys.len() == 1 { } else if tys.len() == 1 {
// Set value directly. // Set value directly.
let local = self.get_val_local(value); let local = self.get_val_local(value);
Some(into_mod.expr_local_set(local, expr)) Some(binaryen::Expression::local_set(into_mod, local, expr))
} else { } else {
todo!("support multivalue") todo!("support multivalue")
} }
} }
_ => None, _ => None,
} }
*/
todo!()
} }
fn get_val_local(&self, value: Value) -> Local { fn get_val_local(&self, value: Value) -> Local {

View file

@ -24,6 +24,16 @@ impl ValueDef {
} }
} }
pub fn tys(&self) -> &[Type] {
match self {
&ValueDef::Operator(_, _, ref tys) => &tys[..],
&ValueDef::BlockParam(_, _, ref ty)
| &ValueDef::PickOutput(_, _, ref ty)
| &ValueDef::Placeholder(ref ty) => std::slice::from_ref(ty),
_ => &[],
}
}
pub fn visit_uses<F: FnMut(Value)>(&self, mut f: F) { pub fn visit_uses<F: FnMut(Value)>(&self, mut f: F) {
match self { match self {
&ValueDef::BlockParam { .. } => {} &ValueDef::BlockParam { .. } => {}