mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Replace byte slices with str
This commit is contained in:
parent
c16a5ad8ae
commit
84a3ac2ef6
7 changed files with 68 additions and 63 deletions
|
@ -1,5 +1,4 @@
|
|||
use bumpalo::{self, collections::Vec};
|
||||
use std::fmt::Write;
|
||||
use bumpalo::collections::{String, Vec};
|
||||
|
||||
use code_builder::Align;
|
||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
|
@ -90,16 +89,18 @@ impl<'a> WasmBackend<'a> {
|
|||
|
||||
// The preloaded binary has a global to tell us where its data section ends
|
||||
// Note: We need this to account for zero data (.bss), which doesn't have an explicit DataSegment!
|
||||
let data_end_name = "__data_end".as_bytes();
|
||||
let data_end_idx = app_exports
|
||||
.iter()
|
||||
.find(|ex| ex.name == data_end_name)
|
||||
.find(|ex| ex.name == "__data_end")
|
||||
.map(|ex| ex.index)
|
||||
.unwrap_or_else(|| {
|
||||
internal_error!("Preloaded Wasm binary must export global constant `__data_end`")
|
||||
});
|
||||
// TODO: move this to module parsing
|
||||
let next_constant_addr = module.global.parse_u32_at_index(data_end_idx).unwrap_or_else(|e| {
|
||||
let next_constant_addr = module
|
||||
.global
|
||||
.parse_u32_at_index(data_end_idx)
|
||||
.unwrap_or_else(|e| {
|
||||
internal_error!("Failed to parse __data_end from object file: {:?}", e);
|
||||
});
|
||||
|
||||
|
@ -145,6 +146,7 @@ impl<'a> WasmBackend<'a> {
|
|||
.layout_ids
|
||||
.get_toplevel(symbol, &layout)
|
||||
.to_symbol_string(symbol, self.interns);
|
||||
let name = String::from_str_in(&name, self.env.arena).into_bump_str();
|
||||
|
||||
self.proc_lookup.push(ProcLookupData {
|
||||
name: symbol,
|
||||
|
@ -302,10 +304,8 @@ impl<'a> WasmBackend<'a> {
|
|||
.unwrap();
|
||||
let wasm_fn_index = self.fn_index_offset + proc_index as u32;
|
||||
|
||||
let mut debug_name = bumpalo::collections::String::with_capacity_in(64, self.env.arena);
|
||||
write!(debug_name, "{:?}", sym).unwrap();
|
||||
let name_bytes = debug_name.into_bytes().into_bump_slice();
|
||||
self.module.names.append_function(wasm_fn_index, name_bytes);
|
||||
let name = String::from_str_in(sym.as_str(self.interns), self.env.arena).into_bump_str();
|
||||
self.module.names.append_function(wasm_fn_index, name);
|
||||
}
|
||||
|
||||
/// Build a wrapper around a Roc procedure so that it can be called from our higher-order Zig builtins.
|
||||
|
@ -952,10 +952,11 @@ impl<'a> WasmBackend<'a> {
|
|||
.layout_ids
|
||||
.get(sym, &Layout::Builtin(Builtin::Str))
|
||||
.to_symbol_string(sym, self.interns);
|
||||
let name = String::from_str_in(&name, self.env.arena).into_bump_str();
|
||||
|
||||
let linker_symbol = SymInfo::Data(DataSymbol::Defined {
|
||||
flags: 0,
|
||||
name: name.clone(),
|
||||
name,
|
||||
segment_index,
|
||||
segment_offset: 4,
|
||||
size: bytes.len() as u32,
|
||||
|
@ -1102,7 +1103,7 @@ impl<'a> WasmBackend<'a> {
|
|||
num_wasm_args: usize,
|
||||
has_return_val: bool,
|
||||
) {
|
||||
let fn_index = self.module.names.functions[name.as_bytes()];
|
||||
let fn_index = self.module.names.functions[name];
|
||||
self.called_preload_fns.push(fn_index);
|
||||
let linker_symbol_index = u32::MAX;
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ pub mod wasm_module;
|
|||
pub mod wasm32_result;
|
||||
pub mod wasm32_sized;
|
||||
|
||||
use bumpalo::{self, collections::Vec, Bump};
|
||||
use bumpalo::collections::{String, Vec};
|
||||
use bumpalo::{self, Bump};
|
||||
|
||||
use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_module::low_level::LowLevelWrapperType;
|
||||
|
@ -58,7 +59,7 @@ pub fn build_module<'a>(
|
|||
interns: &'a mut Interns,
|
||||
preload_bytes: &[u8],
|
||||
procedures: MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
) -> Result<std::vec::Vec<u8>, String> {
|
||||
) -> Result<std::vec::Vec<u8>, std::string::String> {
|
||||
let (mut wasm_module, called_preload_fns, _) =
|
||||
build_module_unserialized(env, interns, preload_bytes, procedures)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
|
@ -102,17 +103,18 @@ pub fn build_module_unserialized<'a>(
|
|||
let fn_name = layout_ids
|
||||
.get_toplevel(sym, &proc_layout)
|
||||
.to_symbol_string(sym, interns);
|
||||
let name = String::from_str_in(&fn_name, env.arena).into_bump_str();
|
||||
|
||||
if env.exposed_to_host.contains(&sym) {
|
||||
maybe_main_fn_index = Some(fn_index);
|
||||
exports.push(Export {
|
||||
name: env.arena.alloc_slice_copy(fn_name.as_bytes()),
|
||||
name,
|
||||
ty: ExportType::Func,
|
||||
index: fn_index,
|
||||
});
|
||||
}
|
||||
|
||||
let linker_sym = SymInfo::for_function(fn_index, fn_name);
|
||||
let linker_sym = SymInfo::for_function(fn_index, name);
|
||||
let linker_sym_index = linker_symbols.len() as u32;
|
||||
|
||||
// linker_sym_index is redundant for these procs from user code, but needed for generated helpers!
|
||||
|
|
|
@ -22,7 +22,7 @@ pub trait Wasm32Result {
|
|||
fn insert_wrapper<'a>(
|
||||
arena: &'a Bump,
|
||||
module: &mut WasmModule<'a>,
|
||||
wrapper_name: &str,
|
||||
wrapper_name: &'static str,
|
||||
main_function_index: u32,
|
||||
) {
|
||||
insert_wrapper_metadata(arena, module, wrapper_name);
|
||||
|
@ -38,7 +38,7 @@ pub trait Wasm32Result {
|
|||
pub fn insert_wrapper_for_layout<'a>(
|
||||
arena: &'a Bump,
|
||||
module: &mut WasmModule<'a>,
|
||||
wrapper_name: &str,
|
||||
wrapper_name: &'static str,
|
||||
main_fn_index: u32,
|
||||
layout: &Layout<'a>,
|
||||
) {
|
||||
|
@ -84,7 +84,11 @@ pub fn insert_wrapper_for_layout<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
fn insert_wrapper_metadata<'a>(arena: &'a Bump, module: &mut WasmModule<'a>, wrapper_name: &str) {
|
||||
fn insert_wrapper_metadata<'a>(
|
||||
arena: &'a Bump,
|
||||
module: &mut WasmModule<'a>,
|
||||
wrapper_name: &'static str,
|
||||
) {
|
||||
let index = module.import.function_count
|
||||
+ module.code.preloaded_count
|
||||
+ module.code.code_builders.len() as u32;
|
||||
|
@ -95,7 +99,7 @@ fn insert_wrapper_metadata<'a>(arena: &'a Bump, module: &mut WasmModule<'a>, wra
|
|||
});
|
||||
|
||||
module.export.append(Export {
|
||||
name: arena.alloc_slice_copy(wrapper_name.as_bytes()),
|
||||
name: wrapper_name,
|
||||
ty: ExportType::Func,
|
||||
index,
|
||||
});
|
||||
|
@ -103,7 +107,7 @@ fn insert_wrapper_metadata<'a>(arena: &'a Bump, module: &mut WasmModule<'a>, wra
|
|||
let linker_symbol = SymInfo::Function(WasmObjectSymbol::Defined {
|
||||
flags: 0,
|
||||
index,
|
||||
name: wrapper_name.to_string(),
|
||||
name: wrapper_name,
|
||||
});
|
||||
module.linking.symbol_table.push(linker_symbol);
|
||||
}
|
||||
|
|
|
@ -175,13 +175,13 @@ impl<'a> Serialize for RelocationSection<'a> {
|
|||
|
||||
/// Linking metadata for data segments
|
||||
#[derive(Debug)]
|
||||
pub struct LinkingSegment {
|
||||
pub name: String,
|
||||
pub struct LinkingSegment<'a> {
|
||||
pub name: &'a str,
|
||||
pub alignment: Align,
|
||||
pub flags: u32,
|
||||
}
|
||||
|
||||
impl Serialize for LinkingSegment {
|
||||
impl<'a> Serialize for LinkingSegment<'a> {
|
||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||
buffer.encode_u32(self.name.len() as u32);
|
||||
buffer.append_slice(self.name.as_bytes());
|
||||
|
@ -238,7 +238,7 @@ impl Serialize for ComdatSym {
|
|||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub struct LinkingComdat<'a> {
|
||||
name: String,
|
||||
name: &'a str,
|
||||
flags: u32,
|
||||
syms: Vec<'a, ComdatSym>,
|
||||
}
|
||||
|
@ -292,11 +292,11 @@ pub const WASM_SYM_EXPLICIT_NAME: u32 = 0x40; // use the name from the symbol ta
|
|||
pub const WASM_SYM_NO_STRIP: u32 = 0x80;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum WasmObjectSymbol {
|
||||
pub enum WasmObjectSymbol<'a> {
|
||||
Defined {
|
||||
flags: u32,
|
||||
index: u32,
|
||||
name: String,
|
||||
name: &'a str,
|
||||
},
|
||||
Imported {
|
||||
flags: u32,
|
||||
|
@ -304,7 +304,7 @@ pub enum WasmObjectSymbol {
|
|||
},
|
||||
}
|
||||
|
||||
impl Serialize for WasmObjectSymbol {
|
||||
impl<'a> Serialize for WasmObjectSymbol<'a> {
|
||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||
match self {
|
||||
Self::Defined { flags, index, name } => {
|
||||
|
@ -322,21 +322,21 @@ impl Serialize for WasmObjectSymbol {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum DataSymbol {
|
||||
pub enum DataSymbol<'a> {
|
||||
Defined {
|
||||
flags: u32,
|
||||
name: String,
|
||||
name: &'a str,
|
||||
segment_index: u32,
|
||||
segment_offset: u32,
|
||||
size: u32,
|
||||
},
|
||||
Imported {
|
||||
flags: u32,
|
||||
name: String,
|
||||
name: &'a str,
|
||||
},
|
||||
}
|
||||
|
||||
impl Serialize for DataSymbol {
|
||||
impl<'a> Serialize for DataSymbol<'a> {
|
||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||
match self {
|
||||
Self::Defined {
|
||||
|
@ -377,17 +377,17 @@ impl Serialize for SectionSymbol {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum SymInfo {
|
||||
Function(WasmObjectSymbol),
|
||||
Data(DataSymbol),
|
||||
Global(WasmObjectSymbol),
|
||||
pub enum SymInfo<'a> {
|
||||
Function(WasmObjectSymbol<'a>),
|
||||
Data(DataSymbol<'a>),
|
||||
Global(WasmObjectSymbol<'a>),
|
||||
Section(SectionSymbol),
|
||||
Event(WasmObjectSymbol),
|
||||
Table(WasmObjectSymbol),
|
||||
Event(WasmObjectSymbol<'a>),
|
||||
Table(WasmObjectSymbol<'a>),
|
||||
}
|
||||
|
||||
impl SymInfo {
|
||||
pub fn for_function(wasm_function_index: u32, name: String) -> Self {
|
||||
impl<'a> SymInfo<'a> {
|
||||
pub fn for_function(wasm_function_index: u32, name: &'a str) -> Self {
|
||||
SymInfo::Function(WasmObjectSymbol::Defined {
|
||||
flags: 0,
|
||||
index: wasm_function_index,
|
||||
|
@ -396,7 +396,7 @@ impl SymInfo {
|
|||
}
|
||||
}
|
||||
|
||||
impl Serialize for SymInfo {
|
||||
impl<'a> Serialize for SymInfo<'a> {
|
||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||
buffer.append_u8(match self {
|
||||
Self::Function(_) => 0,
|
||||
|
@ -459,8 +459,8 @@ const LINKING_VERSION: u8 = 2;
|
|||
/// No point writing code to "find" the symbol table, when we know there's exactly one.
|
||||
#[derive(Debug)]
|
||||
pub struct LinkingSection<'a> {
|
||||
pub symbol_table: Vec<'a, SymInfo>,
|
||||
pub segment_info: Vec<'a, LinkingSegment>,
|
||||
pub symbol_table: Vec<'a, SymInfo<'a>>,
|
||||
pub segment_info: Vec<'a, LinkingSegment<'a>>,
|
||||
pub init_funcs: Vec<'a, LinkingInitFunc>,
|
||||
pub comdat_info: Vec<'a, LinkingComdat<'a>>,
|
||||
}
|
||||
|
|
|
@ -52,15 +52,15 @@ impl Parse<()> for u32 {
|
|||
}
|
||||
}
|
||||
|
||||
// Parse string bytes without utf8 validation
|
||||
impl<'a> Parse<&'a Bump> for &'a [u8] {
|
||||
impl<'a> Parse<&'a Bump> for &'a str {
|
||||
fn parse(arena: &'a Bump, bytes: &[u8], cursor: &mut usize) -> Result<Self, ParseError> {
|
||||
let len = u32::parse((), bytes, cursor)?;
|
||||
let end = *cursor + len as usize;
|
||||
let bytes: &[u8] = &bytes[*cursor..end];
|
||||
let copy = arena.alloc_slice_copy(bytes);
|
||||
let s = unsafe { std::str::from_utf8_unchecked(copy) };
|
||||
*cursor = end;
|
||||
Ok(copy)
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -787,14 +787,14 @@ impl From<u8> for ExportType {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Export<'a> {
|
||||
pub name: &'a [u8],
|
||||
pub name: &'a str,
|
||||
pub ty: ExportType,
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
impl<'a> Export<'a> {
|
||||
fn parse(arena: &'a Bump, bytes: &[u8], cursor: &mut usize) -> Self {
|
||||
let name = <&'a [u8]>::parse(arena, bytes, cursor).unwrap();
|
||||
let name = <&'a str>::parse(arena, bytes, cursor).unwrap();
|
||||
|
||||
let ty = ExportType::from(bytes[*cursor]);
|
||||
*cursor += 1;
|
||||
|
@ -1257,7 +1257,7 @@ enum NameSubSections {
|
|||
|
||||
pub struct NameSection<'a> {
|
||||
pub bytes: Vec<'a, u8>,
|
||||
pub functions: MutMap<&'a [u8], u32>,
|
||||
pub functions: MutMap<&'a str, u32>,
|
||||
}
|
||||
|
||||
impl<'a> NameSection<'a> {
|
||||
|
@ -1268,7 +1268,7 @@ impl<'a> NameSection<'a> {
|
|||
self.bytes.len()
|
||||
}
|
||||
|
||||
pub fn append_function(&mut self, index: u32, name: &'a [u8]) {
|
||||
pub fn append_function(&mut self, index: u32, name: &'a str) {
|
||||
index.serialize(&mut self.bytes);
|
||||
name.serialize(&mut self.bytes);
|
||||
self.functions.insert(name, index);
|
||||
|
@ -1315,12 +1315,12 @@ impl<'a> NameSection<'a> {
|
|||
cursor: &mut usize,
|
||||
section_end: usize,
|
||||
) {
|
||||
let section_name = <&'a [u8]>::parse(arena, module_bytes, cursor).unwrap();
|
||||
if section_name != Self::NAME.as_bytes() {
|
||||
let section_name = <&'a str>::parse(arena, module_bytes, cursor).unwrap();
|
||||
if section_name != Self::NAME {
|
||||
internal_error!(
|
||||
"Expected Custom section {:?}, found {:?}",
|
||||
Self::NAME,
|
||||
std::str::from_utf8(section_name)
|
||||
section_name
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1348,9 +1348,8 @@ impl<'a> NameSection<'a> {
|
|||
let fn_names_start = *cursor;
|
||||
for _ in 0..num_entries {
|
||||
let fn_index = u32::parse((), module_bytes, cursor).unwrap();
|
||||
let name_bytes = <&'a [u8]>::parse(arena, module_bytes, cursor).unwrap();
|
||||
self.functions
|
||||
.insert(arena.alloc_slice_copy(name_bytes), fn_index);
|
||||
let name_bytes = <&'a str>::parse(arena, module_bytes, cursor).unwrap();
|
||||
self.functions.insert(name_bytes, fn_index);
|
||||
}
|
||||
|
||||
// Copy only the bytes for the function names segment
|
||||
|
@ -1395,8 +1394,7 @@ impl<'a> Debug for NameSection<'a> {
|
|||
by_index.sort_unstable();
|
||||
|
||||
for (index, name) in by_index.iter() {
|
||||
let name_str = unsafe { std::str::from_utf8_unchecked(name) };
|
||||
writeln!(f, " {:4}: {}", index, name_str)?;
|
||||
writeln!(f, " {:4}: {}", index, name)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -120,15 +120,15 @@ fn compile_roc_to_wasm_bytes<'a, T: Wasm32Result>(
|
|||
};
|
||||
|
||||
let (mut module, called_preload_fns, main_fn_index) =
|
||||
roc_gen_wasm::build_module_unserialized(&env, &mut interns, preload_bytes, procedures).unwrap();
|
||||
roc_gen_wasm::build_module_unserialized(&env, &mut interns, preload_bytes, procedures)
|
||||
.unwrap();
|
||||
|
||||
T::insert_wrapper(arena, &mut module, TEST_WRAPPER_NAME, main_fn_index);
|
||||
|
||||
// Export the initialiser function for refcount tests
|
||||
let init_refcount_bytes = INIT_REFCOUNT_NAME.as_bytes();
|
||||
let init_refcount_idx = module.names.functions[init_refcount_bytes];
|
||||
let init_refcount_idx = module.names.functions[INIT_REFCOUNT_NAME];
|
||||
module.export.append(Export {
|
||||
name: arena.alloc_slice_copy(init_refcount_bytes),
|
||||
name: INIT_REFCOUNT_NAME,
|
||||
ty: ExportType::Func,
|
||||
index: init_refcount_idx,
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue