mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
Memory and Global sections
This commit is contained in:
parent
e05ef73f6c
commit
2a0dbb39fb
2 changed files with 70 additions and 12 deletions
|
@ -2,6 +2,7 @@ use bumpalo::collections::vec::Vec;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
|
||||||
use crate::code_builder::{Align, ValueType};
|
use crate::code_builder::{Align, ValueType};
|
||||||
|
use crate::opcodes;
|
||||||
use crate::serialize::{SerialBuffer, Serialize};
|
use crate::serialize::{SerialBuffer, Serialize};
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
|
@ -58,7 +59,7 @@ fn write_custom_section_header<T: SerialBuffer>(
|
||||||
buffer: &mut T,
|
buffer: &mut T,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> SectionHeaderIndices {
|
) -> SectionHeaderIndices {
|
||||||
buffer.append_u8(SectionId::Custom as u8);
|
// buffer.append_u8(SectionId::Custom as u8);
|
||||||
let size_index = buffer.reserve_padded_u32();
|
let size_index = buffer.reserve_padded_u32();
|
||||||
let body_index = buffer.size();
|
let body_index = buffer.size();
|
||||||
name.serialize(buffer);
|
name.serialize(buffer);
|
||||||
|
@ -289,28 +290,43 @@ enum Limits {
|
||||||
|
|
||||||
impl Serialize for Limits {
|
impl Serialize for Limits {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
todo!();
|
match self {
|
||||||
|
Self::Min(min) => {
|
||||||
|
buffer.append_u8(0);
|
||||||
|
buffer.encode_u32(*min);
|
||||||
|
}
|
||||||
|
Self::MinMax(min, max) => {
|
||||||
|
buffer.append_u8(1);
|
||||||
|
buffer.encode_u32(*min);
|
||||||
|
buffer.encode_u32(*max);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MemorySection {
|
pub struct MemorySection(Option<Limits>);
|
||||||
/// number of 64kB pages
|
|
||||||
num_pages: Limits,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MemorySection {
|
impl MemorySection {
|
||||||
const PAGE_SIZE_KB: u32 = 64;
|
pub const PAGE_SIZE: u32 = 64 * 1024;
|
||||||
|
|
||||||
pub fn new(kb: u32) -> Self {
|
pub fn new(bytes: u32) -> Self {
|
||||||
MemorySection {
|
if bytes == 0 {
|
||||||
num_pages: Limits::Min(kb / Self::PAGE_SIZE_KB),
|
MemorySection(None)
|
||||||
|
} else {
|
||||||
|
let pages = (bytes + Self::PAGE_SIZE - 1) / Self::PAGE_SIZE;
|
||||||
|
MemorySection(Some(Limits::Min(pages)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for MemorySection {
|
impl Serialize for MemorySection {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
todo!();
|
if let Some(limits) = &self.0 {
|
||||||
|
let header_indices = write_section_header(buffer, SectionId::Memory);
|
||||||
|
buffer.append_u8(1);
|
||||||
|
limits.serialize(buffer);
|
||||||
|
update_section_size(buffer, header_indices);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +362,25 @@ struct Global {
|
||||||
|
|
||||||
impl Serialize for Global {
|
impl Serialize for Global {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
todo!();
|
self.ty.serialize(buffer);
|
||||||
|
match self.init_value {
|
||||||
|
GlobalInitValue::I32(x) => {
|
||||||
|
buffer.append_u8(opcodes::I32CONST);
|
||||||
|
buffer.encode_i32(x);
|
||||||
|
}
|
||||||
|
GlobalInitValue::I64(x) => {
|
||||||
|
buffer.append_u8(opcodes::I64CONST);
|
||||||
|
buffer.encode_i64(x);
|
||||||
|
}
|
||||||
|
GlobalInitValue::F32(x) => {
|
||||||
|
buffer.append_u8(opcodes::F32CONST);
|
||||||
|
buffer.encode_f32(x);
|
||||||
|
}
|
||||||
|
GlobalInitValue::F64(x) => {
|
||||||
|
buffer.append_u8(opcodes::F64CONST);
|
||||||
|
buffer.encode_f64(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,30 @@ impl Serialize for u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: Serialize> Serialize for [S] {
|
||||||
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
|
buffer.encode_u32(self.len() as u32);
|
||||||
|
for item in self.iter() {
|
||||||
|
item.serialize(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: Serialize> Serialize for Option<S> {
|
||||||
|
/// serialize Option as a vector of length 1 or 0
|
||||||
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
|
match self {
|
||||||
|
Some(x) => {
|
||||||
|
buffer.append_u8(1);
|
||||||
|
x.serialize(buffer);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
buffer.append_u8(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn overwrite_padded_u32_help(buffer: &mut [u8], value: u32) {
|
fn overwrite_padded_u32_help(buffer: &mut [u8], value: u32) {
|
||||||
let mut x = value;
|
let mut x = value;
|
||||||
for byte in buffer.iter_mut().take(4) {
|
for byte in buffer.iter_mut().take(4) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue