mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 07:14:46 +00:00
wasm: Keep exported global variables from the preloaded object file
This commit is contained in:
parent
b46690ecf2
commit
4c7be277c2
2 changed files with 45 additions and 9 deletions
|
@ -11,8 +11,6 @@ pub use linking::SymInfo;
|
|||
use roc_error_macros::internal_error;
|
||||
pub use sections::{ConstExpr, Export, ExportType, Global, GlobalType, Signature};
|
||||
|
||||
use crate::wasm_module::serialize::SkipBytes;
|
||||
|
||||
use self::linking::{LinkingSection, RelocationSection};
|
||||
use self::sections::{
|
||||
CodeSection, DataSection, ElementSection, ExportSection, FunctionSection, GlobalSection,
|
||||
|
@ -146,8 +144,7 @@ impl<'a> WasmModule<'a> {
|
|||
|
||||
let global = GlobalSection::preload(arena, bytes, &mut cursor);
|
||||
|
||||
ExportSection::skip_bytes(bytes, &mut cursor);
|
||||
let export = ExportSection::empty(arena);
|
||||
let export = ExportSection::preload_globals(arena, bytes, &mut cursor);
|
||||
|
||||
let start = OpaqueSection::preload(SectionId::Start, arena, bytes, &mut cursor);
|
||||
|
||||
|
|
|
@ -646,6 +646,18 @@ pub enum ExportType {
|
|||
Global = 3,
|
||||
}
|
||||
|
||||
impl From<u8> for ExportType {
|
||||
fn from(x: u8) -> Self {
|
||||
match x {
|
||||
0 => Self::Func,
|
||||
1 => Self::Table,
|
||||
2 => Self::Mem,
|
||||
3 => Self::Global,
|
||||
_ => internal_error!("invalid ExportType {:2x?}", x),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Export<'a> {
|
||||
pub name: &'a [u8],
|
||||
|
@ -653,6 +665,19 @@ pub struct Export<'a> {
|
|||
pub index: u32,
|
||||
}
|
||||
|
||||
impl<'a> Export<'a> {
|
||||
fn parse_type(bytes: &[u8], cursor: &mut usize) -> ExportType {
|
||||
String::skip_bytes(bytes, cursor); // name
|
||||
|
||||
let ty = ExportType::from(bytes[*cursor]);
|
||||
*cursor += 1;
|
||||
|
||||
u32::skip_bytes(bytes, cursor); // index
|
||||
|
||||
ty
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Export<'_> {
|
||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||
self.name.serialize(buffer);
|
||||
|
@ -683,18 +708,32 @@ impl<'a> ExportSection<'a> {
|
|||
section_size(&self.bytes)
|
||||
}
|
||||
|
||||
pub fn empty(arena: &'a Bump) -> Self {
|
||||
fn empty(arena: &'a Bump) -> Self {
|
||||
ExportSection {
|
||||
count: 0,
|
||||
bytes: Vec::with_capacity_in(256, arena),
|
||||
function_indices: Vec::with_capacity_in(4, arena),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SkipBytes for ExportSection<'_> {
|
||||
fn skip_bytes(bytes: &[u8], cursor: &mut usize) {
|
||||
parse_section(Self::ID, bytes, cursor);
|
||||
/// Preload from object file. Keep only the Global exports, ignore the rest.
|
||||
pub fn preload_globals(arena: &'a Bump, module_bytes: &[u8], cursor: &mut usize) -> Self {
|
||||
let (num_exports, body_bytes) = parse_section(Self::ID, module_bytes, cursor);
|
||||
|
||||
let mut export_section = ExportSection::empty(arena);
|
||||
|
||||
let mut body_cursor = 0;
|
||||
for _ in 0..num_exports {
|
||||
let export_start = body_cursor;
|
||||
let export_type = Export::parse_type(body_bytes, &mut body_cursor);
|
||||
if matches!(export_type, ExportType::Global) {
|
||||
let global_bytes = &body_bytes[export_start..body_cursor];
|
||||
export_section.bytes.extend_from_slice(global_bytes);
|
||||
export_section.count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
export_section
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue