Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions fix/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use parser::Parser;
num_memories!(48);
num_tables!(24);

#[fix_entrypoint]
pub fn _fixpoint_apply(combination: RustHandle<'static>) -> Result<RustHandle<'static>, FixError> {
#[procedure_entrypoint]
pub fn _fixpoint_apply(combination: RustHandle<'static>) -> Result<RustHandle<'static>, Error> {
let arguments = combination.to_entries()?;

let source_handle = arguments.get(1).expect("expected source");
Expand Down
10 changes: 5 additions & 5 deletions fix/parser/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl Parser {
pub fn new(
tokens: Vec<Token>,
environment_handle: &RustHandle<'static>,
) -> Result<Self, FixError> {
) -> Result<Self, Error> {
let mut environment = BTreeMap::new();
for entry in environment_handle.to_entries()? {
let entry = entry.to_entries()?;
Expand All @@ -34,13 +34,13 @@ impl Parser {
})
}

pub fn parse_program(&mut self) -> Result<RustHandle<'static>, FixError> {
pub fn parse_program(&mut self) -> Result<RustHandle<'static>, Error> {
let handle = self.parse_expr()?;
self.expect(&Token::Eof, "expected end of program");
Ok(handle)
}

fn parse_expr(&mut self) -> Result<RustHandle<'static>, FixError> {
fn parse_expr(&mut self) -> Result<RustHandle<'static>, Error> {
Ok(match self.advance() {
Token::String(string) => RustHandle::from_bytes(string.as_bytes())?,
Token::Bytes(bytes) => RustHandle::from_bytes(&bytes)?,
Expand Down Expand Up @@ -68,15 +68,15 @@ impl Parser {
})
}

fn parse_handles(&mut self, close: &Token) -> Result<Vec<RustHandle<'static>>, FixError> {
fn parse_handles(&mut self, close: &Token) -> Result<Vec<RustHandle<'static>>, Error> {
let mut handles = Vec::new();
while !self.matches(close) {
handles.push(self.parse_expr()?);
}
Ok(handles)
}

fn parse_let(&mut self) -> Result<RustHandle<'static>, FixError> {
fn parse_let(&mut self) -> Result<RustHandle<'static>, Error> {
self.expect(&Token::LParen, "expected '(' for let bindings");
let outer_context = self.context.clone();
while self.matches(&Token::LParen) {
Expand Down
2 changes: 1 addition & 1 deletion fix/postprocessor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn process(wasm: &[u8]) -> Result<Vec<u8>> {
RoundtripReencoder.parse_memory_section(&mut memories, section)?;
memory_section = Some(memories);
}
Payload::CustomSection(section) if section.name() == "num_fix_memories" => {
Payload::CustomSection(section) if section.name() == "wasm_num_memories" => {
num_memories = u32::from_le_bytes(section.data().try_into()?);
}
// Don't change other sections
Expand Down
8 changes: 4 additions & 4 deletions fix/utils/build.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
fn main() {
println!("cargo::rerun-if-changed=src/fixpoint.h");
println!("cargo::rerun-if-changed=src/fixpoint.c");
println!("cargo::rerun-if-changed=src/utils.h");
println!("cargo::rerun-if-changed=src/utils.c");

cc::Build::new()
.file("src/fixpoint.c")
.file("src/utils.c")
.include("src")
.flag("-mreference-types")
.opt_level(2)
.compile("fixpoint");
.compile("fixutils");
}
43 changes: 22 additions & 21 deletions fix/utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use core::marker::PhantomData;
use fixhandle::{
BitPack, Blob, BlobName, Encode, Handle, Object, RawName, Ref, Thunk, Tree, TreeName,
};
pub use macros::{fix_entrypoint, num_memories, num_tables};
pub use macros::{num_memories, num_tables, procedure_entrypoint};

pub mod memory;
pub mod table;
Expand All @@ -20,9 +20,9 @@ pub use memory::*;
pub use table::*;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FixError {
AllOcuppied, // All memories/tables occupied
Unavailable, // Resource unavilable
pub enum Error {
AllOccupied, // All memories/tables occupied
Unavailable, // Resource unavailable
GrowFailed, // Memory/Table growth failed
OutOfBounds, // Memory/Table access out of bounds
}
Expand Down Expand Up @@ -70,26 +70,26 @@ impl<'a> RustHandle<'a> {
}

pub fn len(&self) -> usize {
unsafe { fix_len(&self.raw_handle) }
unsafe { util_len(&self.raw_handle) }
}

pub fn is_empty(&self) -> bool {
self.len() == 0
}

pub fn from_bytes(bytes: &[u8]) -> Result<Self, FixError> {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
Memory::from_bytes(bytes)?.to_blob(bytes.len())
}

pub fn from_entries(entries: &[RustHandle<'_>]) -> Result<Self, FixError> {
pub fn from_entries(entries: &[RustHandle<'_>]) -> Result<Self, Error> {
Table::from_entries(entries)?.to_tree(entries.len())
}

pub fn to_bytes(&self) -> Result<Vec<u8>, FixError> {
pub fn to_bytes(&self) -> Result<Vec<u8>, Error> {
Memory::from_blob(*self)?.to_bytes(self.len())
}

pub fn to_entries(&self) -> Result<Vec<RustHandle<'static>>, FixError> {
pub fn to_entries(&self) -> Result<Vec<RustHandle<'static>>, Error> {
Table::from_tree(*self)?.to_entries(self.len())
}
}
Expand Down Expand Up @@ -130,16 +130,17 @@ pub fn create_shallow_encode<'a>(handle: RustHandle<'a>) -> RustHandle<'a> {
}

unsafe extern "C" {
pub fn fix_memory_read(memory_index: u32, destination: u32, length: usize);
pub fn fix_memory_write(memory_index: u32, source: u32, length: usize);
pub fn fix_memory_size(memory_index: u32) -> usize;
pub fn fix_memory_grow(memory_index: u32, num_pages: usize) -> usize;

pub fn fix_table_size(table_index: u32) -> usize;
pub fn fix_table_grow(table_index: u32, entries: usize) -> usize;

pub fn fix_attach_blob(memory_index: u32, handle: *const [u8; 32]);
pub fn fix_attach_tree(table_index: u32, handle: *const [u8; 32]);
pub fn fix_len(handle: *const [u8; 32]) -> usize;
pub fn fix_table_set(table_index: u32, entry_index: usize, handle: *const [u8; 32]);
// Defined with inline assembly
pub fn wasm_memory_read(memory_index: u32, destination: u32, length: usize);
pub fn wasm_memory_write(memory_index: u32, source: u32, length: usize);
pub fn wasm_memory_size(memory_index: u32) -> usize;
pub fn wasm_memory_grow(memory_index: u32, num_pages: usize) -> usize;

pub fn wasm_table_size(table_index: u32) -> usize;
pub fn wasm_table_grow(table_index: u32, entries: usize) -> usize;

pub fn util_attach_blob(memory_index: u32, handle: *const [u8; 32]);
pub fn util_attach_tree(table_index: u32, handle: *const [u8; 32]);
pub fn util_len(handle: *const [u8; 32]) -> usize;
pub fn util_table_set(table_index: u32, entry_index: usize, handle: *const [u8; 32]);
}
64 changes: 32 additions & 32 deletions fix/utils/src/memory.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
use crate::*;

unsafe extern "C" {
fn fix_allocate_memory(index: u16) -> *mut Memory;
static FIX_NUM_MEMORIES: u16;
fn util_allocate_memory(index: u16) -> *mut Memory;
static UTIL_NUM_MEMORIES: u16;
}
static mut POSITION: u16 = 0;
const PAGE_SIZE: usize = 65536;

pub fn fix_next_memory() -> Result<&'static mut Memory, FixError> {
unsafe {
while POSITION < FIX_NUM_MEMORIES {
POSITION += 1;
if let Ok(memory) = Memory::new(POSITION) {
return Ok(memory);
}
}
}
Err(FixError::AllOcuppied)
}

#[repr(transparent)]
pub struct Memory(u16);

impl Memory {
#[doc(hidden)]
pub const EMPTY: Self = Self(0);

pub fn new(index: u16) -> Result<&'static mut Self, FixError> {
let slot = unsafe { fix_allocate_memory(index) };
pub fn new(index: u16) -> Result<&'static mut Self, Error> {
let slot = unsafe { util_allocate_memory(index) };
if slot.is_null() {
return Err(FixError::Unavailable);
return Err(Error::Unavailable);
}
let memory = unsafe { &mut *slot };
memory.0 = index;
Ok(memory)
}

pub fn next() -> Result<&'static mut Self, Error> {
unsafe {
while POSITION < UTIL_NUM_MEMORIES {
POSITION += 1;
if let Ok(memory) = Memory::new(POSITION) {
return Ok(memory);
}
}
}
Err(Error::AllOccupied)
}

/// Calls the fixshell's create_blob function when resolved.
/// Borrows the memory until the handle is consumed.
///
Expand All @@ -55,7 +55,7 @@ impl Memory {
/// The `destination` slice's length must be <= size() * PAGE_SIZE
pub unsafe fn read(&self, destination: &mut [u8]) {
unsafe {
fix_memory_read(
wasm_memory_read(
self.0 as u32,
destination.as_mut_ptr() as u32,
destination.len(),
Expand All @@ -69,7 +69,7 @@ impl Memory {
///
/// The `source` slice's length must be <= size() * PAGE_SIZE
pub unsafe fn write(&mut self, source: &[u8]) {
unsafe { fix_memory_write(self.0 as u32, source.as_ptr() as u32, source.len()) }
unsafe { wasm_memory_write(self.0 as u32, source.as_ptr() as u32, source.len()) }
}

/// Calls the fixshell's attach_blob after resolving the provided `handle`
Expand All @@ -78,51 +78,51 @@ impl Memory {
///
/// `handle` must refer to a blob
pub unsafe fn attach_blob(&mut self, handle: RustHandle<'_>) {
unsafe { fix_attach_blob(self.0 as u32, &handle.raw_handle) }
unsafe { util_attach_blob(self.0 as u32, &handle.raw_handle) }
}

pub fn size(&self) -> usize {
unsafe { fix_memory_size(self.0 as u32) }
unsafe { wasm_memory_size(self.0 as u32) }
}

pub fn grow(&mut self, num_pages: usize) -> usize {
unsafe { fix_memory_grow(self.0 as u32, num_pages) }
unsafe { wasm_memory_grow(self.0 as u32, num_pages) }
}

pub fn from_bytes(bytes: &[u8]) -> Result<&'static mut Self, FixError> {
let memory = fix_next_memory()?;
pub fn from_bytes(bytes: &[u8]) -> Result<&'static mut Self, Error> {
let memory = Memory::next()?;
let mapped = memory.size();
let required = bytes.len().div_ceil(PAGE_SIZE);
if required > mapped && memory.grow(required - mapped) == usize::MAX {
return Err(FixError::GrowFailed);
return Err(Error::GrowFailed);
}
unsafe { memory.write(bytes) };
Ok(memory)
}

pub fn from_blob(handle: RustHandle<'_>) -> Result<&'static mut Self, FixError> {
let memory = fix_next_memory()?;
pub fn from_blob(handle: RustHandle<'_>) -> Result<&'static mut Self, Error> {
let memory = Memory::next()?;
let mapped = memory.size();
let required = handle.len().div_ceil(PAGE_SIZE);
if required > mapped && memory.grow(required - mapped) == usize::MAX {
return Err(FixError::GrowFailed);
return Err(Error::GrowFailed);
}
unsafe { memory.attach_blob(handle) };
Ok(memory)
}

pub fn to_bytes(&self, length: usize) -> Result<Vec<u8>, FixError> {
pub fn to_bytes(&self, length: usize) -> Result<Vec<u8>, Error> {
if length > self.size() * PAGE_SIZE {
return Err(FixError::OutOfBounds);
return Err(Error::OutOfBounds);
}
let mut bytes = alloc::vec![0; length];
unsafe { self.read(&mut bytes) };
Ok(bytes)
}

pub fn to_blob(&self, length: usize) -> Result<RustHandle<'_>, FixError> {
pub fn to_blob(&self, length: usize) -> Result<RustHandle<'_>, Error> {
if length > self.size() * PAGE_SIZE {
return Err(FixError::OutOfBounds);
return Err(Error::OutOfBounds);
}
Ok(unsafe { self.create_blob(length) })
}
Expand Down
Loading
Loading