Skip to content

Commit

Permalink
Merge pull request #1880 from coasys/library-use-case
Browse files Browse the repository at this point in the history
Programatic use of Machine / Scryer as library
  • Loading branch information
mthom authored Nov 2, 2023
2 parents dfd9e43 + 59264c0 commit 575245c
Show file tree
Hide file tree
Showing 20 changed files with 2,015 additions and 172 deletions.
48 changes: 47 additions & 1 deletion Cargo.lock

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

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ smallvec = "1.8.0"
static_assertions = "1.1.0"
ryu = "1.0.9"
futures = "0.3"
regex = "1.9.1"
libloading = "0.7"
derive_deref = "1.1.1"
bytes = "1"
Expand All @@ -84,7 +85,7 @@ tokio = { version = "1.28.2", features = ["full"] }

[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.2.10", features = ["js"] }
tokio = { version = "1.28.2", features = ["sync", "macros", "io-util", "rt"] }
tokio = { version = "1.28.2", features = ["sync", "macros", "io-util", "rt", "time"] }

[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
console_error_panic_hook = "0.1"
Expand All @@ -107,6 +108,7 @@ ring = { version = "0.16.13" }
[dev-dependencies]
assert_cmd = "1.0.3"
predicates-core = "1.0.2"
maplit = "1.0.2"
serial_test = "2.0.0"

[patch.crates-io]
Expand Down
9 changes: 5 additions & 4 deletions src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use crate::read::*;

use crate::parser::dashu::{Integer, Rational};
use ordered_float::OrderedFloat;
use tokio::sync::RwLock;

use std::alloc;
use std::cell::UnsafeCell;
Expand All @@ -20,6 +19,7 @@ use std::mem;
use std::net::TcpListener;
use std::ops::{Deref, DerefMut};
use std::ptr;
use std::sync::RwLock;

#[macro_export]
macro_rules! arena_alloc {
Expand Down Expand Up @@ -90,7 +90,8 @@ pub fn lookup_float(
offset: F64Offset,
) -> RcuRef<RawBlock<F64Table>, UnsafeCell<OrderedFloat<f64>>> {
let f64table = global_f64table()
.blocking_read()
.read()
.unwrap()
.upgrade()
.expect("We should only be looking up floats while there is a float table");

Expand All @@ -108,12 +109,12 @@ pub fn lookup_float(
impl F64Table {
#[inline]
pub fn new() -> Arc<Self> {
let upgraded = global_f64table().blocking_read().upgrade();
let upgraded = global_f64table().read().unwrap().upgrade();
// don't inline upgraded, otherwise temporary will be dropped too late in case of None
if let Some(atom_table) = upgraded {
atom_table
} else {
let mut guard = global_f64table().blocking_write();
let mut guard = global_f64table().write().unwrap();
// try to upgrade again in case we lost the race on the write lock
if let Some(atom_table) = guard.upgrade() {
atom_table
Expand Down
8 changes: 4 additions & 4 deletions src/atom_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ use std::slice;
use std::str;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::RwLock;
use std::sync::Weak;

use indexmap::IndexSet;

use modular_bitfield::prelude::*;
use tokio::sync::RwLock;

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Atom {
Expand Down Expand Up @@ -74,7 +74,7 @@ fn global_atom_table() -> &'static RwLock<Weak<AtomTable>> {

#[inline(always)]
fn arc_atom_table() -> Option<Arc<AtomTable>> {
global_atom_table().blocking_read().upgrade()
global_atom_table().read().unwrap().upgrade()
}

impl RawBlockTraits for AtomTable {
Expand Down Expand Up @@ -310,12 +310,12 @@ impl InnerAtomTable {
impl AtomTable {
#[inline]
pub fn new() -> Arc<Self> {
let upgraded = global_atom_table().blocking_read().upgrade();
let upgraded = global_atom_table().read().unwrap().upgrade();
// don't inline upgraded, otherwise temporary will be dropped too late in case of None
if let Some(atom_table) = upgraded {
atom_table
} else {
let mut guard = global_atom_table().blocking_write();
let mut guard = global_atom_table().write().unwrap();
// try to upgrade again in case we lost the race on the write lock
if let Some(atom_table) = guard.upgrade() {
atom_table
Expand Down
19 changes: 17 additions & 2 deletions src/bin/scryer-prolog.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
fn main() -> std::process::ExitCode {
use scryer_prolog::*;
use scryer_prolog::atom_table::Atom;
use std::sync::atomic::Ordering;

#[cfg(feature = "repl")]
Expand All @@ -8,6 +9,20 @@ fn main() -> std::process::ExitCode {
})
.unwrap();

let mut wam = machine::Machine::new();
wam.run_top_level()
#[cfg(target_arch = "wasm32")]
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();

#[cfg(not(target_arch = "wasm32"))]
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();

runtime.block_on(async move {
let mut wam = machine::Machine::new(Default::default());
wam.run_top_level(atom!("$toplevel"), (atom!("$repl"), 1))
})
}
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#[macro_use]
extern crate static_assertions;
#[cfg(test)]
#[macro_use] extern crate maplit;

#[macro_use]
pub mod macros;
Expand Down Expand Up @@ -47,7 +49,6 @@ use wasm_bindgen::prelude::*;
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub fn eval_code(s: &str) -> String {
use web_sys::console;
use machine::mock_wam::*;

let mut wam = Machine::with_test_streams();
Expand Down
4 changes: 4 additions & 0 deletions src/loader.pl
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,10 @@
)
).

consult_stream(Stream, PathFileName) :-
'$push_load_state_payload'(Evacuable),
file_load(Stream, PathFileName, Subevacuable),
'$use_module'(Evacuable, Subevacuable, _).

:- non_counted_backtracking check_predicate_property/5.

Expand Down
32 changes: 32 additions & 0 deletions src/machine/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
pub struct MachineConfig {
pub streams: StreamConfig,
pub toplevel: &'static str,
}

pub enum StreamConfig {
Stdio,
Memory,
}

impl Default for MachineConfig {
fn default() -> Self {
MachineConfig {
streams: StreamConfig::Stdio,
toplevel: include_str!("../toplevel.pl"),
}
}
}

impl MachineConfig {
pub fn in_memory() -> Self {
MachineConfig {
streams: StreamConfig::Memory,
..Default::default()
}
}

pub fn with_toplevel(mut self, toplevel: &'static str) -> Self {
self.toplevel = toplevel;
self
}
}
26 changes: 16 additions & 10 deletions src/machine/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5221,16 +5221,22 @@ impl Machine {
self.machine_st.throw_interrupt_exception();
self.machine_st.backtrack();

#[cfg(not(target_arch = "wasm32"))]
let runtime = tokio::runtime::Runtime::new().unwrap();
#[cfg(target_arch = "wasm32")]
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();

let old_runtime = std::mem::replace(&mut self.runtime, runtime);
old_runtime.shutdown_background();
// We have extracted controll over the Tokio runtime to the calling context for enabling library use case
// (see https://github.com/mthom/scryer-prolog/pull/1880)
// So we only have access to a runtime handle in here and can't shut it down.
// Since I'm not aware of the consequences of deactivating this new code which came in while PR 1880
// was not merged, I'm only deactivating it for now.

//#[cfg(not(target_arch = "wasm32"))]
//let runtime = tokio::runtime::Runtime::new().unwrap();
//#[cfg(target_arch = "wasm32")]
//let runtime = tokio::runtime::Builder::new_current_thread()
// .enable_all()
// .build()
// .unwrap();

//let old_runtime = tokio::runtime::Handle::current();
//old_runtime.shutdown_background();
}
}
Err(_) => unreachable!(),
Expand Down
Loading

0 comments on commit 575245c

Please sign in to comment.