mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +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;
|
use roc_error_macros::internal_error;
|
||||||
pub use sections::{ConstExpr, Export, ExportType, Global, GlobalType, Signature};
|
pub use sections::{ConstExpr, Export, ExportType, Global, GlobalType, Signature};
|
||||||
|
|
||||||
use crate::wasm_module::serialize::SkipBytes;
|
|
||||||
|
|
||||||
use self::linking::{LinkingSection, RelocationSection};
|
use self::linking::{LinkingSection, RelocationSection};
|
||||||
use self::sections::{
|
use self::sections::{
|
||||||
CodeSection, DataSection, ElementSection, ExportSection, FunctionSection, GlobalSection,
|
CodeSection, DataSection, ElementSection, ExportSection, FunctionSection, GlobalSection,
|
||||||
|
@ -146,8 +144,7 @@ impl<'a> WasmModule<'a> {
|
||||||
|
|
||||||
let global = GlobalSection::preload(arena, bytes, &mut cursor);
|
let global = GlobalSection::preload(arena, bytes, &mut cursor);
|
||||||
|
|
||||||
ExportSection::skip_bytes(bytes, &mut cursor);
|
let export = ExportSection::preload_globals(arena, bytes, &mut cursor);
|
||||||
let export = ExportSection::empty(arena);
|
|
||||||
|
|
||||||
let start = OpaqueSection::preload(SectionId::Start, arena, bytes, &mut cursor);
|
let start = OpaqueSection::preload(SectionId::Start, arena, bytes, &mut cursor);
|
||||||
|
|
||||||
|
|
|
@ -646,6 +646,18 @@ pub enum ExportType {
|
||||||
Global = 3,
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct Export<'a> {
|
pub struct Export<'a> {
|
||||||
pub name: &'a [u8],
|
pub name: &'a [u8],
|
||||||
|
@ -653,6 +665,19 @@ pub struct Export<'a> {
|
||||||
pub index: u32,
|
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<'_> {
|
impl Serialize for Export<'_> {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
self.name.serialize(buffer);
|
self.name.serialize(buffer);
|
||||||
|
@ -683,18 +708,32 @@ impl<'a> ExportSection<'a> {
|
||||||
section_size(&self.bytes)
|
section_size(&self.bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty(arena: &'a Bump) -> Self {
|
fn empty(arena: &'a Bump) -> Self {
|
||||||
ExportSection {
|
ExportSection {
|
||||||
count: 0,
|
count: 0,
|
||||||
bytes: Vec::with_capacity_in(256, arena),
|
bytes: Vec::with_capacity_in(256, arena),
|
||||||
function_indices: Vec::with_capacity_in(4, arena),
|
function_indices: Vec::with_capacity_in(4, arena),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl SkipBytes for ExportSection<'_> {
|
/// Preload from object file. Keep only the Global exports, ignore the rest.
|
||||||
fn skip_bytes(bytes: &[u8], cursor: &mut usize) {
|
pub fn preload_globals(arena: &'a Bump, module_bytes: &[u8], cursor: &mut usize) -> Self {
|
||||||
parse_section(Self::ID, bytes, cursor);
|
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