Process declared element segments for "possibly exported funcs" (#2851)
Now that we're using "possibly exported" as an impactful decision for codegen (which trampolines to generate and which ABI a function has) it's important that we calculate this property of a wasm function correctly! Previously Wasmtime forgot to processed "declared" elements in apart from active/passive element segments, but this updates Wasmtime to ensure that these entries are processed and all the functions contained within are flagged as "possibly exported". Closes #2850
This commit is contained in:
@@ -948,6 +948,13 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
|
|||||||
elements: Box<[FuncIndex]>,
|
elements: Box<[FuncIndex]>,
|
||||||
) -> WasmResult<()>;
|
) -> WasmResult<()>;
|
||||||
|
|
||||||
|
/// Indicates that a declarative element segment was seen in the wasm
|
||||||
|
/// module.
|
||||||
|
fn declare_elements(&mut self, elements: Box<[FuncIndex]>) -> WasmResult<()> {
|
||||||
|
drop(elements);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Provides the number of passive data segments up front.
|
/// Provides the number of passive data segments up front.
|
||||||
///
|
///
|
||||||
/// By default this does nothing, but implementations may use this to
|
/// By default this does nothing, but implementations may use this to
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ pub fn parse_element_section<'data>(
|
|||||||
environ.declare_passive_element(index, segments)?;
|
environ.declare_passive_element(index, segments)?;
|
||||||
}
|
}
|
||||||
ElementKind::Declared => {
|
ElementKind::Declared => {
|
||||||
// Nothing to do here.
|
environ.declare_elements(segments)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -746,6 +746,13 @@ impl<'data> cranelift_wasm::ModuleEnvironment<'data> for ModuleEnvironment<'data
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn declare_elements(&mut self, segments: Box<[FuncIndex]>) -> WasmResult<()> {
|
||||||
|
for element in segments.iter() {
|
||||||
|
self.flag_func_possibly_exported(*element);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn reserve_function_bodies(&mut self, _count: u32, offset: u64) {
|
fn reserve_function_bodies(&mut self, _count: u32, offset: u64) {
|
||||||
self.result.debuginfo.wasm_file.code_section_offset = offset;
|
self.result.debuginfo.wasm_file.code_section_offset = offset;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -774,3 +774,30 @@ fn wrap_multiple_results() -> anyhow::Result<()> {
|
|||||||
f64 "f64" F64 f64::from_bits(a),
|
f64 "f64" F64 f64::from_bits(a),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn trampoline_for_declared_elem() -> anyhow::Result<()> {
|
||||||
|
let engine = Engine::default();
|
||||||
|
|
||||||
|
let module = Module::new(
|
||||||
|
&engine,
|
||||||
|
r#"
|
||||||
|
(module
|
||||||
|
(elem declare func $f)
|
||||||
|
(func $f)
|
||||||
|
(func (export "g") (result funcref)
|
||||||
|
(ref.func $f)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let store = Store::new(&engine);
|
||||||
|
let instance = Instance::new(&store, &module, &[])?;
|
||||||
|
|
||||||
|
let g = instance.get_typed_func::<(), Option<Func>>("g")?;
|
||||||
|
|
||||||
|
let func = g.call(())?;
|
||||||
|
func.unwrap().call(&[])?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user