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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
.build
.fix
fix/wasm/coupon-collector.wat
.vscode
.DS_Store
47 changes: 34 additions & 13 deletions fix/postprocessor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,53 @@ use wasmparser::{Parser, Payload};

pub fn process(wasm: &[u8]) -> Result<Vec<u8>> {
let mut module = Module::new();
let mut num_memories: u32 = 0;
let mut memory_section: Option<MemorySection> = None;
// Sections that come after memory_section
let mut trailing_sections = Vec::new();

for payload in Parser::new(0).parse_all(wasm) {
match payload? {
Payload::MemorySection(section) => {
let mut memory_section = MemorySection::new();
RoundtripReencoder.parse_memory_section(&mut memory_section, section)?;
// Inject one hardcoded memory
memory_section.memory(MemoryType {
minimum: 1,
maximum: None,
memory64: false,
shared: false,
page_size_log2: None,
});
module.section(&memory_section);
let mut memories = MemorySection::new();
RoundtripReencoder.parse_memory_section(&mut memories, section)?;
memory_section = Some(memories);
}
Payload::CustomSection(section) if section.name() == "num_fix_memories" => {
num_memories = u32::from_le_bytes(section.data().try_into()?);
}
// Don't change other sections
payload => {
if let Some((id, range)) = payload.as_section() {
module.section(&RawSection {
let section = RawSection {
id,
data: &wasm[range],
});
};
if memory_section.is_some() {
trailing_sections.push(section);
} else {
module.section(&section);
}
}
}
}
}

if let Some(mut mem_section) = memory_section {
for _ in 0..num_memories {
mem_section.memory(MemoryType {
minimum: 1,
maximum: None,
memory64: false,
shared: false,
page_size_log2: None,
});
}
module.section(&mem_section);
}
for section in trailing_sections {
module.section(&section);
}

Ok(module.finish())
}
33 changes: 18 additions & 15 deletions fix/procedure/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
#![cfg_attr(target_arch = "wasm32", no_std)]
#![cfg_attr(target_arch = "wasm32", no_std, feature(asm_experimental_arch))]
use dlmalloc::GlobalDlmalloc;
#[global_allocator]
static ALLOCATOR: GlobalDlmalloc = GlobalDlmalloc;
use fixutils::*;

extern crate alloc;
use alloc::vec::Vec;
num_memories!(1);
num_tables!(1);

const HELLO: &[u8] = b"hello";
const WORLD: &[u8] = b" world";

#[fix_entrypoint]
pub fn _fixpoint_apply(_combination: RustHandle) -> RustHandle {
unsafe {
let mut blob: Vec<u8> = HELLO.to_vec();
memory_1_write(blob.as_ptr() as u32, blob.len());
let handle = create_blob(1, blob.len());
attach_blob(1, &handle);
memory_1_read(blob.as_mut_ptr() as u32, len(&handle));
blob.append(&mut WORLD.to_vec());
memory_1_write(blob.as_ptr() as u32, blob.len());
create_blob(1, blob.len())
}
pub fn _fixpoint_apply(combination: RustHandle<'static>) -> RustHandle<'static> {
let memory_1 = Memory::new(1).expect("expected 1 memory");
let table_1 = Table::new(1).expect("expected 1 table");

let num_entries = combination.len();
table_1.attach_tree(combination);
table_1.grow(1);

memory_1.write(HELLO);
let blob = memory_1.create_blob(HELLO.len());
table_1.set(num_entries, blob);

create_strict_encode(create_identification_thunk(
table_1.create_tree(num_entries + 1),
))
}
58 changes: 49 additions & 9 deletions fix/shell/src/fixpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub unsafe extern "C" fn w2c_fixpoint_attach_tree(
table_idx: u32,
handle: wasm_rt_externref_t,
) {
assert!(table_idx < 63);
assert!(table_idx < 32);
unsafe {
let table = crate::rt::TABLES[table_idx as usize];
if (table.is_null()) {
Expand All @@ -50,15 +50,15 @@ pub unsafe extern "C" fn w2c_fixpoint_attach_tree(
pub unsafe extern "C" fn w2c_fixpoint_create_tree(
fixpoint: *mut w2c_fixpoint,
table_idx: u32,
length: u32,
) -> wasm_rt_externref_t {
assert!(table_idx < 63);
assert!(table_idx < 32);
unsafe {
let table = crate::rt::TABLES[table_idx as usize];
let addr = (1usize << 32) * (64 + table_idx as usize);
wasm_rt_externref_t {
bytes: shell::fixpoint_create_tree(core::slice::from_raw_parts(
addr as *const u8,
(*table).size as usize,
(*table).data.cast::<u8>(),
length as usize * 32,
)),
}
}
Expand All @@ -68,15 +68,15 @@ pub unsafe extern "C" fn w2c_fixpoint_create_tree(
pub unsafe extern "C" fn w2c_fixpoint_create_tag(
fixpoint: *mut w2c_fixpoint,
table_idx: u32,
length: u32,
) -> wasm_rt_externref_t {
assert!(table_idx < 63);
assert!(table_idx < 32);
unsafe {
let table = crate::rt::TABLES[table_idx as usize];
let addr = (1usize << 32) * (64 + table_idx as usize);
wasm_rt_externref_t {
bytes: shell::fixpoint_create_tag(core::slice::from_raw_parts(
addr as *const u8,
(*table).size as usize,
(*table).data.cast::<u8>(),
length as usize * 32,
)),
}
}
Expand Down Expand Up @@ -161,6 +161,26 @@ pub unsafe extern "C" fn w2c_fixpoint_is_equal(
shell::fixpoint_is_equal(lhs.bytes, rhs.bytes) as i32
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn w2c_fixpoint_create_ref(
fixpoint: *mut w2c_fixpoint,
handle: wasm_rt_externref_t,
) -> wasm_rt_externref_t {
wasm_rt_externref_t {
bytes: shell::fixpoint_create_ref(handle.bytes),
}
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn w2c_fixpoint_create_identification_thunk(
fixpoint: *mut w2c_fixpoint,
handle: wasm_rt_externref_t,
) -> wasm_rt_externref_t {
wasm_rt_externref_t {
bytes: shell::fixpoint_create_identification_thunk(handle.bytes),
}
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn w2c_fixpoint_create_application_thunk(
fixpoint: *mut w2c_fixpoint,
Expand All @@ -171,6 +191,16 @@ pub unsafe extern "C" fn w2c_fixpoint_create_application_thunk(
}
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn w2c_fixpoint_create_selection_thunk(
fixpoint: *mut w2c_fixpoint,
handle: wasm_rt_externref_t,
) -> wasm_rt_externref_t {
wasm_rt_externref_t {
bytes: shell::fixpoint_create_selection_thunk(handle.bytes),
}
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn w2c_fixpoint_create_strict_encode(
fixpoint: *mut w2c_fixpoint,
Expand All @@ -181,6 +211,16 @@ pub unsafe extern "C" fn w2c_fixpoint_create_strict_encode(
}
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn w2c_fixpoint_create_shallow_encode(
fixpoint: *mut w2c_fixpoint,
handle: wasm_rt_externref_t,
) -> wasm_rt_externref_t {
wasm_rt_externref_t {
bytes: shell::fixpoint_create_shallow_encode(handle.bytes),
}
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn w2c_fixpoint_len(
fixpoint: *mut w2c_fixpoint,
Expand Down
26 changes: 20 additions & 6 deletions fix/shell/src/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

use core::sync::atomic::{AtomicUsize, Ordering};
use core::{
slice::from_raw_parts_mut,
sync::atomic::{AtomicUsize, Ordering},
};

use arcane::{__MODE_read_write, arca_compat_mmap};
use user::error;
Expand All @@ -16,7 +19,7 @@ unsafe extern "C" {
}

pub static mut MEMORY_IDX: usize = 0;
pub static mut TABLE_IDX: usize = 0;
pub static mut TABLE_IDX: usize = 1;
pub static mut FUNCREF_TABLE_IDX: usize = 0;

pub static mut MEMORIES: [*mut wasm_rt_memory_t; 64] = [core::ptr::null_mut(); 64];
Expand Down Expand Up @@ -113,7 +116,11 @@ pub extern "C" fn wasm_rt_allocate_externref_table(
max_elements = 1 << (32 - 5);
}
let data = ((1 << 32) * (64 + idx)) as *mut u8;
arca_compat_mmap(data as *mut _, (elements * 32) as usize, __MODE_read_write);
arca_compat_mmap(
data as *mut _,
(elements * 32).next_multiple_of(PAGE_SIZE) as usize,
__MODE_read_write,
);
table.write(wasm_rt_externref_table_t {
data: data as *mut _,
size: elements,
Expand All @@ -134,10 +141,17 @@ pub extern "C" fn wasm_rt_grow_externref_table(
return u32::MAX;
}

let start = unsafe { table.data.byte_add(current as usize * 32) };
let size = delta * 32;
let mapped = (current * 32).next_multiple_of(PAGE_SIZE) as usize;
let required = ((current + delta) * 32).next_multiple_of(PAGE_SIZE) as usize;
unsafe {
arca_compat_mmap(start as *mut _, size as usize, __MODE_read_write);
if required > mapped {
arca_compat_mmap(
table.data.byte_add(mapped) as *mut _,
required - mapped,
__MODE_read_write,
);
}
from_raw_parts_mut(table.data.add(current as usize), delta as usize).fill(init);
table.size += delta;
}
current
Expand Down
40 changes: 38 additions & 2 deletions fix/shell/src/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use core::ffi::c_void;
use fixhandle::*;

use user::ArcaError;
use user::Ref;
use user::Runtime;
use user::error::log as arca_log;
use user::error::log_int as arca_log_int;
Expand Down Expand Up @@ -242,19 +241,56 @@ pub fn fixpoint_is_equal(lhs: [u8; 32], rhs: [u8; 32]) -> bool {
result == 1
}

pub fn fixpoint_create_ref(handle: [u8; 32]) -> [u8; 32] {
Handle::Ref(match Handle::unpack(handle) {
Handle::Object(Object::Blob(blob)) => Ref::Blob(blob),
Handle::Object(Object::Tree(tree)) => Ref::Tree(tree),
_ => {
arca_log("create_ref: handle does not refer to an Object");
panic!()
}
})
.pack()
}

pub fn fixpoint_create_identification_thunk(handle: [u8; 32]) -> [u8; 32] {
let reference = match Handle::unpack(handle) {
Handle::Ref(reference) => reference,
Handle::Object(Object::Blob(blob)) => Ref::Blob(blob),
Handle::Object(Object::Tree(tree)) => Ref::Tree(tree),
_ => {
arca_log("create_identification_thunk: handle does not refer to an Object or Ref");
panic!()
}
};
let thunk: Handle = Thunk::Identification(reference).into();
thunk.pack()
}

pub fn fixpoint_create_application_thunk(handle: [u8; 32]) -> [u8; 32] {
let handle = Handle::unpack(handle);
// TODO: handle refs
let thunk: Handle = Thunk::Application(handle.unwrap_object().unwrap_tree()).into();
thunk.pack()
}

pub fn fixpoint_create_selection_thunk(handle: [u8; 32]) -> [u8; 32] {
let handle = Handle::unpack(handle);
let thunk: Handle = Thunk::Selection(handle.unwrap_object().unwrap_tree()).into();
thunk.pack()
}

pub fn fixpoint_create_strict_encode(handle: [u8; 32]) -> [u8; 32] {
let handle = Handle::unpack(handle);
let encode: Handle = Encode::Strict(handle.unwrap_thunk()).into();
encode.pack()
}

pub fn fixpoint_create_shallow_encode(handle: [u8; 32]) -> [u8; 32] {
let handle = Handle::unpack(handle);
let encode: Handle = Encode::Shallow(handle.unwrap_thunk()).into();
encode.pack()
}

pub fn fixpoint_len(handle: [u8; 32]) -> usize {
let handle = Handle::unpack(handle);
handle.len()
Expand Down
3 changes: 2 additions & 1 deletion fix/src/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ impl<R: Runtime> Evaluator<R> {
match thought {
Handle::Object(_) => thought,
Handle::Ref(_) => self.lift(thought),
Handle::Thunk(_) | Handle::Encode(_) => todo!(),
Handle::Thunk(thunk) => self.force(thunk),
Handle::Encode(encode) => self.lift(self.encode(encode)),
}
}

Expand Down
2 changes: 2 additions & 0 deletions fix/utils/build.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
fn main() {
println!("cargo::rerun-if-changed=src/fixpoint.h");
println!("cargo::rerun-if-changed=src/fixpoint.c");

cc::Build::new()
.file("src/fixpoint.c")
.include("src")
.flag("-mreference-types")
.opt_level(2)
.compile("fixpoint");
Expand Down
Loading
Loading