WIP.
This commit is contained in:
parent
726b4da33d
commit
f92ea9a556
|
@ -1,11 +1,10 @@
|
|||
//! Final Wasm operator sequence production.
|
||||
|
||||
use super::{Locations, SerializedBlockTarget, SerializedBody, SerializedOperator};
|
||||
use crate::{ops::ty_to_valty, FunctionBody};
|
||||
use std::borrow::Cow;
|
||||
use wasm_encoder::BlockType;
|
||||
|
||||
use crate::{ops::ty_to_valty, FunctionBody, Operator};
|
||||
|
||||
use super::{Locations, SerializedBody, SerializedOperator};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Wasm {
|
||||
operators: Vec<wasm_encoder::Instruction<'static>>,
|
||||
|
@ -62,36 +61,96 @@ impl Wasm {
|
|||
self.operators.push(op.clone().into());
|
||||
}
|
||||
SerializedOperator::Br(ref target) => {
|
||||
todo!()
|
||||
self.translate_target(0, target, locations);
|
||||
}
|
||||
SerializedOperator::BrIf {
|
||||
cond,
|
||||
ref if_true,
|
||||
ref if_false,
|
||||
} => {
|
||||
todo!()
|
||||
let loc = *locations.locations.get(&(*cond, 0)).unwrap();
|
||||
self.operators
|
||||
.push(wasm_encoder::Instruction::LocalGet(loc));
|
||||
self.operators.push(wasm_encoder::Instruction::If(
|
||||
wasm_encoder::BlockType::Empty,
|
||||
));
|
||||
self.translate_target(1, if_true, locations);
|
||||
self.operators.push(wasm_encoder::Instruction::Else);
|
||||
self.translate_target(1, if_false, locations);
|
||||
self.operators.push(wasm_encoder::Instruction::End);
|
||||
}
|
||||
SerializedOperator::BrTable {
|
||||
index,
|
||||
ref targets,
|
||||
ref default,
|
||||
} => {
|
||||
todo!()
|
||||
for _ in 0..(targets.len() + 2) {
|
||||
self.operators.push(wasm_encoder::Instruction::Block(
|
||||
wasm_encoder::BlockType::Empty,
|
||||
));
|
||||
}
|
||||
|
||||
let loc = *locations.locations.get(&(*index, 0)).unwrap();
|
||||
self.operators
|
||||
.push(wasm_encoder::Instruction::LocalGet(loc));
|
||||
let br_table_targets = (1..=targets.len()).map(|i| i as u32).collect::<Vec<_>>();
|
||||
self.operators.push(wasm_encoder::Instruction::BrTable(
|
||||
Cow::Owned(br_table_targets),
|
||||
0,
|
||||
));
|
||||
self.operators.push(wasm_encoder::Instruction::End);
|
||||
|
||||
self.translate_target(targets.len() + 1, default, locations);
|
||||
self.operators.push(wasm_encoder::Instruction::End);
|
||||
|
||||
for i in 0..targets.len() {
|
||||
self.translate_target(targets.len() - i, &targets[i], locations);
|
||||
self.operators.push(wasm_encoder::Instruction::End);
|
||||
}
|
||||
}
|
||||
SerializedOperator::Get(v, i) => {
|
||||
todo!()
|
||||
let loc = *locations.locations.get(&(*v, *i)).unwrap();
|
||||
self.operators
|
||||
.push(wasm_encoder::Instruction::LocalGet(loc));
|
||||
}
|
||||
SerializedOperator::Set(v, i) => {
|
||||
todo!()
|
||||
let loc = *locations.locations.get(&(*v, *i)).unwrap();
|
||||
self.operators
|
||||
.push(wasm_encoder::Instruction::LocalSet(loc));
|
||||
}
|
||||
SerializedOperator::Tee(v, i) => {
|
||||
todo!()
|
||||
let loc = *locations.locations.get(&(*v, *i)).unwrap();
|
||||
self.operators
|
||||
.push(wasm_encoder::Instruction::LocalTee(loc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_target(
|
||||
&mut self,
|
||||
extra_blocks: usize,
|
||||
target: &SerializedBlockTarget,
|
||||
locations: &Locations,
|
||||
) {
|
||||
match target {
|
||||
&SerializedBlockTarget::Fallthrough(ref ops) => {
|
||||
for op in ops {
|
||||
self.translate(op, locations);
|
||||
}
|
||||
}
|
||||
&SerializedBlockTarget::Branch(branch, ref ops) => {
|
||||
for op in ops {
|
||||
self.translate(op, locations);
|
||||
}
|
||||
self.operators.push(wasm_encoder::Instruction::Br(
|
||||
(branch + extra_blocks) as u32,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn produce_wasm(f: &FunctionBody, body: &SerializedBody, locations: &Locations) -> Wasm {
|
||||
pub fn produce_func_wasm(f: &FunctionBody, body: &SerializedBody, locations: &Locations) -> Wasm {
|
||||
let mut wasm = Wasm {
|
||||
operators: vec![],
|
||||
locals: vec![],
|
||||
|
|
|
@ -65,10 +65,10 @@ impl<'a> Allocator<'a> {
|
|||
let mut reads = vec![];
|
||||
let mut writes = vec![];
|
||||
op.visit_value_locals(
|
||||
|value, index| {
|
||||
&mut |value, index| {
|
||||
reads.push((value, index));
|
||||
},
|
||||
|value, index| {
|
||||
&mut |value, index| {
|
||||
writes.push((value, index));
|
||||
},
|
||||
);
|
||||
|
@ -77,7 +77,7 @@ impl<'a> Allocator<'a> {
|
|||
let span = match self.spans.get_mut(&(value, index)) {
|
||||
Some(span) => span,
|
||||
None => {
|
||||
panic!("Read before any write to local (v{},{})", value, index);
|
||||
panic!("Read before any write to local ({},{})", value, index);
|
||||
}
|
||||
};
|
||||
span.end = location + 1;
|
||||
|
|
|
@ -72,12 +72,12 @@ pub enum SerializedOperator {
|
|||
impl SerializedOperator {
|
||||
pub fn visit_value_locals<R: FnMut(Value, usize), W: FnMut(Value, usize)>(
|
||||
&self,
|
||||
mut r: R,
|
||||
mut w: W,
|
||||
r: &mut R,
|
||||
w: &mut W,
|
||||
) {
|
||||
match self {
|
||||
&SerializedOperator::Br(ref target) => {
|
||||
target.visit_value_locals(&mut r, &mut w);
|
||||
target.visit_value_locals(r, w);
|
||||
}
|
||||
&SerializedOperator::BrIf {
|
||||
cond,
|
||||
|
@ -85,8 +85,8 @@ impl SerializedOperator {
|
|||
ref if_false,
|
||||
} => {
|
||||
r(cond, 0);
|
||||
if_true.visit_value_locals(&mut r, &mut w);
|
||||
if_false.visit_value_locals(&mut r, &mut w);
|
||||
if_true.visit_value_locals(r, w);
|
||||
if_false.visit_value_locals(r, w);
|
||||
}
|
||||
&SerializedOperator::BrTable {
|
||||
index,
|
||||
|
@ -94,9 +94,9 @@ impl SerializedOperator {
|
|||
ref targets,
|
||||
} => {
|
||||
r(index, 0);
|
||||
default.visit_value_locals(&mut r, &mut w);
|
||||
default.visit_value_locals(r, w);
|
||||
for target in targets {
|
||||
target.visit_value_locals(&mut r, &mut w);
|
||||
target.visit_value_locals(r, w);
|
||||
}
|
||||
}
|
||||
&SerializedOperator::Get(v, i) => {
|
||||
|
@ -128,7 +128,7 @@ impl SerializedBlockTarget {
|
|||
&SerializedBlockTarget::Branch(_, ref ops)
|
||||
| &SerializedBlockTarget::Fallthrough(ref ops) => {
|
||||
for op in ops {
|
||||
op.visit_value_locals(|value, i| r(value, i), |value, i| w(value, i));
|
||||
op.visit_value_locals(r, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use std::collections::hash_map::Entry;
|
||||
|
||||
use crate::{
|
||||
backend::{BlockOrder, LoopNest, SerializedBody, WasmRegion},
|
||||
backend::{produce_func_wasm, BlockOrder, Locations, LoopNest, SerializedBody, WasmRegion},
|
||||
cfg::CFGInfo,
|
||||
frontend, Operator,
|
||||
};
|
||||
|
@ -493,6 +493,10 @@ impl<'a> Module<'a> {
|
|||
let blockorder = BlockOrder::compute(body, &cfg, ®ions);
|
||||
let serialized = SerializedBody::compute(body, &cfg, &blockorder);
|
||||
log::trace!("serialized: {:?}", serialized);
|
||||
let locations = Locations::compute(body, &serialized);
|
||||
log::trace!("locations: {:?}", locations);
|
||||
let func_body = produce_func_wasm(body, &serialized, &locations);
|
||||
log::trace!("body: {:?}", func_body);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue