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

remove lazy mode #132

Closed
wants to merge 2 commits into from
Closed
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
7 changes: 0 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
"monomorphized",
"newtype",
"nilary",
"nohash",
"nomicon",
"oper",
"outdir",
Expand Down
8 changes: 4 additions & 4 deletions host/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::prelude::*;

use crate::Host;
use hvm64_ast::{Lab, Net as AstNet, Tree};
use hvm64_runtime::{Instruction, InterpretedDef, Mode, Net, Port, Trg, TrgId};
use hvm64_runtime::{Instruction, InterpretedDef, Net, Port, Trg, TrgId};
use hvm64_util::{maybe_grow, ops::TypedOp as Op};

impl Host {
Expand All @@ -19,15 +19,15 @@ impl Host {

/// Encode `tree` directly into `trg`, skipping the intermediate `Def`
/// representation.
pub fn encode_tree<M: Mode>(&self, net: &mut Net<M>, trg: Trg, tree: &Tree) {
pub fn encode_tree(&self, net: &mut Net, trg: Trg, tree: &Tree) {
let mut state = State { host: self, encoder: net, scope: Default::default() };
state.visit_tree(tree, trg);
state.finish();
}

/// Encode the root of `ast_net` directly into `trg` and encode its redexes
/// into `net` redex list.
pub fn encode_net<M: Mode>(&self, net: &mut Net<M>, trg: Trg, ast_net: &AstNet) {
pub fn encode_net(&self, net: &mut Net, trg: Trg, ast_net: &AstNet) {
let mut state = State { host: self, encoder: net, scope: Default::default() };
state.visit_net(ast_net, trg);
state.finish();
Expand Down Expand Up @@ -193,7 +193,7 @@ impl Encoder for InterpretedDef {
}
}

impl<'a, M: Mode> Encoder for Net<'a, M> {
impl<'a> Encoder for Net<'a> {
type Trg = Trg;

fn link_const(&mut self, trg: Self::Trg, port: Port) {
Expand Down
2 changes: 1 addition & 1 deletion host/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ include!("../../prelude.rs");

use crate::prelude::*;
use hvm64_ast::{Book, Tree};
use hvm64_runtime::{Addr, Def, InterpretedDef, LabSet, Mode, Port, Tag, Wire};
use hvm64_runtime::{Addr, Def, InterpretedDef, LabSet, Port, Tag, Wire};

use core::ops::{Deref, DerefMut};

Expand Down
4 changes: 2 additions & 2 deletions host/src/readback.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::prelude::*;

use super::{Addr, Host, Mode, Port, Tag, Wire};
use super::{Addr, Host, Port, Tag, Wire};

use core::ops::RangeFrom;

Expand All @@ -19,7 +19,7 @@ impl Host {
/// resulting ast net, as it is impossible to read these back from the runtime
/// net representation. In the case of vicious circles, this may result in
/// unbound variables.
pub fn readback<M: Mode>(&self, rt_net: &hvm64_runtime::Net<M>) -> Net {
pub fn readback(&self, rt_net: &hvm64_runtime::Net) -> Net {
let mut state = ReadbackState { host: self, vars: Default::default(), var_id: 0 .. };
let mut net = Net::default();

Expand Down
78 changes: 34 additions & 44 deletions host/src/stdlib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ use parking_lot::Mutex;

use crate::{DefRef, Host};
use hvm64_ast::Tree;
use hvm64_runtime::{dispatch_dyn_net, AsDef, Def, DynNetMut, LabSet, Mode, Net, Port, Tag, Trg};
use hvm64_runtime::{AsDef, Def, LabSet, Net, Port, Tag, Trg};
use hvm64_util::create_var;

/// `@IDENTITY = (x x)`
pub const IDENTITY: *const Def = const { &Def::new(LabSet::from_bits(&[1]), (call_identity, call_identity)) }.upcast();
pub const IDENTITY: *const Def = const { &Def::new(LabSet::from_bits(&[1]), call_identity) }.upcast();

fn call_identity<M: Mode>(net: &mut Net<M>, port: Port) {
fn call_identity(net: &mut Net, port: Port) {
let (a, b) = net.do_ctr(0, Trg::port(port));
net.link_trg(a, b);
}
Expand All @@ -41,7 +41,7 @@ impl<F: Fn(Tree) + Clone + Send + Sync + 'static> LogDef<F> {
pub struct LogDef<F>(Arc<Mutex<Host>>, F);

impl<F: Fn(Tree) + Clone + Send + Sync + 'static> AsHostedDef for LogDef<F> {
fn call<M: Mode>(def: &Def<Self>, net: &mut Net<M>, port: Port) {
fn call(def: &Def<Self>, net: &mut Net, port: Port) {
let (arg, seq) = net.do_ctr(0, Trg::port(port));
let seq = net.wire_to_trg(seq);
// SAFETY: the function inside `readback` won't live longer than
Expand All @@ -50,9 +50,7 @@ impl<F: Fn(Tree) + Clone + Send + Sync + 'static> AsHostedDef for LogDef<F> {
let def: &'static Def<Self> = unsafe { mem::transmute(def) };
readback(net, def.data.0.clone(), arg, |net, tree| {
(def.data.1)(tree);
dispatch_dyn_net!(net => {
net.link_wire_port(seq, Port::new_ref(unsafe { &*IDENTITY }));
});
net.link_wire_port(seq, Port::new_ref(unsafe { &*IDENTITY }));
});
}
}
Expand Down Expand Up @@ -102,11 +100,11 @@ impl<T: AsBoxDef> BoxDef<T> {
}

pub trait AsBoxDef: Send + Sync + 'static {
fn call<M: Mode>(slf: Box<Def<Self>>, net: &mut Net<M>, port: Port);
fn call(slf: Box<Def<Self>>, net: &mut Net, port: Port);
}

impl<T: AsBoxDef> AsDef for BoxDef<T> {
unsafe fn call<M: Mode>(slf: *const Def<Self>, net: &mut Net<M>, port: Port) {
unsafe fn call(slf: *const Def<Self>, net: &mut Net, port: Port) {
T::call(Box::from_raw(slf as *mut _), net, port)
}
}
Expand Down Expand Up @@ -136,11 +134,11 @@ impl<T: AsArcDef> ArcDef<T> {
}

pub trait AsArcDef: Send + Sync + 'static {
fn call<M: Mode>(slf: Arc<Def<Self>>, net: &mut Net<M>, port: Port);
fn call(slf: Arc<Def<Self>>, net: &mut Net, port: Port);
}

impl<T: AsArcDef> AsDef for ArcDef<T> {
unsafe fn call<M: Mode>(slf: *const Def<Self>, net: &mut Net<M>, port: Port) {
unsafe fn call(slf: *const Def<Self>, net: &mut Net, port: Port) {
T::call(Arc::from_raw(slf as *mut _), net, port);
}
}
Expand All @@ -162,11 +160,11 @@ impl<T: AsHostedDef> HostedDef<T> {
}

pub trait AsHostedDef: Send + Sync + 'static {
fn call<M: Mode>(slf: &Def<Self>, net: &mut Net<M>, port: Port);
fn call(slf: &Def<Self>, net: &mut Net, port: Port);
}

impl<T: AsHostedDef> AsDef for HostedDef<T> {
unsafe fn call<M: Mode>(slf: *const Def<Self>, net: &mut Net<M>, port: Port) {
unsafe fn call(slf: *const Def<Self>, net: &mut Net, port: Port) {
T::call((slf as *const Def<T>).as_ref().unwrap(), net, port)
}
}
Expand All @@ -182,15 +180,15 @@ impl UniqueTreePtr {
}
}

pub struct ReadbackDef<F: FnOnce(DynNetMut) + Send + Sync + 'static> {
pub struct ReadbackDef<F: FnOnce(&mut Net) + Send + Sync + 'static> {
root: Arc<F>,
host: Arc<Mutex<Host>>,
var_idx: Arc<AtomicUsize>,
tree: UniqueTreePtr,
}

impl<F: FnOnce(DynNetMut) + Send + Sync + 'static> ReadbackDef<F> {
fn maybe_finish(net: DynNetMut<'_, '_>, root: Arc<F>) {
impl<F: FnOnce(&mut Net) + Send + Sync + 'static> ReadbackDef<F> {
fn maybe_finish(net: &mut Net, root: Arc<F>) {
let Some(root) = Arc::into_inner(root) else { return };
(root)(net)
}
Expand All @@ -204,8 +202,8 @@ impl<F: FnOnce(DynNetMut) + Send + Sync + 'static> ReadbackDef<F> {
}
}

impl<F: FnOnce(DynNetMut) + Send + Sync + 'static> AsBoxDef for ReadbackDef<F> {
fn call<M: Mode>(def: Box<Def<Self>>, net: &mut Net<M>, port: Port) {
impl<F: FnOnce(&mut Net) + Send + Sync + 'static> AsBoxDef for ReadbackDef<F> {
fn call(def: Box<Def<Self>>, net: &mut Net, port: Port) {
match port.tag() {
Tag::Var | Tag::Red => {
unreachable!()
Expand All @@ -218,7 +216,7 @@ impl<F: FnOnce(DynNetMut) + Send + Sync + 'static> AsBoxDef for ReadbackDef<F> {
(*def.data.tree.0) = var.clone();
(*other.data.0.tree.0) = var;
}
Self::maybe_finish(DynNetMut::from(&mut *net), other.data.0.root);
Self::maybe_finish(net, other.data.0.root);
} else if let Some(back) = def.data.host.lock().back.get(&port.addr()) {
unsafe { *(def.data.tree.0) = Tree::Ref { nam: back.clone() } };
} else {
Expand Down Expand Up @@ -267,38 +265,30 @@ impl<F: FnOnce(DynNetMut) + Send + Sync + 'static> AsBoxDef for ReadbackDef<F> {
net.link_wire_port(old.p2, def.data.with(rhs));
}
}
Self::maybe_finish(DynNetMut::from(net), def.data.root);
Self::maybe_finish(net, def.data.root);
}
}

pub fn readback<M: Mode>(
net: &mut Net<M>,
pub fn readback(
net: &mut Net,
host: Arc<Mutex<Host>>,
from: Trg,
f: impl FnOnce(DynNetMut, Tree) + Send + Sync + 'static,
f: impl FnOnce(&mut Net, Tree) + Send + Sync + 'static,
) {
let root = UniqueTreePtr(Box::leak(Box::default()));

if M::LAZY {
let from = net.wire_to_trg(from);
net.normal_from(from.clone());
let tree = host.lock().readback_tree(&from);
net.link_wire_port(from, Port::ERA);
f(DynNetMut::from(net), tree);
} else {
let closure: Box<dyn FnOnce(DynNetMut) + Send + Sync + 'static> = Box::new(move |net| {
let root = unsafe { root.to_box() };
f(net, *root);
});
let closure: Box<dyn FnOnce(&mut Net) + Send + Sync + 'static> = Box::new(move |net| {
let root = unsafe { root.to_box() };
f(net, *root);
});

net.link_trg_port(
from,
Port::new_ref(Box::leak(BoxDef::new_boxed(LabSet::ALL, ReadbackDef {
root: Arc::new(closure),
host,
tree: root,
var_idx: Arc::new(AtomicUsize::from(0)),
}))),
);
}
net.link_trg_port(
from,
Port::new_ref(Box::leak(BoxDef::new_boxed(LabSet::ALL, ReadbackDef {
root: Arc::new(closure),
host,
tree: root,
var_idx: Arc::new(AtomicUsize::from(0)),
}))),
);
}
3 changes: 1 addition & 2 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ path = "src/runtime.rs"

[dependencies]
parking_lot = "0.12.2"
nohash-hasher = { version = "0.2.0", optional = true }

hvm64-util = { path = "../util", default-features = false }

[features]
std = ["hvm64-util/std", "dep:nohash-hasher"]
std = ["hvm64-util/std"]
trace = []

[lints]
Expand Down
3 changes: 0 additions & 3 deletions runtime/src/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ use super::*;
#[must_use]
pub struct Addr(pub usize);

#[cfg(feature = "std")]
impl nohash_hasher::IsEnabled for Addr {}

impl fmt::Debug for Addr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:012x?}", self.0)
Expand Down
29 changes: 10 additions & 19 deletions runtime/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ pub struct Def<T: ?Sized + Send + Sync = Dynamic> {
/// interaction combinator whose label is not in this set.
pub labs: LabSet,
ty: TypeId,
call_strict: unsafe fn(*const Def<T>, &mut Net<Strict>, port: Port),
call_lazy: unsafe fn(*const Def<T>, &mut Net<Lazy>, port: Port),
call: unsafe fn(*const Def<T>, &mut Net, port: Port),
pub data: T,
}

Expand All @@ -106,15 +105,15 @@ unsafe impl Send for Dynamic {}
unsafe impl Sync for Dynamic {}

pub trait AsDef: Any + Send + Sync {
unsafe fn call<M: Mode>(slf: *const Def<Self>, net: &mut Net<M>, port: Port);
unsafe fn call(slf: *const Def<Self>, net: &mut Net, port: Port);
}

impl<T: Send + Sync> Def<T> {
pub const fn new(labs: LabSet, data: T) -> Self
where
T: AsDef,
{
Def { labs, ty: TypeId::of::<T>(), call_strict: T::call::<Strict>, call_lazy: T::call::<Lazy>, data }
Def { labs, ty: TypeId::of::<T>(), call: T::call, data }
}

#[inline(always)]
Expand Down Expand Up @@ -146,11 +145,8 @@ impl Def {
unsafe { Def::downcast_mut_ptr(self).map(|x| &mut *x) }
}
#[inline(always)]
pub unsafe fn call<M: Mode>(slf: *const Def, net: &mut Net<M>, port: Port) {
match net.as_dyn_mut() {
DynNetMut::Strict(net) => ((*slf).call_strict)(slf as *const _, net, port),
DynNetMut::Lazy(net) => ((*slf).call_lazy)(slf as *const _, net, port),
}
pub unsafe fn call(slf: *const Def, net: &mut Net, port: Port) {
((*slf).call)(slf as *const _, net, port)
}
}

Expand All @@ -169,18 +165,13 @@ impl<T: Send + Sync> DerefMut for Def<T> {
}
}

impl<F: Fn(&mut Net<Strict>, Port) + Send + Sync + 'static, G: Fn(&mut Net<Lazy>, Port) + Send + Sync + 'static> AsDef
for (F, G)
{
unsafe fn call<M: Mode>(slf: *const Def<Self>, net: &mut Net<M>, port: Port) {
match net.as_dyn_mut() {
DynNetMut::Strict(net) => ((*slf).data.0)(net, port),
DynNetMut::Lazy(net) => ((*slf).data.1)(net, port),
}
impl<F: Fn(&mut Net, Port) + Send + Sync + 'static> AsDef for F {
unsafe fn call(slf: *const Def<Self>, net: &mut Net, port: Port) {
((*slf).data)(net, port)
}
}

impl<'a, M: Mode> Net<'a, M> {
impl<'a> Net<'a> {
/// Expands a [`Ref`] node connected to `trg`.
#[inline(never)]
pub fn call(&mut self, port: Port, trg: Port) {
Expand Down Expand Up @@ -223,7 +214,7 @@ impl InterpretedDef {
}

impl AsDef for InterpretedDef {
unsafe fn call<M: Mode>(def: *const Def<InterpretedDef>, net: &mut Net<M>, trg: Port) {
unsafe fn call(def: *const Def<InterpretedDef>, net: &mut Net, trg: Port) {
let def = unsafe { &*def };
let def = &def.data;
let instructions = &def.instr;
Expand Down
Loading
Loading