mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 07:14:46 +00:00
Wasm: Remove code to adjust function indices based on imports
With pre-linking we don't need this anymore. Pure Roc code can't add Imports.
This commit is contained in:
parent
5de9581b62
commit
8e7f398e50
1 changed files with 2 additions and 75 deletions
|
@ -1,9 +1,7 @@
|
||||||
use bumpalo::collections::vec::Vec;
|
use bumpalo::collections::vec::Vec;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
|
||||||
use super::linking::{
|
use super::linking::{LinkingSection, RelocationEntry, RelocationSection};
|
||||||
IndexRelocType, LinkingSection, RelocationEntry, RelocationSection, SymInfo, WasmObjectSymbol,
|
|
||||||
};
|
|
||||||
use super::opcodes::OpCode;
|
use super::opcodes::OpCode;
|
||||||
use super::serialize::{decode_u32_or_panic, SerialBuffer, Serialize};
|
use super::serialize::{decode_u32_or_panic, SerialBuffer, Serialize};
|
||||||
use super::{CodeBuilder, ValueType};
|
use super::{CodeBuilder, ValueType};
|
||||||
|
@ -730,13 +728,6 @@ impl<'a> WasmModule<'a> {
|
||||||
section_index: 0,
|
section_index: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// If we have imports, then references to other functions need to be re-indexed.
|
|
||||||
// Modify exports before serializing them, since we don't have linker data for them
|
|
||||||
let n_imported_fns = self.import.function_count() as u32;
|
|
||||||
if n_imported_fns > 0 {
|
|
||||||
self.finalize_exported_fn_indices(n_imported_fns);
|
|
||||||
}
|
|
||||||
|
|
||||||
counter.serialize_and_count(buffer, &self.types);
|
counter.serialize_and_count(buffer, &self.types);
|
||||||
counter.serialize_and_count(buffer, &self.import);
|
counter.serialize_and_count(buffer, &self.import);
|
||||||
counter.serialize_and_count(buffer, &self.function);
|
counter.serialize_and_count(buffer, &self.function);
|
||||||
|
@ -749,16 +740,9 @@ impl<'a> WasmModule<'a> {
|
||||||
|
|
||||||
// Code section is the only one with relocations so we can stop counting
|
// Code section is the only one with relocations so we can stop counting
|
||||||
let code_section_index = counter.section_index;
|
let code_section_index = counter.section_index;
|
||||||
let code_section_body_index = self
|
self.code
|
||||||
.code
|
|
||||||
.serialize_with_relocs(buffer, &mut self.relocations.entries);
|
.serialize_with_relocs(buffer, &mut self.relocations.entries);
|
||||||
|
|
||||||
// If we have imports, references to other functions need to be re-indexed.
|
|
||||||
// Simplest to do after serialization, using linker data
|
|
||||||
if n_imported_fns > 0 {
|
|
||||||
self.finalize_code_fn_indices(buffer, code_section_body_index, n_imported_fns);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.data.serialize(buffer);
|
self.data.serialize(buffer);
|
||||||
|
|
||||||
self.linking.serialize(buffer);
|
self.linking.serialize(buffer);
|
||||||
|
@ -766,63 +750,6 @@ impl<'a> WasmModule<'a> {
|
||||||
self.relocations.target_section_index = Some(code_section_index);
|
self.relocations.target_section_index = Some(code_section_index);
|
||||||
self.relocations.serialize(buffer);
|
self.relocations.serialize(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shift indices of exported functions to make room for imported functions,
|
|
||||||
/// which come first in the function index space.
|
|
||||||
/// Must be called after traversing the full IR, but before export section is serialized.
|
|
||||||
fn finalize_exported_fn_indices(&mut self, n_imported_fns: u32) {
|
|
||||||
for export in self.export.entries.iter_mut() {
|
|
||||||
if export.ty == ExportType::Func {
|
|
||||||
export.index += n_imported_fns;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Re-index internally-defined functions to make room for imported functions.
|
|
||||||
/// Imported functions come first in the index space, but we didn't know how many we needed until now.
|
|
||||||
/// We do this after serializing the code section, since we have linker data that is literally
|
|
||||||
/// *designed* for changing function indices in serialized code!
|
|
||||||
fn finalize_code_fn_indices<T: SerialBuffer>(
|
|
||||||
&mut self,
|
|
||||||
buffer: &mut T,
|
|
||||||
code_section_body_index: usize,
|
|
||||||
n_imported_fns: u32,
|
|
||||||
) {
|
|
||||||
// Lookup vector of symbol index to new function index
|
|
||||||
let mut new_index_lookup = std::vec::Vec::with_capacity(self.linking.symbol_table.len());
|
|
||||||
|
|
||||||
// Modify symbol table entries and fill the lookup vector
|
|
||||||
for sym_info in self.linking.symbol_table.iter_mut() {
|
|
||||||
match sym_info {
|
|
||||||
SymInfo::Function(WasmObjectSymbol::Defined { index, .. }) => {
|
|
||||||
let new_fn_index = *index + n_imported_fns;
|
|
||||||
*index = new_fn_index;
|
|
||||||
new_index_lookup.push(new_fn_index);
|
|
||||||
}
|
|
||||||
SymInfo::Function(WasmObjectSymbol::Imported { index, .. }) => {
|
|
||||||
new_index_lookup.push(*index);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// Symbol is not a function, so we won't look it up. Use a dummy value.
|
|
||||||
new_index_lookup.push(u32::MAX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modify call instructions, using linker data
|
|
||||||
for reloc in &self.relocations.entries {
|
|
||||||
if let RelocationEntry::Index {
|
|
||||||
type_id: IndexRelocType::FunctionIndexLeb,
|
|
||||||
offset,
|
|
||||||
symbol_index,
|
|
||||||
} = reloc
|
|
||||||
{
|
|
||||||
let new_fn_index = new_index_lookup[*symbol_index as usize];
|
|
||||||
let buffer_index = code_section_body_index + (*offset as usize);
|
|
||||||
buffer.overwrite_padded_u32(buffer_index, new_fn_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assertion to run on the generated Wasm module in every test
|
/// Assertion to run on the generated Wasm module in every test
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue