mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
Replace some helper functions with Parse trait instances
This commit is contained in:
parent
8114ec60c1
commit
66c78ceed5
3 changed files with 35 additions and 54 deletions
|
@ -2,7 +2,7 @@ use bumpalo::collections::vec::Vec;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
|
||||||
use super::opcodes::OpCode;
|
use super::opcodes::OpCode;
|
||||||
use super::parse::{parse_u32_or_panic, SkipBytes};
|
use super::parse::{Parse, SkipBytes};
|
||||||
use super::serialize::{SerialBuffer, Serialize};
|
use super::serialize::{SerialBuffer, Serialize};
|
||||||
use super::CodeBuilder;
|
use super::CodeBuilder;
|
||||||
|
|
||||||
|
@ -92,13 +92,13 @@ pub fn parse_preloads_call_graph<'a>(
|
||||||
call_graph.code_offsets.push(cursor as u32);
|
call_graph.code_offsets.push(cursor as u32);
|
||||||
call_graph.calls_offsets.push(call_graph.calls.len() as u32);
|
call_graph.calls_offsets.push(call_graph.calls.len() as u32);
|
||||||
|
|
||||||
let func_size = parse_u32_or_panic(code_section_body, &mut cursor);
|
let func_size = u32::parse((), code_section_body, &mut cursor).unwrap();
|
||||||
let func_end = cursor + func_size as usize;
|
let func_end = cursor + func_size as usize;
|
||||||
|
|
||||||
// Skip over local variable declarations
|
// Skip over local variable declarations
|
||||||
let local_groups_count = parse_u32_or_panic(code_section_body, &mut cursor);
|
let local_groups_count = u32::parse((), code_section_body, &mut cursor).unwrap();
|
||||||
for _ in 0..local_groups_count {
|
for _ in 0..local_groups_count {
|
||||||
parse_u32_or_panic(code_section_body, &mut cursor);
|
u32::parse((), code_section_body, &mut cursor).unwrap();
|
||||||
cursor += 1; // ValueType
|
cursor += 1; // ValueType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,12 +107,12 @@ pub fn parse_preloads_call_graph<'a>(
|
||||||
let opcode_byte: u8 = code_section_body[cursor];
|
let opcode_byte: u8 = code_section_body[cursor];
|
||||||
if opcode_byte == OpCode::CALL as u8 {
|
if opcode_byte == OpCode::CALL as u8 {
|
||||||
cursor += 1;
|
cursor += 1;
|
||||||
let call_index = parse_u32_or_panic(code_section_body, &mut cursor);
|
let call_index = u32::parse((), code_section_body, &mut cursor).unwrap();
|
||||||
call_graph.calls.push(call_index as u32);
|
call_graph.calls.push(call_index as u32);
|
||||||
} else if opcode_byte == OpCode::CALLINDIRECT as u8 {
|
} else if opcode_byte == OpCode::CALLINDIRECT as u8 {
|
||||||
cursor += 1;
|
cursor += 1;
|
||||||
// Insert all indirect callees with a matching type signature
|
// Insert all indirect callees with a matching type signature
|
||||||
let sig = parse_u32_or_panic(code_section_body, &mut cursor);
|
let sig = u32::parse((), code_section_body, &mut cursor).unwrap();
|
||||||
call_graph.calls.extend(
|
call_graph.calls.extend(
|
||||||
indirect_callees
|
indirect_callees
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use super::serialize::MAX_SIZE_ENCODED_U32;
|
use super::serialize::MAX_SIZE_ENCODED_U32;
|
||||||
use bumpalo::collections::vec::Vec;
|
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use roc_error_macros::internal_error;
|
|
||||||
|
|
||||||
/// Parse serialized bytes into a data structure
|
/// Parse serialized bytes into a data structure
|
||||||
/// Specific parsers may need contextual data from other parts of the .wasm file
|
/// Specific parsers may need contextual data from other parts of the .wasm file
|
||||||
|
@ -41,34 +39,18 @@ impl Parse<()> for u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse a vector of bytes (used for strings, but we don't bother with utf8 validation)
|
// Parse string bytes without utf8 validation
|
||||||
impl<'a> Parse<&'a Bump> for Vec<'a, u8> {
|
impl<'a> Parse<&'a Bump> for &'a [u8] {
|
||||||
fn parse(arena: &'a Bump, bytes: &[u8], cursor: &mut usize) -> Result<Self, String> {
|
fn parse(arena: &'a Bump, bytes: &[u8], cursor: &mut usize) -> Result<Self, String> {
|
||||||
let len = parse_u32_or_panic(bytes, cursor);
|
let len = u32::parse((), bytes, cursor)?;
|
||||||
let end = *cursor + len as usize;
|
let end = *cursor + len as usize;
|
||||||
let bytes: &[u8] = &bytes[*cursor..end];
|
let bytes: &[u8] = &bytes[*cursor..end];
|
||||||
let mut copy = Vec::with_capacity_in(bytes.len(), arena);
|
let copy = arena.alloc_slice_copy(bytes);
|
||||||
copy.extend_from_slice(bytes);
|
|
||||||
*cursor = end;
|
*cursor = end;
|
||||||
Ok(copy)
|
Ok(copy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_u32_or_panic(bytes: &[u8], cursor: &mut usize) -> u32 {
|
|
||||||
let (value, len) = decode_u32(&bytes[*cursor..]).unwrap_or_else(|e| internal_error!("{}", e));
|
|
||||||
*cursor += len;
|
|
||||||
value
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_string_bytes<'a>(arena: &'a Bump, bytes: &[u8], cursor: &mut usize) -> &'a [u8] {
|
|
||||||
let len = parse_u32_or_panic(bytes, cursor);
|
|
||||||
let end = *cursor + len as usize;
|
|
||||||
let bytes: &[u8] = &bytes[*cursor..end];
|
|
||||||
let copy = arena.alloc_slice_copy(bytes);
|
|
||||||
*cursor = end;
|
|
||||||
copy
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SkipBytes for u32 {
|
impl SkipBytes for u32 {
|
||||||
fn skip_bytes(bytes: &[u8], cursor: &mut usize) -> Result<(), String> {
|
fn skip_bytes(bytes: &[u8], cursor: &mut usize) -> Result<(), String> {
|
||||||
const MAX_LEN: usize = 5;
|
const MAX_LEN: usize = 5;
|
||||||
|
@ -105,7 +87,7 @@ impl SkipBytes for u8 {
|
||||||
/// Note: This is just for skipping over Wasm bytes. We don't actually care about String vs str!
|
/// Note: This is just for skipping over Wasm bytes. We don't actually care about String vs str!
|
||||||
impl SkipBytes for String {
|
impl SkipBytes for String {
|
||||||
fn skip_bytes(bytes: &[u8], cursor: &mut usize) -> Result<(), String> {
|
fn skip_bytes(bytes: &[u8], cursor: &mut usize) -> Result<(), String> {
|
||||||
let len = parse_u32_or_panic(bytes, cursor);
|
let len = u32::parse((), bytes, cursor)?;
|
||||||
|
|
||||||
if false {
|
if false {
|
||||||
let str_bytes = &bytes[*cursor..(*cursor + len as usize)];
|
let str_bytes = &bytes[*cursor..(*cursor + len as usize)];
|
||||||
|
@ -123,7 +105,7 @@ impl SkipBytes for String {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::wasm_module::parse::{decode_u32, parse_u32_or_panic};
|
use crate::wasm_module::parse::decode_u32;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_u32() {
|
fn test_decode_u32() {
|
||||||
|
@ -148,13 +130,13 @@ mod tests {
|
||||||
let expected = [0, 128, u32::MAX];
|
let expected = [0, 128, u32::MAX];
|
||||||
let mut cursor = 0;
|
let mut cursor = 0;
|
||||||
|
|
||||||
assert_eq!(parse_u32_or_panic(bytes, &mut cursor), expected[0]);
|
assert_eq!(u32::parse((), bytes, &mut cursor).unwrap(), expected[0]);
|
||||||
assert_eq!(cursor, 1);
|
assert_eq!(cursor, 1);
|
||||||
|
|
||||||
assert_eq!(parse_u32_or_panic(bytes, &mut cursor), expected[1]);
|
assert_eq!(u32::parse((), bytes, &mut cursor).unwrap(), expected[1]);
|
||||||
assert_eq!(cursor, 3);
|
assert_eq!(cursor, 3);
|
||||||
|
|
||||||
assert_eq!(parse_u32_or_panic(bytes, &mut cursor), expected[2]);
|
assert_eq!(u32::parse((), bytes, &mut cursor).unwrap(), expected[2]);
|
||||||
assert_eq!(cursor, 8);
|
assert_eq!(cursor, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use super::dead_code::{
|
||||||
};
|
};
|
||||||
use super::linking::RelocationEntry;
|
use super::linking::RelocationEntry;
|
||||||
use super::opcodes::OpCode;
|
use super::opcodes::OpCode;
|
||||||
use super::parse::{parse_string_bytes, parse_u32_or_panic, Parse, SkipBytes};
|
use super::parse::{Parse, SkipBytes};
|
||||||
use super::serialize::{SerialBuffer, Serialize, MAX_SIZE_ENCODED_U32};
|
use super::serialize::{SerialBuffer, Serialize, MAX_SIZE_ENCODED_U32};
|
||||||
use super::{CodeBuilder, ValueType};
|
use super::{CodeBuilder, ValueType};
|
||||||
|
|
||||||
|
@ -118,9 +118,9 @@ fn parse_section<'a>(id: SectionId, module_bytes: &'a [u8], cursor: &mut usize)
|
||||||
}
|
}
|
||||||
*cursor += 1;
|
*cursor += 1;
|
||||||
|
|
||||||
let section_size = parse_u32_or_panic(module_bytes, cursor);
|
let section_size = u32::parse((), module_bytes, cursor).unwrap();
|
||||||
let count_start = *cursor;
|
let count_start = *cursor;
|
||||||
let count = parse_u32_or_panic(module_bytes, cursor);
|
let count = u32::parse((), module_bytes, cursor).unwrap();
|
||||||
let body_start = *cursor;
|
let body_start = *cursor;
|
||||||
|
|
||||||
let next_section_start = count_start + section_size as usize;
|
let next_section_start = count_start + section_size as usize;
|
||||||
|
@ -237,7 +237,7 @@ impl<'a> TypeSection<'a> {
|
||||||
debug_assert!(self.bytes[i] == Signature::SEPARATOR);
|
debug_assert!(self.bytes[i] == Signature::SEPARATOR);
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
||||||
let n_params = parse_u32_or_panic(&self.bytes, &mut i);
|
let n_params = u32::parse((), &self.bytes, &mut i).unwrap();
|
||||||
i += n_params as usize; // skip over one byte per param type
|
i += n_params as usize; // skip over one byte per param type
|
||||||
|
|
||||||
let n_return_values = self.bytes[i];
|
let n_return_values = self.bytes[i];
|
||||||
|
@ -421,7 +421,7 @@ impl<'a> FunctionSection<'a> {
|
||||||
let mut signatures = Vec::with_capacity_in(count, arena);
|
let mut signatures = Vec::with_capacity_in(count, arena);
|
||||||
let mut cursor = 0;
|
let mut cursor = 0;
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
signatures.push(parse_u32_or_panic(&self.bytes, &mut cursor));
|
signatures.push(u32::parse((), &self.bytes, &mut cursor).unwrap());
|
||||||
}
|
}
|
||||||
signatures
|
signatures
|
||||||
}
|
}
|
||||||
|
@ -579,9 +579,9 @@ impl Limits {
|
||||||
let variant_id = bytes[*cursor];
|
let variant_id = bytes[*cursor];
|
||||||
*cursor += 1;
|
*cursor += 1;
|
||||||
|
|
||||||
let min = parse_u32_or_panic(bytes, cursor);
|
let min = u32::parse((), bytes, cursor).unwrap();
|
||||||
if variant_id == LimitsId::MinMax as u8 {
|
if variant_id == LimitsId::MinMax as u8 {
|
||||||
let max = parse_u32_or_panic(bytes, cursor);
|
let max = u32::parse((), bytes, cursor).unwrap();
|
||||||
Limits::MinMax(min, max)
|
Limits::MinMax(min, max)
|
||||||
} else {
|
} else {
|
||||||
Limits::Min(min)
|
Limits::Min(min)
|
||||||
|
@ -663,7 +663,7 @@ impl ConstExpr {
|
||||||
}
|
}
|
||||||
*cursor += 1;
|
*cursor += 1;
|
||||||
|
|
||||||
let value = parse_u32_or_panic(bytes, cursor);
|
let value = u32::parse((), bytes, cursor).unwrap();
|
||||||
|
|
||||||
if bytes[*cursor] != OpCode::END as u8 {
|
if bytes[*cursor] != OpCode::END as u8 {
|
||||||
return err;
|
return err;
|
||||||
|
@ -791,12 +791,12 @@ pub struct Export<'a> {
|
||||||
|
|
||||||
impl<'a> Export<'a> {
|
impl<'a> Export<'a> {
|
||||||
fn parse(arena: &'a Bump, bytes: &[u8], cursor: &mut usize) -> Self {
|
fn parse(arena: &'a Bump, bytes: &[u8], cursor: &mut usize) -> Self {
|
||||||
let name = parse_string_bytes(arena, bytes, cursor);
|
let name = <&'a [u8]>::parse(arena, bytes, cursor).unwrap();
|
||||||
|
|
||||||
let ty = ExportType::from(bytes[*cursor]);
|
let ty = ExportType::from(bytes[*cursor]);
|
||||||
*cursor += 1;
|
*cursor += 1;
|
||||||
|
|
||||||
let index = parse_u32_or_panic(bytes, cursor);
|
let index = u32::parse((), bytes, cursor).unwrap();
|
||||||
|
|
||||||
Export { name, ty, index }
|
Export { name, ty, index }
|
||||||
}
|
}
|
||||||
|
@ -895,14 +895,14 @@ impl<'a> ElementSegment<'a> {
|
||||||
let const_expr_opcode = bytes[*cursor];
|
let const_expr_opcode = bytes[*cursor];
|
||||||
debug_assert!(const_expr_opcode == OpCode::I32CONST as u8);
|
debug_assert!(const_expr_opcode == OpCode::I32CONST as u8);
|
||||||
*cursor += 1;
|
*cursor += 1;
|
||||||
let offset = parse_u32_or_panic(bytes, cursor);
|
let offset = u32::parse((), bytes, cursor).unwrap();
|
||||||
debug_assert!(bytes[*cursor] == OpCode::END as u8);
|
debug_assert!(bytes[*cursor] == OpCode::END as u8);
|
||||||
*cursor += 1;
|
*cursor += 1;
|
||||||
|
|
||||||
let num_elems = parse_u32_or_panic(bytes, cursor);
|
let num_elems = u32::parse((), bytes, cursor).unwrap();
|
||||||
let mut fn_indices = Vec::with_capacity_in(num_elems as usize, arena);
|
let mut fn_indices = Vec::with_capacity_in(num_elems as usize, arena);
|
||||||
for _ in 0..num_elems {
|
for _ in 0..num_elems {
|
||||||
let fn_idx = parse_u32_or_panic(bytes, cursor);
|
let fn_idx = u32::parse((), bytes, cursor).unwrap();
|
||||||
|
|
||||||
fn_indices.push(fn_idx);
|
fn_indices.push(fn_idx);
|
||||||
}
|
}
|
||||||
|
@ -1219,7 +1219,7 @@ impl<'a> OpaqueSection<'a> {
|
||||||
} else {
|
} else {
|
||||||
let section_start = *cursor;
|
let section_start = *cursor;
|
||||||
*cursor += 1;
|
*cursor += 1;
|
||||||
let section_size = parse_u32_or_panic(module_bytes, cursor);
|
let section_size = u32::parse((), module_bytes, cursor).unwrap();
|
||||||
let next_section_start = *cursor + section_size as usize;
|
let next_section_start = *cursor + section_size as usize;
|
||||||
bytes = &module_bytes[section_start..next_section_start];
|
bytes = &module_bytes[section_start..next_section_start];
|
||||||
*cursor = next_section_start;
|
*cursor = next_section_start;
|
||||||
|
@ -1293,7 +1293,7 @@ impl<'a> NameSection<'a> {
|
||||||
*cursor += 1;
|
*cursor += 1;
|
||||||
|
|
||||||
// Section size
|
// Section size
|
||||||
let section_size = parse_u32_or_panic(module_bytes, cursor) as usize;
|
let section_size = u32::parse((), module_bytes, cursor).unwrap() as usize;
|
||||||
let section_end = *cursor + section_size;
|
let section_end = *cursor + section_size;
|
||||||
|
|
||||||
let mut section = NameSection {
|
let mut section = NameSection {
|
||||||
|
@ -1312,7 +1312,7 @@ impl<'a> NameSection<'a> {
|
||||||
cursor: &mut usize,
|
cursor: &mut usize,
|
||||||
section_end: usize,
|
section_end: usize,
|
||||||
) {
|
) {
|
||||||
let section_name = parse_string_bytes(arena, module_bytes, cursor);
|
let section_name = <&'a [u8]>::parse(arena, module_bytes, cursor).unwrap();
|
||||||
if section_name != Self::NAME.as_bytes() {
|
if section_name != Self::NAME.as_bytes() {
|
||||||
internal_error!(
|
internal_error!(
|
||||||
"Expected Custom section {:?}, found {:?}",
|
"Expected Custom section {:?}, found {:?}",
|
||||||
|
@ -1326,7 +1326,7 @@ impl<'a> NameSection<'a> {
|
||||||
for _possible_subsection_id in 0..2 {
|
for _possible_subsection_id in 0..2 {
|
||||||
let subsection_id = module_bytes[*cursor];
|
let subsection_id = module_bytes[*cursor];
|
||||||
*cursor += 1;
|
*cursor += 1;
|
||||||
let subsection_size = parse_u32_or_panic(module_bytes, cursor);
|
let subsection_size = u32::parse((), module_bytes, cursor).unwrap();
|
||||||
if subsection_id == NameSubSections::FunctionNames as u8 {
|
if subsection_id == NameSubSections::FunctionNames as u8 {
|
||||||
found_function_names = true;
|
found_function_names = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1341,12 +1341,11 @@ impl<'a> NameSection<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function names
|
// Function names
|
||||||
let num_entries = parse_u32_or_panic(module_bytes, cursor) as usize;
|
let num_entries = u32::parse((), module_bytes, cursor).unwrap() as usize;
|
||||||
let fn_names_start = *cursor;
|
let fn_names_start = *cursor;
|
||||||
for _ in 0..num_entries {
|
for _ in 0..num_entries {
|
||||||
let fn_index = parse_u32_or_panic(module_bytes, cursor);
|
let fn_index = u32::parse((), module_bytes, cursor).unwrap();
|
||||||
let name_bytes = parse_string_bytes(arena, module_bytes, cursor);
|
let name_bytes = <&'a [u8]>::parse(arena, module_bytes, cursor).unwrap();
|
||||||
|
|
||||||
self.functions
|
self.functions
|
||||||
.insert(arena.alloc_slice_copy(name_bytes), fn_index);
|
.insert(arena.alloc_slice_copy(name_bytes), fn_index);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue