WIP.
This commit is contained in:
parent
e6024c4ffd
commit
bc245b581a
|
@ -189,7 +189,8 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
|||
| Operator::Call { .. }
|
||||
| Operator::LocalGet { .. }
|
||||
| Operator::LocalSet { .. }
|
||||
| Operator::LocalTee { .. } => self.emit(op.clone())?,
|
||||
| Operator::LocalTee { .. }
|
||||
| Operator::I32Eqz => self.emit(op.clone())?,
|
||||
|
||||
Operator::End => match self.ctrl_stack.pop() {
|
||||
None => {
|
||||
|
@ -409,7 +410,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
|||
|
||||
fn emit_branch(&mut self, target: BlockId, args: &[ValueId]) {
|
||||
if let Some(block) = self.cur_block {
|
||||
let args = args.iter().map(|&val| Operand::Value(val)).collect();
|
||||
let args = args.iter().map(|&val| Operand::value(val)).collect();
|
||||
let target = BlockTarget {
|
||||
block: target,
|
||||
args,
|
||||
|
@ -429,14 +430,14 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
|||
if let Some(block) = self.cur_block {
|
||||
let if_true_args = if_true_args
|
||||
.iter()
|
||||
.map(|&val| Operand::Value(val))
|
||||
.map(|&val| Operand::value(val))
|
||||
.collect();
|
||||
let if_false_args = if_false_args
|
||||
.iter()
|
||||
.map(|&val| Operand::Value(val))
|
||||
.map(|&val| Operand::value(val))
|
||||
.collect();
|
||||
self.body.blocks[block].terminator = Terminator::CondBr {
|
||||
cond: Operand::Value(cond),
|
||||
cond: Operand::value(cond),
|
||||
if_true: BlockTarget {
|
||||
block: if_true,
|
||||
args: if_true_args,
|
||||
|
@ -457,7 +458,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
|||
args: &[ValueId],
|
||||
) {
|
||||
if let Some(block) = self.cur_block {
|
||||
let args: Vec<Operand<'a>> = args.iter().map(|&arg| Operand::Value(arg)).collect();
|
||||
let args: Vec<Operand<'a>> = args.iter().map(|&arg| Operand::value(arg)).collect();
|
||||
let targets = indexed_targets
|
||||
.iter()
|
||||
.map(|&block| BlockTarget {
|
||||
|
@ -470,7 +471,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
|||
args: args.clone(),
|
||||
};
|
||||
self.body.blocks[block].terminator = Terminator::Select {
|
||||
value: Operand::Value(index),
|
||||
value: Operand::value(index),
|
||||
targets,
|
||||
default,
|
||||
};
|
||||
|
@ -500,7 +501,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
|||
{
|
||||
let stack_top = self.op_stack.pop().unwrap();
|
||||
assert_eq!(self.body.values[stack_top].ty, input);
|
||||
inputs.push(Operand::Value(stack_top));
|
||||
inputs.push(Operand::value(stack_top));
|
||||
}
|
||||
inputs.reverse();
|
||||
|
||||
|
@ -520,6 +521,13 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
|||
outputs,
|
||||
inputs,
|
||||
});
|
||||
} else {
|
||||
let _ = self
|
||||
.op_stack
|
||||
.split_off(op_inputs(self.module, self.my_sig, &self.body.locals[..], &op)?.len());
|
||||
for _ in 0..op_outputs(self.module, &self.body.locals[..], &op)?.len() {
|
||||
self.op_stack.push(NO_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
17
src/ir.rs
17
src/ir.rs
|
@ -8,6 +8,8 @@ pub type BlockId = usize;
|
|||
pub type InstId = usize;
|
||||
pub type ValueId = usize;
|
||||
|
||||
pub const NO_VALUE: ValueId = usize::MAX;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Module<'a> {
|
||||
pub funcs: Vec<FuncDecl<'a>>,
|
||||
|
@ -64,8 +66,23 @@ pub struct Inst<'a> {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Operand<'a> {
|
||||
/// An SSA value.
|
||||
Value(ValueId),
|
||||
/// Tree-ified instructions for Wasm emission.
|
||||
Sub(Box<Inst<'a>>),
|
||||
/// Undef values are produced when code is unreachable and thus
|
||||
/// removed/never executed.
|
||||
Undef,
|
||||
}
|
||||
|
||||
impl<'a> Operand<'a> {
|
||||
pub fn value(value: ValueId) -> Self {
|
||||
if value == NO_VALUE {
|
||||
Operand::Undef
|
||||
} else {
|
||||
Operand::Value(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -24,6 +24,9 @@ pub fn op_inputs(
|
|||
}
|
||||
&Operator::LocalGet { .. } => Ok(vec![]),
|
||||
|
||||
&Operator::I32Eqz => Ok(vec![Type::I32]),
|
||||
&Operator::I32Eq => Ok(vec![Type::I32, Type::I32]),
|
||||
|
||||
_ => bail!("Unknown operator in op_inputs(): {:?}", op),
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +43,8 @@ pub fn op_outputs(module: &Module, my_locals: &[Type], op: &Operator<'_>) -> Res
|
|||
&Operator::LocalSet { .. } | &Operator::LocalTee { .. } => Ok(vec![]),
|
||||
&Operator::LocalGet { local_index } => Ok(vec![my_locals[local_index as usize]]),
|
||||
|
||||
&Operator::I32Eqz | &Operator::I32Eq => Ok(vec![Type::I32]),
|
||||
|
||||
_ => bail!("Unknown operator in op_outputs(): {:?}", op),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue