Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support stable compiler #135

Merged
merged 4 commits into from
May 28, 2024
Merged
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 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)) }
}
Loading