Skip to content

Commit

Permalink
support stable compiler (#135)
Browse files Browse the repository at this point in the history
  • Loading branch information
tjjfvi authored May 28, 2024
1 parent d0261e0 commit c18425e
Show file tree
Hide file tree
Showing 16 changed files with 50 additions and 62 deletions.
4 changes: 2 additions & 2 deletions ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ mod parser;
use alloc::collections::BTreeMap;

use crate::prelude::*;
use hvm64_util::{create_var, deref, maybe_grow, multi_iterator, ops::TypedOp as Op, var_to_num};
use hvm64_util::{create_var, deref_to, maybe_grow, multi_iterator, ops::TypedOp as Op, var_to_num};

use ordered_float::OrderedFloat;

Expand All @@ -34,7 +34,7 @@ pub struct Book {
pub nets: BTreeMap<String, Net>,
}

deref!(Book => self.nets: BTreeMap<String, Net>);
deref_to!(Book => self.nets: BTreeMap<String, Net>);

/// An AST node representing an interaction net with one free port.
///
Expand Down
3 changes: 1 addition & 2 deletions host/src/host.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! The runtime's host, which acts as a translation layer between the AST and
//! the runtime.
#![cfg_attr(not(feature = "std"), no_std)]
#![feature(inline_const)]

include!("../../prelude.rs");

Expand Down Expand Up @@ -83,6 +82,6 @@ impl Host {

/// Returns a mutable [`Def`] named `name`.
pub fn get_mut<T: Send + Sync + 'static>(&mut self, name: &str) -> &mut Def<T> {
self.defs.get_mut(name).unwrap().downcast_mut().unwrap()
Def::downcast_mut(self.defs.get_mut(name).unwrap()).unwrap()
}
}
32 changes: 13 additions & 19 deletions runtime/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub struct Allocator<'h> {
pub(super) head: Addr,
}

deref!({<'h>} Allocator<'h> => self.tracer: Tracer);
deref_to!({<'h>} Allocator<'h> => self.tracer: Tracer);

impl<'h> Allocator<'h> {
pub fn new(heap: &'h Heap) -> Self {
Expand All @@ -73,24 +73,18 @@ impl<'h> Allocator<'h> {
pub fn half_free(&mut self, addr: Addr) {
trace!(self.tracer, addr);
const FREE: u64 = Port::FREE.0;
if cfg!(feature = "_fuzz") {
if cfg!(not(feature = "_fuzz_no_free")) {
assert_ne!(addr.val().swap(FREE, Relaxed), FREE, "double free");
}
} else {
addr.val().store(FREE, Relaxed);
if addr.other_half().val().load(Relaxed) == FREE {
trace!(self.tracer, "other free");
let addr = addr.left_half();
if addr.val().compare_exchange(FREE, self.head.0 as u64, Relaxed, Relaxed).is_ok() {
let old_head = &self.head;
let new_head = addr;
trace!(self.tracer, "appended", old_head, new_head);
self.head = new_head;
} else {
trace!(self.tracer, "too slow");
};
}
addr.val().store(FREE, Relaxed);
if addr.other_half().val().load(Relaxed) == FREE {
trace!(self.tracer, "other free");
let addr = addr.left_half();
if addr.val().compare_exchange(FREE, self.head.0 as u64, Relaxed, Relaxed).is_ok() {
let old_head = &self.head;
let new_head = addr;
trace!(self.tracer, "appended", old_head, new_head);
self.head = new_head;
} else {
trace!(self.tracer, "too slow");
};
}
}

Expand Down
26 changes: 12 additions & 14 deletions runtime/src/def.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use hvm64_util::new_uninit_slice;

use super::*;

/// A bitset representing the set of labels used in a def.
Expand Down Expand Up @@ -94,14 +96,10 @@ pub struct Def<T: ?Sized + Send + Sync = Dynamic> {

pub type DynDef = dyn DerefMut<Target = Def> + Send + Sync;

extern "C" {
/// An internal type used to mark dynamic `Def`s.
///
/// Because this is an `extern type`, it is unsized, but has zero metadata.
/// This is essentially a workaround for the lack of custom DSTs.
#[doc(hidden)]
pub type Dynamic;
}
/// An internal type used to mark dynamic `Def`s.
///
/// This should be unsized, but there is no stable way to do this at the moment.
pub struct Dynamic(());

unsafe impl Send for Dynamic {}
unsafe impl Sync for Dynamic {}
Expand All @@ -111,7 +109,7 @@ pub trait AsDef: Any + Send + Sync {
}

impl<T: Send + Sync> Def<T> {
pub const fn new(labs: LabSet, data: T) -> Self
pub fn new(labs: LabSet, data: T) -> Self
where
T: AsDef,
{
Expand All @@ -132,11 +130,11 @@ impl<T: Send + Sync> Def<T> {
impl Def {
#[inline(always)]
pub unsafe fn downcast_ptr<T: Send + Sync + 'static>(slf: *const Def) -> Option<*const Def<T>> {
if (*slf).ty == TypeId::of::<T>() { Some(slf.cast()) } else { None }
if (*slf).ty == TypeId::of::<T>() { Some(slf as *const Def<T>) } else { None }
}
#[inline(always)]
pub unsafe fn downcast_mut_ptr<T: Send + Sync + 'static>(slf: *mut Def) -> Option<*mut Def<T>> {
if (*slf).ty == TypeId::of::<T>() { Some(slf.cast()) } else { None }
if (*slf).ty == TypeId::of::<T>() { Some(slf as *mut Def<T>) } else { None }
}
#[inline(always)]
pub fn downcast_ref<T: Send + Sync + 'static>(&self) -> Option<&Def<T>> {
Expand All @@ -156,14 +154,14 @@ impl<T: Send + Sync> Deref for Def<T> {
type Target = Def;
#[inline(always)]
fn deref(&self) -> &Self::Target {
self.upcast()
Def::upcast(self)
}
}

impl<T: Send + Sync> DerefMut for Def<T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
self.upcast_mut()
Def::upcast_mut(self)
}
}

Expand Down Expand Up @@ -222,7 +220,7 @@ impl AsDef for InterpretedDef {
let instructions = &def.instr;

if def.trgs >= net.trgs.len() {
net.trgs = Box::new_uninit_slice(def.trgs);
net.trgs = new_uninit_slice(def.trgs);
}

let mut trgs = Trgs(&mut net.trgs[..] as *mut _ as *mut _);
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct Linker<'h> {
pub redexes: RedexQueue,
}

deref!({<'h, >} Linker<'h> => self.allocator: Allocator<'h>);
deref_to!({<'h, >} Linker<'h> => self.allocator: Allocator<'h>);

impl<'h> Linker<'h> {
pub fn new(heap: &'h Heap) -> Self {
Expand Down
5 changes: 3 additions & 2 deletions runtime/src/net.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;

use hvm64_util::new_uninit_slice;
use mem::MaybeUninit;

/// An interaction combinator net.
Expand All @@ -11,7 +12,7 @@ pub struct Net<'a> {
pub root: Wire,
}

deref!({<'a, >} Net<'a> => self.linker: Linker<'a>);
deref_to!({<'a, >} Net<'a> => self.linker: Linker<'a>);

impl<'h> Net<'h> {
/// Creates an empty net with a given heap.
Expand All @@ -22,7 +23,7 @@ impl<'h> Net<'h> {
}

pub(super) fn new_with_root(heap: &'h Heap, root: Wire) -> Self {
Net { linker: Linker::new(heap), tid: 0, tids: 1, trgs: Box::new_uninit_slice(1 << 16), root }
Net { linker: Linker::new(heap), tid: 0, tids: 1, trgs: new_uninit_slice(1 << 16), root }
}

/// Boots a net from a Def.
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/parallel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl<'h> Net<'h> {
(0 .. tids).map(move |tid| {
let heap_size = (heap.0.len() / tids) & !63; // round down to needed alignment
let heap_start = heap_size * tid;
let area = unsafe { mem::transmute(&heap.0[heap_start .. heap_start + heap_size]) };
let area = unsafe { mem::transmute::<&[Node], &Heap>(&heap.0[heap_start .. heap_start + heap_size]) };
let mut net = Net::new_with_root(area, root.clone());
net.next = next.saturating_sub(heap_start);
net.head = if tid == 0 { net.head } else { Addr::NULL };
Expand Down
3 changes: 1 addition & 2 deletions runtime/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
//! the *auxiliary ports* of the net (as managed by the linker); the target of
//! the principal port is left implicit
//! - active pairs are thus stored in a dedicated vector, `net.redexes`
#![feature(const_type_id, extern_types, inline_const, new_uninit)]
#![cfg_attr(feature = "trace", feature(const_type_name))]
#![cfg_attr(not(feature = "std"), no_std)]

Expand All @@ -27,7 +26,7 @@ use crate::prelude::*;

pub use hvm64_util::ops;

use hvm64_util::{bi_enum, deref, pretty_num};
use hvm64_util::{bi_enum, deref_to, pretty_num};

use self::trace::Tracer;
use alloc::borrow::Cow;
Expand Down
3 changes: 0 additions & 3 deletions runtime/src/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,6 @@ impl TraceWriter {
self.lock.locked.store(false, Ordering::Release);
}
fn trace<S: TraceSourceBearer, A: TraceArgs>(&mut self, args: A) {
if cfg!(feature = "_fuzz") {
self.sync();
}
let meta: &'static _ = &TraceMetadata { source: S::SOURCE, arg_fmts: A::FMTS };
self.acquire(|data| {
let nonce = self.nonce;
Expand Down
13 changes: 0 additions & 13 deletions runtime/src/wire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,12 @@ impl Wire {

#[inline(always)]
fn target<'a>(&self) -> &'a AtomicU64 {
if cfg!(feature = "_fuzz") {
assert_ne!(self.0 as usize, 0xfffffffffff0u64 as usize);
assert_ne!(self.0 as usize, 0);
}
unsafe { &*self.0 }
}

#[inline(always)]
pub fn load_target(&self) -> Port {
let port = Port(self.target().load(Relaxed));
if cfg!(feature = "_fuzz") {
assert_ne!(port, Port::FREE);
}
port
}

Expand All @@ -66,9 +59,6 @@ impl Wire {
#[inline(always)]
pub fn swap_target(&self, value: Port) -> Port {
let port = Port(self.target().swap(value.0, Relaxed));
if cfg!(feature = "_fuzz") {
assert_ne!(port, Port::FREE);
}
port
}

Expand All @@ -77,9 +67,6 @@ impl Wire {
pub fn lock_target(&self) -> Port {
loop {
let got = self.swap_target(Port::LOCK);
if cfg!(feature = "_fuzz") {
assert_ne!(got, Port::FREE);
}
if got != Port::LOCK {
return got;
}
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
profile = "minimal"
channel = "nightly-2024-01-27"
channel = "nightly-2024-05-28"
components = ["rustfmt", "clippy"]
2 changes: 1 addition & 1 deletion src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn _compile_host(host: &Host) -> Result<String, fmt::Error> {

let mut def_infos: BTreeMap<&str, DefInfo<'_>> = BTreeMap::new();
for (hvm64_name, def) in &host.defs {
if let Some(def) = def.downcast_ref::<InterpretedDef>() {
if let Some(def) = Def::downcast_ref::<InterpretedDef>(def) {
def_infos.insert(hvm64_name, DefInfo {
rust_name: sanitize_name(hvm64_name),
refs: refs(host, def.data.instructions()),
Expand Down
1 change: 1 addition & 0 deletions src/compile/include_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ hvm64-runtime = { path = "../runtime", default-features = false }
bi_enum
create_var
deref
new_uninit_slice
maybe_grow
multi_iterator
ops {
Expand Down
2 changes: 1 addition & 1 deletion util/src/deref.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[macro_export]
macro_rules! deref {
macro_rules! deref_to {
($({$($gen:tt)*})? $ty:ty => self.$field:ident: $trg:ty) => {
impl $($($gen)*)? core::ops::Deref for $ty {
type Target = $trg;
Expand Down
2 changes: 2 additions & 0 deletions util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ mod multi_iterator;

mod create_var;
mod maybe_grow;
mod new_uninit_slice;
mod parse_abbrev_number;
mod pretty_num;

pub use create_var::*;
pub use maybe_grow::*;
pub use new_uninit_slice::*;
pub use parse_abbrev_number::*;
pub use pretty_num::*;
10 changes: 10 additions & 0 deletions util/src/new_uninit_slice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use alloc::alloc::alloc;
use core::{alloc::Layout, mem::MaybeUninit, slice};

use crate::prelude::*;

// TODO: use `Box::new_uninit_slice` once stabilized
// https://github.com/rust-lang/rust/issues/63291
pub fn new_uninit_slice<T>(len: usize) -> Box<[MaybeUninit<T>]> {
unsafe { Box::from_raw(slice::from_raw_parts_mut(alloc(Layout::array::<T>(len).unwrap()).cast(), len)) }
}

0 comments on commit c18425e

Please sign in to comment.