mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-13 04:51:23 +00:00
Correctly hook up the anyref table initialization
This functionality got lost in recent refactorings for WebIDL bindings unfortunately, so this commit touches things up to ensure that the anyref table initialization in anyref-mode is hooked up correctly, even when tests are enabled. This invovled moving injection of the start function to the webidl processing pass and ensuring its intrinsic is registered in the internal maps of wasm-bindgen.
This commit is contained in:
@ -254,10 +254,6 @@ impl Transform<'_> {
|
||||
// functions and make sure everything is still hooked up right.
|
||||
self.rewrite_calls(module);
|
||||
|
||||
// Inject initialization routine to set up default slots in the table
|
||||
// (things like null/undefined/true/false)
|
||||
self.inject_initialization(module);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -669,31 +665,4 @@ impl Transform<'_> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the `start` function for this module calls the
|
||||
// `__wbindgen_init_anyref_table` function. This'll ensure that all
|
||||
// instances of this module have the initial slots of the anyref table
|
||||
// initialized correctly.
|
||||
fn inject_initialization(&mut self, module: &mut Module) {
|
||||
let ty = module.types.add(&[], &[]);
|
||||
let (import, _) = module.add_import_func(
|
||||
"__wbindgen_placeholder__",
|
||||
"__wbindgen_init_anyref_table",
|
||||
ty,
|
||||
);
|
||||
|
||||
let prev_start = match module.start {
|
||||
Some(f) => f,
|
||||
None => {
|
||||
module.start = Some(import);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut builder = walrus::FunctionBuilder::new();
|
||||
let call_init = builder.call(import, Box::new([]));
|
||||
let call_prev = builder.call(prev_start, Box::new([]));
|
||||
let new_start = builder.finish(ty, Vec::new(), vec![call_init, call_prev], module);
|
||||
module.start = Some(new_start);
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ intrinsics! {
|
||||
#[symbol = "__wbindgen_anyref_heap_live_count"]
|
||||
#[signature = fn() -> I32]
|
||||
AnyrefHeapLiveCount,
|
||||
#[symbol = "__wbindgen_init_nyref_table"]
|
||||
#[symbol = "__wbindgen_init_anyref_table"]
|
||||
#[signature = fn() -> Unit]
|
||||
InitAnyrefTable,
|
||||
}
|
||||
|
@ -194,10 +194,7 @@ impl<'a> Context<'a> {
|
||||
// up we always remove the `start` function if one is present. The JS
|
||||
// bindings glue then manually calls the start function (if it was
|
||||
// previously present).
|
||||
let mut needs_manual_start = false;
|
||||
if self.config.emit_start {
|
||||
needs_manual_start = self.unstart_start_function();
|
||||
}
|
||||
let needs_manual_start = self.unstart_start_function();
|
||||
|
||||
// After all we've done, especially
|
||||
// `unexport_unused_internal_exports()`, we probably have a bunch of
|
||||
@ -517,7 +514,10 @@ impl<'a> Context<'a> {
|
||||
for (i, extra) in extra_modules.iter().enumerate() {
|
||||
let imports = match &mut imports {
|
||||
Some(list) => list,
|
||||
None => bail!("cannot import from modules (`{}`) with `--no-modules`", extra),
|
||||
None => bail!(
|
||||
"cannot import from modules (`{}`) with `--no-modules`",
|
||||
extra
|
||||
),
|
||||
};
|
||||
imports.push_str(&format!("import * as __wbg_star{} from '{}';\n", i, extra));
|
||||
imports_init.push_str(&format!("imports['{}'] = __wbg_star{};\n", extra, i));
|
||||
|
@ -313,7 +313,7 @@ impl Bindgen {
|
||||
// the webidl bindings proposal) as well as an auxiliary section for all
|
||||
// sorts of miscellaneous information and features #[wasm_bindgen]
|
||||
// supports that aren't covered by WebIDL bindings.
|
||||
webidl::process(&mut module)?;
|
||||
webidl::process(&mut module, self.anyref, self.emit_start)?;
|
||||
|
||||
// Now that we've got type information from the webidl processing pass,
|
||||
// touch up the output of rustc to insert anyref shims where necessary.
|
||||
@ -324,12 +324,6 @@ impl Bindgen {
|
||||
anyref::process(&mut module)?;
|
||||
}
|
||||
|
||||
// If we're in a testing mode then remove the start function since we
|
||||
// shouldn't execute it.
|
||||
if !self.emit_start {
|
||||
module.start = None;
|
||||
}
|
||||
|
||||
let aux = module
|
||||
.customs
|
||||
.delete_typed::<webidl::WasmBindgenAux>()
|
||||
|
@ -473,10 +473,14 @@ struct Context<'a> {
|
||||
vendor_prefixes: HashMap<String, Vec<String>>,
|
||||
unique_crate_identifier: &'a str,
|
||||
descriptors: HashMap<String, Descriptor>,
|
||||
anyref_enabled: bool,
|
||||
support_start: bool,
|
||||
}
|
||||
|
||||
pub fn process(
|
||||
module: &mut Module,
|
||||
anyref_enabled: bool,
|
||||
support_start: bool,
|
||||
) -> Result<(NonstandardWebidlSectionId, WasmBindgenAuxId), Error> {
|
||||
let mut storage = Vec::new();
|
||||
let programs = extract_programs(module, &mut storage)?;
|
||||
@ -491,6 +495,8 @@ pub fn process(
|
||||
unique_crate_identifier: "",
|
||||
module,
|
||||
start_found: false,
|
||||
anyref_enabled,
|
||||
support_start,
|
||||
};
|
||||
cx.init()?;
|
||||
|
||||
@ -532,18 +538,11 @@ impl<'a> Context<'a> {
|
||||
}
|
||||
}
|
||||
for (id, intrinsic) in intrinsics {
|
||||
bindings::register_import(
|
||||
self.module,
|
||||
&mut self.bindings,
|
||||
id,
|
||||
intrinsic.binding(),
|
||||
ast::WebidlFunctionKind::Static,
|
||||
)?;
|
||||
self.aux
|
||||
.import_map
|
||||
.insert(id, AuxImport::Intrinsic(intrinsic));
|
||||
self.bind_intrinsic(id, intrinsic)?;
|
||||
}
|
||||
|
||||
self.inject_anyref_initialization()?;
|
||||
|
||||
if let Some(custom) = self
|
||||
.module
|
||||
.customs
|
||||
@ -612,6 +611,48 @@ impl<'a> Context<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Ensure that the `start` function for this module calls the
|
||||
// `__wbindgen_init_anyref_table` function. This'll ensure that all
|
||||
// instances of this module have the initial slots of the anyref table
|
||||
// initialized correctly.
|
||||
fn inject_anyref_initialization(&mut self) -> Result<(), Error> {
|
||||
if !self.anyref_enabled {
|
||||
return Ok(());
|
||||
}
|
||||
let ty = self.module.types.add(&[], &[]);
|
||||
let (import, import_id) = self.module.add_import_func(
|
||||
PLACEHOLDER_MODULE,
|
||||
"__wbindgen_init_anyref_table",
|
||||
ty,
|
||||
);
|
||||
|
||||
self.module.start = Some(match self.module.start {
|
||||
Some(prev_start) => {
|
||||
let mut builder = walrus::FunctionBuilder::new();
|
||||
let call_init = builder.call(import, Box::new([]));
|
||||
let call_prev = builder.call(prev_start, Box::new([]));
|
||||
builder.finish(ty, Vec::new(), vec![call_init, call_prev], self.module)
|
||||
}
|
||||
None => import,
|
||||
});
|
||||
self.bind_intrinsic(import_id, Intrinsic::InitAnyrefTable)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn bind_intrinsic(&mut self, id: ImportId, intrinsic: Intrinsic) -> Result<(), Error> {
|
||||
bindings::register_import(
|
||||
self.module,
|
||||
&mut self.bindings,
|
||||
id,
|
||||
intrinsic.binding(),
|
||||
ast::WebidlFunctionKind::Static,
|
||||
)?;
|
||||
self.aux
|
||||
.import_map
|
||||
.insert(id, AuxImport::Intrinsic(intrinsic));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn program(&mut self, program: decode::Program<'a>) -> Result<(), Error> {
|
||||
self.unique_crate_identifier = program.unique_crate_identifier;
|
||||
let decode::Program {
|
||||
@ -752,6 +793,11 @@ impl<'a> Context<'a> {
|
||||
}
|
||||
self.start_found = true;
|
||||
|
||||
// Skip this when we're generating tests
|
||||
if !self.support_start {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let prev_start = match self.module.start {
|
||||
Some(f) => f,
|
||||
None => {
|
||||
|
Reference in New Issue
Block a user