Tweaks to API around function bodie.

This commit is contained in:
Chris Fallin 2023-02-28 16:31:53 -08:00
parent 2713240bd0
commit 1c0b2964af
5 changed files with 20 additions and 30 deletions

View file

@ -587,8 +587,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<Vec<u8>> {
match func_decl { match func_decl {
FuncDecl::Import(_, _) => anyhow::bail!("Import comes after func with body: {}", func), FuncDecl::Import(_, _) => anyhow::bail!("Import comes after func with body: {}", func),
FuncDecl::Lazy(sig, _, _) FuncDecl::Lazy(sig, _, _)
| FuncDecl::Body(sig, _, _) | FuncDecl::Body(sig, _, _) => {
| FuncDecl::Expanded(sig, _, _, _) => {
funcs.function(sig.index() as u32); funcs.function(sig.index() as u32);
} }
FuncDecl::None => panic!("FuncDecl::None at compilation time"), FuncDecl::None => panic!("FuncDecl::None at compilation time"),
@ -710,10 +709,6 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<Vec<u8>> {
let data = &module.orig_bytes[reader.range()]; let data = &module.orig_bytes[reader.range()];
Ok(FuncOrRawBytes::Raw(data)) Ok(FuncOrRawBytes::Raw(data))
} }
FuncDecl::Expanded(_, _name, range, _) => {
let data = &module.orig_bytes[range.clone()];
Ok(FuncOrRawBytes::Raw(data))
}
FuncDecl::Body(_, name, body) => { FuncDecl::Body(_, name, body) => {
log::debug!("Compiling {} \"{}\"", func, name); log::debug!("Compiling {} \"{}\"", func, name);
WasmFuncBackend::new(body)? WasmFuncBackend::new(body)?

View file

@ -95,7 +95,7 @@ impl InterpContext {
assert_eq!(import.kind, ImportKind::Func(func)); assert_eq!(import.kind, ImportKind::Func(func));
return self.call_import(&import.name[..], args); return self.call_import(&import.name[..], args);
} }
FuncDecl::Body(_, _, body) | FuncDecl::Expanded(_, _, _, body) => body, FuncDecl::Body(_, _, body) => body,
FuncDecl::None => panic!("FuncDecl::None in call()"), FuncDecl::None => panic!("FuncDecl::None in call()"),
}; };

View file

@ -230,7 +230,7 @@ impl<'a> Display for ModuleDisplay<'a> {
} }
for (func, func_decl) in self.0.funcs.entries() { for (func, func_decl) in self.0.funcs.entries() {
match func_decl { match func_decl {
FuncDecl::Body(sig, name, body) | FuncDecl::Expanded(sig, name, _, body) => { FuncDecl::Body(sig, name, body) => {
writeln!( writeln!(
f, f,
" {} \"{}\": {} = # {}", " {} \"{}\": {} = # {}",

View file

@ -4,7 +4,6 @@ use crate::entity::{EntityRef, EntityVec, PerEntity};
use crate::frontend::parse_body; use crate::frontend::parse_body;
use crate::ir::SourceLoc; use crate::ir::SourceLoc;
use anyhow::Result; use anyhow::Result;
use std::ops::Range;
/// A declaration of a function: there is one `FuncDecl` per `Func` /// A declaration of a function: there is one `FuncDecl` per `Func`
/// index. /// index.
@ -14,10 +13,6 @@ pub enum FuncDecl<'a> {
Import(Signature, String), Import(Signature, String),
/// An un-expanded body that can be lazily expanded if needed. /// An un-expanded body that can be lazily expanded if needed.
Lazy(Signature, String, wasmparser::FunctionBody<'a>), Lazy(Signature, String, wasmparser::FunctionBody<'a>),
/// Expanded body, but still "clean" (unchanged); range in
/// original Wasm lets us pass it straight through when converting
/// back to a Wasm module.
Expanded(Signature, String, Range<usize>, FunctionBody),
/// A modified or new function body that requires compilation. /// A modified or new function body that requires compilation.
Body(Signature, String, FunctionBody), Body(Signature, String, FunctionBody),
/// A placeholder. /// A placeholder.
@ -30,7 +25,6 @@ impl<'a> FuncDecl<'a> {
match self { match self {
FuncDecl::Import(sig, ..) => *sig, FuncDecl::Import(sig, ..) => *sig,
FuncDecl::Lazy(sig, ..) => *sig, FuncDecl::Lazy(sig, ..) => *sig,
FuncDecl::Expanded(sig, ..) => *sig,
FuncDecl::Body(sig, ..) => *sig, FuncDecl::Body(sig, ..) => *sig,
FuncDecl::None => panic!("No signature for FuncDecl::None"), FuncDecl::None => panic!("No signature for FuncDecl::None"),
} }
@ -39,9 +33,8 @@ impl<'a> FuncDecl<'a> {
pub fn parse(&mut self, module: &Module) -> Result<()> { pub fn parse(&mut self, module: &Module) -> Result<()> {
match self { match self {
FuncDecl::Lazy(sig, name, body) => { FuncDecl::Lazy(sig, name, body) => {
let range = body.range();
let body = parse_body(module, *sig, body)?; let body = parse_body(module, *sig, body)?;
*self = FuncDecl::Expanded(*sig, name.clone(), range, body); *self = FuncDecl::Body(*sig, name.clone(), body);
Ok(()) Ok(())
} }
_ => Ok(()), _ => Ok(()),
@ -49,7 +42,6 @@ impl<'a> FuncDecl<'a> {
} }
pub fn optimize(&mut self) { pub fn optimize(&mut self) {
self.mark_dirty();
match self { match self {
FuncDecl::Body(_, _, body) => { FuncDecl::Body(_, _, body) => {
body.optimize(); body.optimize();
@ -59,7 +51,6 @@ impl<'a> FuncDecl<'a> {
} }
pub fn convert_to_max_ssa(&mut self) { pub fn convert_to_max_ssa(&mut self) {
self.mark_dirty();
match self { match self {
FuncDecl::Body(_, _, body) => { FuncDecl::Body(_, _, body) => {
body.convert_to_max_ssa(); body.convert_to_max_ssa();
@ -68,23 +59,14 @@ impl<'a> FuncDecl<'a> {
} }
} }
pub fn mark_dirty(&mut self) {
let new = match std::mem::take(self) {
FuncDecl::Expanded(sig, name, _, body) => FuncDecl::Body(sig, name, body),
x => x,
};
*self = new;
}
pub fn body(&self) -> Option<&FunctionBody> { pub fn body(&self) -> Option<&FunctionBody> {
match self { match self {
FuncDecl::Expanded(_, _, _, body) | FuncDecl::Body(_, _, body) => Some(body), FuncDecl::Body(_, _, body) => Some(body),
_ => None, _ => None,
} }
} }
pub fn body_mut(&mut self) -> Option<&mut FunctionBody> { pub fn body_mut(&mut self) -> Option<&mut FunctionBody> {
self.mark_dirty();
match self { match self {
FuncDecl::Body(_, _, body) => Some(body), FuncDecl::Body(_, _, body) => Some(body),
_ => None, _ => None,
@ -95,7 +77,6 @@ impl<'a> FuncDecl<'a> {
match self { match self {
FuncDecl::Body(_, name, _) FuncDecl::Body(_, name, _)
| FuncDecl::Lazy(_, name, _) | FuncDecl::Lazy(_, name, _)
| FuncDecl::Expanded(_, name, _, _)
| FuncDecl::Import(_, name) => &name[..], | FuncDecl::Import(_, name) => &name[..],
FuncDecl::None => panic!("No name for FuncDecl::None"), FuncDecl::None => panic!("No name for FuncDecl::None"),
} }
@ -105,7 +86,6 @@ impl<'a> FuncDecl<'a> {
match self { match self {
FuncDecl::Body(_, name, _) FuncDecl::Body(_, name, _)
| FuncDecl::Lazy(_, name, _) | FuncDecl::Lazy(_, name, _)
| FuncDecl::Expanded(_, name, _, _)
| FuncDecl::Import(_, name) => *name = new_name.to_owned(), | FuncDecl::Import(_, name) => *name = new_name.to_owned(),
FuncDecl::None => panic!("No name for FuncDecl::None"), FuncDecl::None => panic!("No name for FuncDecl::None"),
} }

View file

@ -187,6 +187,21 @@ impl<'a> Module<'a> {
Ok(&mut self.funcs[id]) Ok(&mut self.funcs[id])
} }
pub fn clone_and_expand_body(&self, id: Func) -> Result<FunctionBody> {
let mut body = self.funcs[id].clone();
body.parse(self)?;
Ok(match body {
FuncDecl::Body(_, _, body) => body,
_ => unreachable!(),
})
}
pub fn replace_body(&mut self, id: Func, body: FunctionBody) {
let sig = self.funcs[id].sig();
let name = self.funcs[id].name().to_owned();
self.funcs[id] = FuncDecl::Body(sig, name, body);
}
pub fn expand_all_funcs(&mut self) -> Result<()> { pub fn expand_all_funcs(&mut self) -> Result<()> {
for id in 0..self.funcs.len() { for id in 0..self.funcs.len() {
let id = Func::new(id); let id = Func::new(id);