Fix "already-compiled function" functionality: avoid mismatch in whether length field is included between CodeSection::raw() and function().

This commit is contained in:
Chris Fallin 2023-04-13 19:59:38 -07:00
parent c70bfa20d9
commit 73d8789242
3 changed files with 24 additions and 15 deletions

View file

@ -48,7 +48,7 @@ impl<'a> WasmFuncBackend<'a> {
}) })
} }
pub fn compile(&self) -> Result<Vec<u8>> { pub fn compile(&self) -> Result<wasm_encoder::Function> {
let mut func = wasm_encoder::Function::new( let mut func = wasm_encoder::Function::new(
self.locals self.locals
.locals .locals
@ -76,12 +76,7 @@ impl<'a> WasmFuncBackend<'a> {
log::debug!("Compiled to:\n{:?}\n", func); log::debug!("Compiled to:\n{:?}\n", func);
let mut bytes = vec![]; Ok(func)
{
use wasm_encoder::Encode;
func.encode(&mut bytes);
}
Ok(bytes)
} }
fn lower_block(&self, block: &WasmBlock<'_>, func: &mut wasm_encoder::Function) { fn lower_block(&self, block: &WasmBlock<'_>, func: &mut wasm_encoder::Function) {
@ -703,6 +698,11 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<Vec<u8>> {
let mut code = wasm_encoder::CodeSection::new(); let mut code = wasm_encoder::CodeSection::new();
enum FuncOrRawBytes<'a> {
Raw(&'a [u8]),
Func(Cow<'a, wasm_encoder::Function>),
}
let bodies = module let bodies = module
.funcs .funcs
.entries() .entries()
@ -713,14 +713,16 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<Vec<u8>> {
match func_decl { match func_decl {
FuncDecl::Lazy(_, _name, reader) => { FuncDecl::Lazy(_, _name, reader) => {
let data = &module.orig_bytes[reader.range()]; let data = &module.orig_bytes[reader.range()];
Ok(Cow::Borrowed(data)) Ok(FuncOrRawBytes::Raw(data))
}
FuncDecl::Compiled(_, _name, encoder) => {
Ok(FuncOrRawBytes::Func(Cow::Borrowed(encoder)))
} }
FuncDecl::Compiled(_, _name, bytes) => Ok(Cow::Borrowed(&bytes[..])),
FuncDecl::Body(_, name, body) => { FuncDecl::Body(_, name, body) => {
log::debug!("Compiling {} \"{}\"", func, name); log::debug!("Compiling {} \"{}\"", func, name);
WasmFuncBackend::new(body)? WasmFuncBackend::new(body)?
.compile() .compile()
.map(|bytes| Cow::Owned(bytes)) .map(|func| FuncOrRawBytes::Func(Cow::Owned(func)))
} }
FuncDecl::Import(_, _) => unreachable!("Should have skipped imports"), FuncDecl::Import(_, _) => unreachable!("Should have skipped imports"),
FuncDecl::None => panic!("FuncDecl::None at compilation time"), FuncDecl::None => panic!("FuncDecl::None at compilation time"),
@ -729,7 +731,14 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<Vec<u8>> {
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
for body in bodies { for body in bodies {
code.raw(&body[..]); match body {
FuncOrRawBytes::Raw(bytes) => {
code.raw(bytes);
}
FuncOrRawBytes::Func(func) => {
code.function(&*func);
}
}
} }
into_mod.section(&code); into_mod.section(&code);

View file

@ -252,7 +252,7 @@ impl<'a> Display for ModuleDisplay<'a> {
)?; )?;
writeln!(f, " # raw bytes (length {})", reader.range().len())?; writeln!(f, " # raw bytes (length {})", reader.range().len())?;
} }
FuncDecl::Compiled(sig, name, bytes) => { FuncDecl::Compiled(sig, name, _) => {
writeln!( writeln!(
f, f,
" {} \"{}\": {} = # {}", " {} \"{}\": {} = # {}",
@ -261,7 +261,7 @@ impl<'a> Display for ModuleDisplay<'a> {
sig, sig,
sig_strs.get(&sig).unwrap() sig_strs.get(&sig).unwrap()
)?; )?;
writeln!(f, " # already compiled (length {})", bytes.len())?; writeln!(f, " # already compiled")?;
} }
FuncDecl::Import(sig, name) => { FuncDecl::Import(sig, name) => {
writeln!( writeln!(

View file

@ -18,7 +18,7 @@ pub enum FuncDecl<'a> {
/// 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 compiled function body (was IR, has been collapsed back to bytecode). /// A compiled function body (was IR, has been collapsed back to bytecode).
Compiled(Signature, String, Vec<u8>), Compiled(Signature, String, wasm_encoder::Function),
/// A placeholder. /// A placeholder.
#[default] #[default]
None, None,
@ -436,7 +436,7 @@ impl FunctionBody {
Ok(()) Ok(())
} }
pub fn compile(&self) -> Result<Vec<u8>> { pub fn compile(&self) -> Result<wasm_encoder::Function> {
let backend = WasmFuncBackend::new(self)?; let backend = WasmFuncBackend::new(self)?;
backend.compile() backend.compile()
} }