mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-05-02 09:02:16 +00:00
This commit adds a new attribute to `#[wasm_bindgen]`: `start`. The `start` attribute can be used to indicate that a function should be executed when the module is loaded, configuring the `start` function of the wasm executable. While this doesn't necessarily literally configure the `start` section, it does its best! Only one crate in a crate graph may indicate `#[wasm_bindgen(start)]`, so it's not recommended to be used in libraries but only end-user applications. Currently this still must be used with the `crate-type = ["cdylib"]` annotation in `Cargo.toml`. The implementation here is somewhat tricky because of the circular dependency between our generated JS and the wasm file that we emit. This circular dependency makes running initialization routines (like the `start` shim) particularly fraught with complications because one may need to run before the other but bundlers may not necessarily respect it. Workarounds have been implemented for various emission strategies, for example calling the start function directly after exports are wired up with `--no-modules` and otherwise working around what appears to be a Webpack bug with initializers running in a different order than we'd like. In any case, this in theory doesn't show up to the end user! Closes #74
105 lines
3.0 KiB
Rust
105 lines
3.0 KiB
Rust
use std::mem;
|
|
|
|
use parity_wasm::elements::*;
|
|
|
|
pub struct Remap<F>(pub F);
|
|
|
|
impl<F> Remap<F> where F: FnMut(u32) -> u32 {
|
|
pub fn remap_module(&mut self, module: &mut Module) {
|
|
for section in module.sections_mut() {
|
|
match section {
|
|
Section::Export(e) => self.remap_export_section(e),
|
|
Section::Element(e) => self.remap_element_section(e),
|
|
Section::Code(e) => self.remap_code_section(e),
|
|
Section::Start(i) => {
|
|
self.remap_idx(i);
|
|
}
|
|
Section::Name(n) => self.remap_name_section(n),
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn remap_export_section(&mut self, section: &mut ExportSection) {
|
|
for entry in section.entries_mut() {
|
|
self.remap_export_entry(entry);
|
|
}
|
|
}
|
|
|
|
fn remap_export_entry(&mut self, entry: &mut ExportEntry) {
|
|
match entry.internal_mut() {
|
|
Internal::Function(i) => {
|
|
self.remap_idx(i);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn remap_element_section(&mut self, section: &mut ElementSection) {
|
|
for entry in section.entries_mut() {
|
|
self.remap_element_entry(entry);
|
|
}
|
|
}
|
|
|
|
fn remap_element_entry(&mut self, entry: &mut ElementSegment) {
|
|
for member in entry.members_mut() {
|
|
self.remap_idx(member);
|
|
}
|
|
}
|
|
|
|
fn remap_code_section(&mut self, section: &mut CodeSection) {
|
|
for body in section.bodies_mut() {
|
|
self.remap_func_body(body);
|
|
}
|
|
}
|
|
|
|
fn remap_func_body(&mut self, body: &mut FuncBody) {
|
|
self.remap_instructions(body.code_mut());
|
|
}
|
|
|
|
fn remap_instructions(&mut self, code: &mut Instructions) {
|
|
for instr in code.elements_mut() {
|
|
self.remap_instruction(instr);
|
|
}
|
|
}
|
|
|
|
fn remap_instruction(&mut self, instr: &mut Instruction) {
|
|
match instr {
|
|
Instruction::Call(i) => {
|
|
self.remap_idx(i);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn remap_name_section(&mut self, names: &mut NameSection) {
|
|
match names {
|
|
NameSection::Function(f) => self.remap_function_name_section(f),
|
|
NameSection::Local(f) => self.remap_local_name_section(f),
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn remap_function_name_section(&mut self, names: &mut FunctionNameSection) {
|
|
let map = names.names_mut();
|
|
let new = IndexMap::with_capacity(map.len());
|
|
for (mut idx, name) in mem::replace(map, new) {
|
|
self.remap_idx(&mut idx);
|
|
map.insert(idx, name);
|
|
}
|
|
}
|
|
|
|
fn remap_local_name_section(&mut self, names: &mut LocalNameSection) {
|
|
let map = names.local_names_mut();
|
|
let new = IndexMap::with_capacity(map.len());
|
|
for (mut idx, name) in mem::replace(map, new) {
|
|
self.remap_idx(&mut idx);
|
|
map.insert(idx, name);
|
|
}
|
|
}
|
|
|
|
fn remap_idx(&mut self, idx: &mut u32) {
|
|
*idx = (self.0)(*idx);
|
|
}
|
|
}
|