[WIP] make AtomTable concurrentcy ready
This commit is contained in:
@@ -19,6 +19,7 @@ repl = ["dep:crossterm", "dep:ctrlc", "dep:rustyline"]
|
|||||||
hostname = ["dep:hostname"]
|
hostname = ["dep:hostname"]
|
||||||
tls = ["dep:native-tls"]
|
tls = ["dep:native-tls"]
|
||||||
http = ["dep:hyper", "dep:reqwest"]
|
http = ["dep:hyper", "dep:reqwest"]
|
||||||
|
rust_beta_channel = []
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
indexmap = "1.0.2"
|
indexmap = "1.0.2"
|
||||||
|
|||||||
18
src/arena.rs
18
src/arena.rs
@@ -965,8 +965,8 @@ mod tests {
|
|||||||
let f_atom = atom!("f");
|
let f_atom = atom!("f");
|
||||||
let g_atom = atom!("g");
|
let g_atom = atom!("g");
|
||||||
|
|
||||||
assert_eq!(f_atom.as_str(), "f");
|
assert_eq!(&*f_atom.as_str(), "f");
|
||||||
assert_eq!(g_atom.as_str(), "g");
|
assert_eq!(&*g_atom.as_str(), "g");
|
||||||
|
|
||||||
let f_atom_cell = atom_as_cell!(f_atom);
|
let f_atom_cell = atom_as_cell!(f_atom);
|
||||||
let g_atom_cell = atom_as_cell!(g_atom);
|
let g_atom_cell = atom_as_cell!(g_atom);
|
||||||
@@ -976,7 +976,7 @@ mod tests {
|
|||||||
match f_atom_cell.to_atom() {
|
match f_atom_cell.to_atom() {
|
||||||
Some(atom) => {
|
Some(atom) => {
|
||||||
assert_eq!(f_atom, atom);
|
assert_eq!(f_atom, atom);
|
||||||
assert_eq!(atom.as_str(), "f");
|
assert_eq!(&*atom.as_str(), "f");
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
assert!(false);
|
assert!(false);
|
||||||
@@ -987,7 +987,7 @@ mod tests {
|
|||||||
(HeapCellValueTag::Atom, (atom, arity)) => {
|
(HeapCellValueTag::Atom, (atom, arity)) => {
|
||||||
assert_eq!(f_atom, atom);
|
assert_eq!(f_atom, atom);
|
||||||
assert_eq!(arity, 0);
|
assert_eq!(arity, 0);
|
||||||
assert_eq!(atom.as_str(), "f");
|
assert_eq!(&*atom.as_str(), "f");
|
||||||
}
|
}
|
||||||
_ => { unreachable!() }
|
_ => { unreachable!() }
|
||||||
);
|
);
|
||||||
@@ -996,7 +996,7 @@ mod tests {
|
|||||||
(HeapCellValueTag::Atom, (atom, arity)) => {
|
(HeapCellValueTag::Atom, (atom, arity)) => {
|
||||||
assert_eq!(g_atom, atom);
|
assert_eq!(g_atom, atom);
|
||||||
assert_eq!(arity, 0);
|
assert_eq!(arity, 0);
|
||||||
assert_eq!(atom.as_str(), "g");
|
assert_eq!(&*atom.as_str(), "g");
|
||||||
}
|
}
|
||||||
_ => { unreachable!() }
|
_ => { unreachable!() }
|
||||||
);
|
);
|
||||||
@@ -1006,7 +1006,7 @@ mod tests {
|
|||||||
let pstr_var_cell = put_partial_string(
|
let pstr_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"ronan",
|
"ronan",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
||||||
|
|
||||||
@@ -1014,7 +1014,7 @@ mod tests {
|
|||||||
|
|
||||||
match pstr_cell.to_pstr() {
|
match pstr_cell.to_pstr() {
|
||||||
Some(pstr) => {
|
Some(pstr) => {
|
||||||
assert_eq!(pstr.as_str_from(0), "ronan");
|
assert_eq!(&*pstr.as_str_from(0), "ronan");
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
assert!(false);
|
assert!(false);
|
||||||
@@ -1024,7 +1024,7 @@ mod tests {
|
|||||||
read_heap_cell!(pstr_cell,
|
read_heap_cell!(pstr_cell,
|
||||||
(HeapCellValueTag::PStr, pstr_atom) => {
|
(HeapCellValueTag::PStr, pstr_atom) => {
|
||||||
let pstr = PartialString::from(pstr_atom);
|
let pstr = PartialString::from(pstr_atom);
|
||||||
assert_eq!(pstr.as_str_from(0), "ronan");
|
assert_eq!(&*pstr.as_str_from(0), "ronan");
|
||||||
}
|
}
|
||||||
_ => { unreachable!() }
|
_ => { unreachable!() }
|
||||||
);
|
);
|
||||||
@@ -1133,7 +1133,7 @@ mod tests {
|
|||||||
read_heap_cell!(cell,
|
read_heap_cell!(cell,
|
||||||
(HeapCellValueTag::Atom, (el, _arity)) => {
|
(HeapCellValueTag::Atom, (el, _arity)) => {
|
||||||
assert_eq!(el.flat_index(), empty_list_as_cell!().get_value());
|
assert_eq!(el.flat_index(), empty_list_as_cell!().get_value());
|
||||||
assert_eq!(el.as_str(), "[]");
|
assert_eq!(&*el.as_str(), "[]");
|
||||||
}
|
}
|
||||||
_ => { unreachable!() }
|
_ => { unreachable!() }
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,17 +2,22 @@ use crate::parser::ast::MAX_ARITY;
|
|||||||
use crate::raw_block::*;
|
use crate::raw_block::*;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
|
|
||||||
use std::borrow::Borrow;
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::Weak;
|
||||||
|
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
use modular_bitfield::prelude::*;
|
use modular_bitfield::prelude::*;
|
||||||
|
use tokio::runtime::Handle;
|
||||||
|
use tokio::sync::OwnedRwLockReadGuard;
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct Atom {
|
pub struct Atom {
|
||||||
@@ -41,61 +46,29 @@ impl From<bool> for Atom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl indexmap::Equivalent<Atom> for str {
|
||||||
|
fn equivalent(&self, atom: &Atom) -> bool {
|
||||||
|
&*atom.as_str() == self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const ATOM_TABLE_INIT_SIZE: usize = 1 << 16;
|
const ATOM_TABLE_INIT_SIZE: usize = 1 << 16;
|
||||||
const ATOM_TABLE_ALIGN: usize = 8;
|
const ATOM_TABLE_ALIGN: usize = 8;
|
||||||
|
|
||||||
#[cfg(test)]
|
pub fn global_atom_table() -> &'static RwLock<Weak<RwLock<AtomTable>>> {
|
||||||
thread_local! {
|
#[cfg(feature = "rust_beta_channel")]
|
||||||
static ATOM_TABLE_BUF_BASE: std::cell::RefCell<*const u8> = std::cell::RefCell::new(ptr::null_mut());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(test))]
|
|
||||||
static ATOM_TABLE_BUF_BASE: std::sync::atomic::AtomicPtr<u8> =
|
|
||||||
std::sync::atomic::AtomicPtr::new(ptr::null_mut());
|
|
||||||
|
|
||||||
fn set_atom_tbl_buf_base(old_ptr: *const u8, new_ptr: *const u8) -> Result<(), *const u8> {
|
|
||||||
#[cfg(test)]
|
|
||||||
{
|
{
|
||||||
ATOM_TABLE_BUF_BASE.with(|atom_table_buf_base| {
|
// const Weak::new will be stabilized in 1.73 which is currently in beta,
|
||||||
let mut borrow = atom_table_buf_base.borrow_mut();
|
// till then we need a OnceLock for initialization
|
||||||
if *borrow != old_ptr {
|
static GLOBAL_ATOM_TABLE: RwLock<Weak<RwLock<AtomTable>>> = RwLock::new(Weak::new());
|
||||||
Err(*borrow)
|
&GLOBAL_ATOM_TABLE
|
||||||
} else {
|
|
||||||
*borrow = new_ptr;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
})?;
|
#[cfg(not(feature = "rust_beta_channel"))]
|
||||||
};
|
|
||||||
#[cfg(not(test))]
|
|
||||||
{
|
{
|
||||||
ATOM_TABLE_BUF_BASE
|
use std::sync::OnceLock;
|
||||||
.compare_exchange(
|
static GLOBAL_ATOM_TABLE: OnceLock<RwLock<Weak<RwLock<AtomTable>>>> = OnceLock::new();
|
||||||
old_ptr.cast_mut(),
|
GLOBAL_ATOM_TABLE.get_or_init(|| RwLock::new(Weak::new()))
|
||||||
new_ptr.cast_mut(),
|
|
||||||
std::sync::atomic::Ordering::Relaxed,
|
|
||||||
std::sync::atomic::Ordering::Relaxed,
|
|
||||||
)
|
|
||||||
.map_err(|ptr| ptr.cast_const())
|
|
||||||
}?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_atom_tbl_buf_base() -> *const u8 {
|
|
||||||
#[cfg(test)]
|
|
||||||
{
|
|
||||||
ATOM_TABLE_BUF_BASE.with(|atom_table_buf_base| *atom_table_buf_base.borrow())
|
|
||||||
}
|
|
||||||
#[cfg(not(test))]
|
|
||||||
{
|
|
||||||
ATOM_TABLE_BUF_BASE.load(std::sync::atomic::Ordering::Relaxed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic(expected = "Overwriting atom table base pointer")]
|
|
||||||
fn atomtable_is_not_concurrency_safe() {
|
|
||||||
let _table_a = AtomTable::new();
|
|
||||||
let _table_b = AtomTable::new();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RawBlockTraits for AtomTable {
|
impl RawBlockTraits for AtomTable {
|
||||||
@@ -126,13 +99,6 @@ impl AtomHeader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Borrow<str> for Atom {
|
|
||||||
#[inline]
|
|
||||||
fn borrow(&self) -> &str {
|
|
||||||
self.as_str()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hash for Atom {
|
impl Hash for Atom {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||||
@@ -148,16 +114,68 @@ macro_rules! is_char {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Atom {
|
pub enum AtomString<'a> {
|
||||||
#[inline]
|
Static(&'a str),
|
||||||
pub fn buf(self) -> *const u8 {
|
Dynamic(OwnedRwLockReadGuard<AtomTable, str>),
|
||||||
let ptr = self.as_ptr();
|
|
||||||
|
|
||||||
if ptr.is_null() {
|
|
||||||
return ptr::null();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(ptr as usize + mem::size_of::<AtomHeader>()) as *const u8
|
impl AtomString<'_> {
|
||||||
|
pub fn map<F>(self, f: F) -> Self
|
||||||
|
where
|
||||||
|
for<'a> F: FnOnce(&'a str) -> &'a str,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Self::Static(reference) => Self::Static(f(reference)),
|
||||||
|
Self::Dynamic(guard) => Self::Dynamic(OwnedRwLockReadGuard::map(guard, f)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for AtomString<'_> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
std::fmt::Debug::fmt(self.deref(), f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for AtomString<'_> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(self.deref(), f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Deref for AtomString<'_> {
|
||||||
|
type Target = str;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
match self {
|
||||||
|
Self::Static(reference) => reference,
|
||||||
|
Self::Dynamic(guard) => guard.deref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl rustyline::completion::Candidate for AtomString<'_> {
|
||||||
|
fn display(&self) -> &str {
|
||||||
|
self.deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn replacement(&self) -> &str {
|
||||||
|
self.deref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Atom {
|
||||||
|
#[inline]
|
||||||
|
pub fn buf(self) -> Option<OwnedRwLockReadGuard<AtomTable, u8>> {
|
||||||
|
if let Some(guard) = self.as_ptr() {
|
||||||
|
Some(OwnedRwLockReadGuard::map(guard, |ptr| unsafe {
|
||||||
|
(ptr as *const u8)
|
||||||
|
.offset(mem::size_of::<AtomHeader>() as isize)
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -166,12 +184,36 @@ impl Atom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn as_ptr(self) -> *const u8 {
|
pub fn as_ptr(self) -> Option<OwnedRwLockReadGuard<AtomTable, u8>> {
|
||||||
if self.is_static() {
|
if self.is_static() {
|
||||||
ptr::null()
|
None
|
||||||
} else {
|
} else {
|
||||||
(get_atom_tbl_buf_base() as usize + (self.index as usize) - (STRINGS.len() << 3))
|
let atom_table = global_atom_table()
|
||||||
as *const u8
|
.blocking_read()
|
||||||
|
.upgrade()
|
||||||
|
.expect("We should only have an Atom while there is an AtomTable");
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
|
let guard = Handle::current().block_on(atom_table.read_owned());
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
let guard = {
|
||||||
|
if let Ok(handle) = Handle::try_current() {
|
||||||
|
handle.block_on(atom_table.read_owned())
|
||||||
|
} else {
|
||||||
|
tokio::runtime::Runtime::new()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(atom_table.read_owned())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(OwnedRwLockReadGuard::map(guard, |atom_table| unsafe {
|
||||||
|
atom_table
|
||||||
|
.buf()
|
||||||
|
.offset(((self.index as usize) - (STRINGS.len() << 3)) as isize)
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +227,10 @@ impl Atom {
|
|||||||
if self.is_static() {
|
if self.is_static() {
|
||||||
STRINGS[(self.index >> 3) as usize].len()
|
STRINGS[(self.index >> 3) as usize].len()
|
||||||
} else {
|
} else {
|
||||||
unsafe { ptr::read(self.as_ptr() as *const AtomHeader).len() as _ }
|
unsafe {
|
||||||
|
ptr::read(self.as_ptr().unwrap().deref() as *const u8 as *const AtomHeader).len()
|
||||||
|
as _
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,24 +254,20 @@ impl Atom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn chars(&self) -> str::Chars {
|
pub fn as_str(&self) -> AtomString<'static> {
|
||||||
self.as_str().chars()
|
if let Some(ptr_guard) = self.as_ptr() {
|
||||||
}
|
AtomString::Dynamic(OwnedRwLockReadGuard::map(ptr_guard, |ptr| {
|
||||||
|
let header =
|
||||||
#[inline]
|
unsafe { ptr::read::<AtomHeader>(ptr as *const u8 as *const AtomHeader) };
|
||||||
pub fn as_str(&self) -> &str {
|
|
||||||
unsafe {
|
|
||||||
let ptr = self.as_ptr();
|
|
||||||
|
|
||||||
if ptr.is_null() {
|
|
||||||
return STRINGS[(self.index >> 3) as usize];
|
|
||||||
}
|
|
||||||
|
|
||||||
let header = ptr::read::<AtomHeader>(ptr as *const _);
|
|
||||||
let len = header.len() as usize;
|
let len = header.len() as usize;
|
||||||
let buf = (ptr as usize + mem::size_of::<AtomHeader>()) as *mut u8;
|
let buf =
|
||||||
|
(unsafe { (ptr as *const u8).offset(mem::size_of::<AtomHeader>() as isize) })
|
||||||
|
as *mut u8;
|
||||||
|
|
||||||
str::from_utf8_unchecked(slice::from_raw_parts(buf, len))
|
unsafe { str::from_utf8_unchecked(slice::from_raw_parts(buf, len)) }
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
return AtomString::Static(STRINGS[(self.index >> 3) as usize]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +300,7 @@ impl PartialOrd for Atom {
|
|||||||
impl Ord for Atom {
|
impl Ord for Atom {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cmp(&self, other: &Atom) -> Ordering {
|
fn cmp(&self, other: &Atom) -> Ordering {
|
||||||
self.as_str().cmp(other.as_str())
|
self.as_str().cmp(&*other.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,34 +310,32 @@ pub struct AtomTable {
|
|||||||
pub table: IndexSet<Atom>,
|
pub table: IndexSet<Atom>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cold]
|
|
||||||
fn atom_table_base_pointer_mismatch(expected: *const u8, got: *const u8) -> ! {
|
|
||||||
assert_eq!(expected, got, "Overwriting atom table base pointer, expected old value to be {expected:p}, but found {got:p}");
|
|
||||||
unreachable!("This should only be called in a case of a mismatch as such the assert_eq should have failed!")
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for AtomTable {
|
impl Drop for AtomTable {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Err(got) = set_atom_tbl_buf_base(self.block.base, ptr::null()) {
|
|
||||||
atom_table_base_pointer_mismatch(self.block.base, got);
|
|
||||||
}
|
|
||||||
self.block.deallocate();
|
self.block.deallocate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AtomTable {
|
impl AtomTable {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Arc<RwLock<Self>> {
|
||||||
let mut block = RawBlock::new();
|
let upgraded = global_atom_table().blocking_read().upgrade();
|
||||||
|
// don't inline upgraded, temporary will be dropped too late in case of None
|
||||||
if let Err(got) = set_atom_tbl_buf_base(ptr::null(), block.base) {
|
if let Some(atom_table) = upgraded {
|
||||||
block.deallocate();
|
atom_table
|
||||||
atom_table_base_pointer_mismatch(ptr::null(), got);
|
} else {
|
||||||
}
|
let mut guard = global_atom_table().blocking_write();
|
||||||
|
// try to upgrade again in case we lost the race on the write lock
|
||||||
Self {
|
if let Some(atom_table) = guard.upgrade() {
|
||||||
block,
|
atom_table
|
||||||
|
} else {
|
||||||
|
let atom_table = Arc::new(RwLock::new(Self {
|
||||||
|
block: RawBlock::new(),
|
||||||
table: IndexSet::new(),
|
table: IndexSet::new(),
|
||||||
|
}));
|
||||||
|
*guard = Arc::downgrade(&atom_table);
|
||||||
|
atom_table
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,24 +367,14 @@ impl AtomTable {
|
|||||||
let align_offset = 8 * mem::align_of::<AtomHeader>();
|
let align_offset = 8 * mem::align_of::<AtomHeader>();
|
||||||
let size = (size & !(align_offset - 1)) + align_offset;
|
let size = (size & !(align_offset - 1)) + align_offset;
|
||||||
|
|
||||||
let len_ptr = {
|
let len_ptr = loop {
|
||||||
let mut ptr;
|
let ptr = self.block.alloc(size);
|
||||||
|
|
||||||
loop {
|
|
||||||
ptr = self.block.alloc(size);
|
|
||||||
|
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
let old_base = self.block.base;
|
|
||||||
self.block.grow();
|
self.block.grow();
|
||||||
if let Err(got) = set_atom_tbl_buf_base(old_base, self.block.base) {
|
|
||||||
atom_table_base_pointer_mismatch(old_base, got);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break ptr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ptr
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let ptr_base = self.block.base as usize;
|
let ptr_base = self.block.base as usize;
|
||||||
@@ -363,6 +392,9 @@ impl AtomTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for AtomTable {}
|
||||||
|
unsafe impl Sync for AtomTable {}
|
||||||
|
|
||||||
#[bitfield]
|
#[bitfield]
|
||||||
#[repr(u64)]
|
#[repr(u64)]
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ use crate::machine::machine_errors::*;
|
|||||||
use fxhash::FxBuildHasher;
|
use fxhash::FxBuildHasher;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
@@ -262,7 +264,7 @@ impl CodeGenSettings {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct CodeGenerator<'a> {
|
pub(crate) struct CodeGenerator<'a> {
|
||||||
pub(crate) atom_tbl: &'a mut AtomTable,
|
pub(crate) atom_tbl: &'a RwLock<AtomTable>,
|
||||||
marker: DebrayAllocator,
|
marker: DebrayAllocator,
|
||||||
settings: CodeGenSettings,
|
settings: CodeGenSettings,
|
||||||
pub(crate) skeleton: PredicateSkeleton,
|
pub(crate) skeleton: PredicateSkeleton,
|
||||||
@@ -362,7 +364,7 @@ fn structure_cell(term: &Term) -> Option<&Cell<RegType>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'b> CodeGenerator<'b> {
|
impl<'b> CodeGenerator<'b> {
|
||||||
pub(crate) fn new(atom_tbl: &'b mut AtomTable, settings: CodeGenSettings) -> Self {
|
pub(crate) fn new(atom_tbl: &'b RwLock<AtomTable>, settings: CodeGenSettings) -> Self {
|
||||||
CodeGenerator {
|
CodeGenerator {
|
||||||
atom_tbl,
|
atom_tbl,
|
||||||
marker: DebrayAllocator::new(),
|
marker: DebrayAllocator::new(),
|
||||||
@@ -509,7 +511,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
TermRef::PartialString(lvl, cell, string, tail) => {
|
TermRef::PartialString(lvl, cell, string, tail) => {
|
||||||
self.marker
|
self.marker
|
||||||
.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
|
.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
|
||||||
let atom = self.atom_tbl.build_with(&string);
|
let atom = self.atom_tbl.blocking_write().build_with(&string);
|
||||||
|
|
||||||
target.push_back(Target::to_pstr(lvl, atom, cell.get(), true));
|
target.push_back(Target::to_pstr(lvl, atom, cell.get(), true));
|
||||||
self.subterm_to_instr::<Target>(tail, term_loc, &mut target);
|
self.subterm_to_instr::<Target>(tail, term_loc, &mut target);
|
||||||
@@ -1240,7 +1242,12 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
let index = code.len();
|
let index = code.len();
|
||||||
|
|
||||||
if clauses_len > 1 || self.settings.is_extensible {
|
if clauses_len > 1 || self.settings.is_extensible {
|
||||||
code_offsets.index_term(arg, index, &mut clause_index_info, self.atom_tbl);
|
code_offsets.index_term(
|
||||||
|
arg,
|
||||||
|
index,
|
||||||
|
&mut clause_index_info,
|
||||||
|
&mut self.atom_tbl.blocking_write(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ impl ForeignFunctionTable {
|
|||||||
atom!("ptr") => &mut types::pointer,
|
atom!("ptr") => &mut types::pointer,
|
||||||
atom!("f32") => &mut types::float,
|
atom!("f32") => &mut types::float,
|
||||||
atom!("f64") => &mut types::double,
|
atom!("f64") => &mut types::double,
|
||||||
struct_name => match self.structs.get_mut(struct_name.as_str()) {
|
struct_name => match self.structs.get_mut(&*struct_name.as_str()) {
|
||||||
Some(ref mut struct_type) => &mut struct_type.ffi_type,
|
Some(ref mut struct_type) => &mut struct_type.ffi_type,
|
||||||
None => unreachable!(),
|
None => unreachable!(),
|
||||||
},
|
},
|
||||||
@@ -437,11 +437,11 @@ impl ForeignFunctionTable {
|
|||||||
let substruct = struct_type.atom_fields[i].as_str();
|
let substruct = struct_type.atom_fields[i].as_str();
|
||||||
let struct_type = self
|
let struct_type = self
|
||||||
.structs
|
.structs
|
||||||
.get(substruct)
|
.get(&*substruct)
|
||||||
.ok_or(FFIError::StructNotFound)?;
|
.ok_or(FFIError::StructNotFound)?;
|
||||||
field_ptr = field_ptr
|
field_ptr = field_ptr
|
||||||
.add(field_ptr.align_offset(struct_type.ffi_type.alignment as usize));
|
.add(field_ptr.align_offset(struct_type.ffi_type.alignment as usize));
|
||||||
let struct_val = self.read_struct(field_ptr, substruct, struct_type);
|
let struct_val = self.read_struct(field_ptr, &*substruct, struct_type);
|
||||||
returns.push(struct_val?);
|
returns.push(struct_val?);
|
||||||
field_ptr = field_ptr.add(struct_type.ffi_type.size);
|
field_ptr = field_ptr.add(struct_type.ffi_type.size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ impl ClauseInfo for Term {
|
|||||||
|
|
||||||
fn arity(&self) -> usize {
|
fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
Term::Clause(_, name, terms) => match name.as_str() {
|
Term::Clause(_, name, terms) => match &*name.as_str() {
|
||||||
":-" => match terms.len() {
|
":-" => match terms.len() {
|
||||||
1 => 0,
|
1 => 0,
|
||||||
2 => terms[0].arity(),
|
2 => terms[0].arity(),
|
||||||
@@ -489,11 +489,11 @@ impl AtomOrString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> AtomString<'_> {
|
||||||
match self {
|
match self {
|
||||||
AtomOrString::Atom(atom) if atom == &atom!("[]") => "",
|
AtomOrString::Atom(atom) if atom == &atom!("[]") => AtomString::Static(""),
|
||||||
AtomOrString::Atom(atom) => atom.as_str(),
|
AtomOrString::Atom(atom) => atom.as_str(),
|
||||||
AtomOrString::String(string) => string.as_str(),
|
AtomOrString::String(string) => AtomString::Static(string.as_str()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -711,7 +711,7 @@ mod tests {
|
|||||||
let pstr_var_cell = put_partial_string(
|
let pstr_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc ",
|
"abc ",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
||||||
|
|
||||||
@@ -736,7 +736,7 @@ mod tests {
|
|||||||
let pstr_second_var_cell = put_partial_string(
|
let pstr_second_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"def",
|
"def",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
||||||
@@ -1779,7 +1779,7 @@ mod tests {
|
|||||||
let pstr_var_cell = put_partial_string(
|
let pstr_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc ",
|
"abc ",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
||||||
|
|
||||||
@@ -1807,7 +1807,7 @@ mod tests {
|
|||||||
let pstr_second_var_cell = put_partial_string(
|
let pstr_second_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"def",
|
"def",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
||||||
|
|
||||||
@@ -2378,7 +2378,7 @@ mod tests {
|
|||||||
let pstr_var_cell = put_partial_string(
|
let pstr_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc ",
|
"abc ",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
||||||
|
|
||||||
@@ -2405,7 +2405,7 @@ mod tests {
|
|||||||
let pstr_second_var_cell = put_partial_string(
|
let pstr_second_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"def",
|
"def",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
||||||
|
|
||||||
@@ -2841,7 +2841,7 @@ mod tests {
|
|||||||
let pstr_var_cell = put_partial_string(
|
let pstr_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc ",
|
"abc ",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
||||||
|
|
||||||
@@ -2865,7 +2865,7 @@ mod tests {
|
|||||||
let pstr_second_var_cell = put_partial_string(
|
let pstr_second_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"def",
|
"def",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
||||||
|
|||||||
@@ -24,11 +24,14 @@ use ordered_float::OrderedFloat;
|
|||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
use std::net::{IpAddr, TcpListener};
|
use std::net::{IpAddr, TcpListener};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
/* contains the location, name, precision and Specifier of the parent op. */
|
/* contains the location, name, precision and Specifier of the parent op. */
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
@@ -74,7 +77,7 @@ fn needs_bracketing(child_desc: OpDesc, op: &DirectedOp) -> bool {
|
|||||||
DirectedOp::Left(name, cell) => {
|
DirectedOp::Left(name, cell) => {
|
||||||
let (priority, spec) = cell.get();
|
let (priority, spec) = cell.get();
|
||||||
|
|
||||||
if name.as_str() == "-" {
|
if &*name.as_str() == "-" {
|
||||||
let child_assoc = child_desc.get_spec();
|
let child_assoc = child_desc.get_spec();
|
||||||
if is_prefix!(spec) && (is_postfix!(child_assoc) || is_infix!(child_assoc)) {
|
if is_prefix!(spec) && (is_postfix!(child_assoc) || is_infix!(child_assoc)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -480,7 +483,7 @@ pub fn fmt_float(mut fl: f64) -> String {
|
|||||||
pub struct HCPrinter<'a, Outputter> {
|
pub struct HCPrinter<'a, Outputter> {
|
||||||
outputter: Outputter,
|
outputter: Outputter,
|
||||||
iter: StackfulPreOrderHeapIter<'a>,
|
iter: StackfulPreOrderHeapIter<'a>,
|
||||||
atom_tbl: &'a mut AtomTable,
|
atom_tbl: Arc<RwLock<AtomTable>>,
|
||||||
op_dir: &'a OpDir,
|
op_dir: &'a OpDir,
|
||||||
state_stack: Vec<TokenOrRedirect>,
|
state_stack: Vec<TokenOrRedirect>,
|
||||||
toplevel_spec: Option<DirectedOp>,
|
toplevel_spec: Option<DirectedOp>,
|
||||||
@@ -549,7 +552,7 @@ pub(crate) fn numbervar(offset: &Integer, addr: HeapCellValue) -> Option<String>
|
|||||||
impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
heap: &'a mut Heap,
|
heap: &'a mut Heap,
|
||||||
atom_tbl: &'a mut AtomTable,
|
atom_tbl: Arc<RwLock<AtomTable>>,
|
||||||
stack: &'a mut Stack,
|
stack: &'a mut Stack,
|
||||||
op_dir: &'a OpDir,
|
op_dir: &'a OpDir,
|
||||||
output: Outputter,
|
output: Outputter,
|
||||||
@@ -631,7 +634,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.state_stack.push(TokenOrRedirect::Op(name, spec));
|
self.state_stack.push(TokenOrRedirect::Op(name, spec));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match name.as_str() {
|
match &*name.as_str() {
|
||||||
"|" => {
|
"|" => {
|
||||||
self.format_bar_separator_op(max_depth, name, spec);
|
self.format_bar_separator_op(max_depth, name, spec);
|
||||||
return;
|
return;
|
||||||
@@ -894,7 +897,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn print_impromptu_atom(&mut self, atom: Atom) {
|
fn print_impromptu_atom(&mut self, atom: Atom) {
|
||||||
let result = self.print_op_addendum(atom.as_str());
|
let result = self.print_op_addendum(&*atom.as_str());
|
||||||
|
|
||||||
push_space_if_amb!(self, result.as_str(), {
|
push_space_if_amb!(self, result.as_str(), {
|
||||||
append_str!(self, &result);
|
append_str!(self, &result);
|
||||||
@@ -1405,7 +1408,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
for op in &[op, parent_op] {
|
for op in &[op, parent_op] {
|
||||||
if let Some(ref op) = &op {
|
if let Some(ref op) = &op {
|
||||||
if op.is_left()
|
if op.is_left()
|
||||||
&& (op.is_prefix() || requires_space(op.as_atom().as_str(), "("))
|
&& (op.is_prefix() || requires_space(&*op.as_atom().as_str(), "("))
|
||||||
{
|
{
|
||||||
self.state_stack.push(TokenOrRedirect::Space);
|
self.state_stack.push(TokenOrRedirect::Space);
|
||||||
return;
|
return;
|
||||||
@@ -1530,7 +1533,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
max_depth,
|
max_depth,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
push_space_if_amb!(printer, name.as_str(), {
|
push_space_if_amb!(printer, &*name.as_str(), {
|
||||||
printer.format_clause(max_depth, arity, name, None);
|
printer.format_clause(max_depth, arity, name, None);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1551,7 +1554,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
result.push('(');
|
result.push('(');
|
||||||
}
|
}
|
||||||
|
|
||||||
result += &printer.print_op_addendum(name.as_str());
|
result += &printer.print_op_addendum(&*name.as_str());
|
||||||
|
|
||||||
if op.is_some() {
|
if op.is_some() {
|
||||||
result.push(')');
|
result.push(')');
|
||||||
@@ -1561,7 +1564,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
append_str!(printer, &result);
|
append_str!(printer, &result);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
push_space_if_amb!(printer, name.as_str(), {
|
push_space_if_amb!(printer, &*name.as_str(), {
|
||||||
printer.print_impromptu_atom(name);
|
printer.print_impromptu_atom(name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1585,7 +1588,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
print_struct(self, name, arity);
|
print_struct(self, name, arity);
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Char, c) => {
|
(HeapCellValueTag::Char, c) => {
|
||||||
let name = self.atom_tbl.build_with(&String::from(c));
|
let name = self.atom_tbl.blocking_write().build_with(&String::from(c));
|
||||||
print_struct(self, name, 0);
|
print_struct(self, name, 0);
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Str, s) => {
|
(HeapCellValueTag::Str, s) => {
|
||||||
@@ -1603,7 +1606,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
max_depth,
|
max_depth,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
push_space_if_amb!(self, name.as_str(), {
|
push_space_if_amb!(self, &*name.as_str(), {
|
||||||
self.format_clause(max_depth, arity, name, None);
|
self.format_clause(max_depth, arity, name, None);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1686,7 +1689,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
TokenOrRedirect::BarAsOp => append_str!(self, " | "),
|
TokenOrRedirect::BarAsOp => append_str!(self, " | "),
|
||||||
TokenOrRedirect::Char(c) => print_char!(self, self.quoted, c),
|
TokenOrRedirect::Char(c) => print_char!(self, self.quoted, c),
|
||||||
TokenOrRedirect::Op(atom, op) => {
|
TokenOrRedirect::Op(atom, op) => {
|
||||||
self.print_op(atom.as_str());
|
self.print_op(&*atom.as_str());
|
||||||
|
|
||||||
if is_prefix!(op.get_spec()) {
|
if is_prefix!(op.get_spec()) {
|
||||||
self.set_parent_of_first_op(Some(DirectedOp::Left(atom, op)));
|
self.set_parent_of_first_op(Some(DirectedOp::Left(atom, op)));
|
||||||
@@ -1762,7 +1765,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let printer = HCPrinter::new(
|
let printer = HCPrinter::new(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
&mut wam.machine_st.atom_tbl,
|
Arc::clone(&wam.machine_st.atom_tbl),
|
||||||
&mut wam.machine_st.stack,
|
&mut wam.machine_st.stack,
|
||||||
&wam.op_dir,
|
&wam.op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
@@ -1791,7 +1794,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let printer = HCPrinter::new(
|
let printer = HCPrinter::new(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
&mut wam.machine_st.atom_tbl,
|
Arc::clone(&wam.machine_st.atom_tbl),
|
||||||
&mut wam.machine_st.stack,
|
&mut wam.machine_st.stack,
|
||||||
&wam.op_dir,
|
&wam.op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
@@ -1815,7 +1818,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let printer = HCPrinter::new(
|
let printer = HCPrinter::new(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
&mut wam.machine_st.atom_tbl,
|
Arc::clone(&wam.machine_st.atom_tbl),
|
||||||
&mut wam.machine_st.stack,
|
&mut wam.machine_st.stack,
|
||||||
&wam.op_dir,
|
&wam.op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
@@ -1828,7 +1831,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut printer = HCPrinter::new(
|
let mut printer = HCPrinter::new(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
&mut wam.machine_st.atom_tbl,
|
Arc::clone(&wam.machine_st.atom_tbl),
|
||||||
&mut wam.machine_st.stack,
|
&mut wam.machine_st.stack,
|
||||||
&wam.op_dir,
|
&wam.op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
@@ -1861,7 +1864,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let printer = HCPrinter::new(
|
let printer = HCPrinter::new(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
&mut wam.machine_st.atom_tbl,
|
Arc::clone(&wam.machine_st.atom_tbl),
|
||||||
&mut wam.machine_st.stack,
|
&mut wam.machine_st.stack,
|
||||||
&wam.op_dir,
|
&wam.op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
@@ -1880,7 +1883,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let printer = HCPrinter::new(
|
let printer = HCPrinter::new(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
&mut wam.machine_st.atom_tbl,
|
Arc::clone(&wam.machine_st.atom_tbl),
|
||||||
&mut wam.machine_st.stack,
|
&mut wam.machine_st.stack,
|
||||||
&wam.op_dir,
|
&wam.op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
@@ -1897,7 +1900,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let mut printer = HCPrinter::new(
|
let mut printer = HCPrinter::new(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
&mut wam.machine_st.atom_tbl,
|
Arc::clone(&wam.machine_st.atom_tbl),
|
||||||
&mut wam.machine_st.stack,
|
&mut wam.machine_st.stack,
|
||||||
&wam.op_dir,
|
&wam.op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
@@ -1929,7 +1932,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let mut printer = HCPrinter::new(
|
let mut printer = HCPrinter::new(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
&mut wam.machine_st.atom_tbl,
|
Arc::clone(&wam.machine_st.atom_tbl),
|
||||||
&mut wam.machine_st.stack,
|
&mut wam.machine_st.stack,
|
||||||
&wam.op_dir,
|
&wam.op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
@@ -1950,13 +1953,13 @@ mod tests {
|
|||||||
put_partial_string(
|
put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc",
|
"abc",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
{
|
{
|
||||||
let printer = HCPrinter::new(
|
let printer = HCPrinter::new(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
&mut wam.machine_st.atom_tbl,
|
Arc::clone(&wam.machine_st.atom_tbl),
|
||||||
&mut wam.machine_st.stack,
|
&mut wam.machine_st.stack,
|
||||||
&wam.op_dir,
|
&wam.op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
@@ -1984,7 +1987,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let mut printer = HCPrinter::new(
|
let mut printer = HCPrinter::new(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
&mut wam.machine_st.atom_tbl,
|
Arc::clone(&wam.machine_st.atom_tbl),
|
||||||
&mut wam.machine_st.stack,
|
&mut wam.machine_st.stack,
|
||||||
&wam.op_dir,
|
&wam.op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
|
|||||||
@@ -1240,6 +1240,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
return Some(
|
return Some(
|
||||||
LS::machine_st(&mut self.payload)
|
LS::machine_st(&mut self.payload)
|
||||||
.atom_tbl
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
.build_with(path_str),
|
.build_with(path_str),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1259,7 +1260,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
let clause = self.try_term_to_tl(term, &mut preprocessor)?;
|
let clause = self.try_term_to_tl(term, &mut preprocessor)?;
|
||||||
// let queue = preprocessor.parse_queue(self)?;
|
// let queue = preprocessor.parse_queue(self)?;
|
||||||
|
|
||||||
let mut cg = CodeGenerator::new(&mut LS::machine_st(&mut self.payload).atom_tbl, settings);
|
let mut cg = CodeGenerator::new(&LS::machine_st(&mut self.payload).atom_tbl, settings);
|
||||||
|
|
||||||
let clause_code = cg.compile_predicate(vec![clause])?;
|
let clause_code = cg.compile_predicate(vec![clause])?;
|
||||||
|
|
||||||
@@ -1289,7 +1290,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
clauses.push(self.try_term_to_tl(term, &mut preprocessor)?);
|
clauses.push(self.try_term_to_tl(term, &mut preprocessor)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cg = CodeGenerator::new(&mut LS::machine_st(&mut self.payload).atom_tbl, settings);
|
let mut cg = CodeGenerator::new(&LS::machine_st(&mut self.payload).atom_tbl, settings);
|
||||||
|
|
||||||
let mut code = cg.compile_predicate(clauses)?;
|
let mut code = cg.compile_predicate(clauses)?;
|
||||||
|
|
||||||
|
|||||||
@@ -409,7 +409,7 @@ mod tests {
|
|||||||
let pstr_var_cell = put_partial_string(
|
let pstr_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc ",
|
"abc ",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ mod tests {
|
|||||||
let pstr_second_var_cell = put_partial_string(
|
let pstr_second_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"def",
|
"def",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
||||||
|
|
||||||
|
|||||||
@@ -647,7 +647,7 @@ mod tests {
|
|||||||
let pstr_var_cell = put_partial_string(
|
let pstr_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc ",
|
"abc ",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
||||||
|
|
||||||
@@ -672,7 +672,7 @@ mod tests {
|
|||||||
let pstr_second_var_cell = put_partial_string(
|
let pstr_second_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"def",
|
"def",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
||||||
|
|
||||||
|
|||||||
@@ -1150,7 +1150,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
pub(crate) fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
|
pub(crate) fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
|
||||||
let (stream, listing_src) = match module_src {
|
let (stream, listing_src) = match module_src {
|
||||||
ModuleSource::File(filename) => {
|
ModuleSource::File(filename) => {
|
||||||
let mut path_buf = PathBuf::from(filename.as_str());
|
let mut path_buf = PathBuf::from(&*filename.as_str());
|
||||||
path_buf.set_extension("pl");
|
path_buf.set_extension("pl");
|
||||||
|
|
||||||
let file = File::open(&path_buf)?;
|
let file = File::open(&path_buf)?;
|
||||||
@@ -1164,7 +1164,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
ListingSource::File(filename, path_buf),
|
ListingSource::File(filename, path_buf),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
|
ModuleSource::Library(library) => match LIBRARIES.borrow().get(&*library.as_str()) {
|
||||||
Some(code) => {
|
Some(code) => {
|
||||||
if let Some(ref module) = self.wam_prelude.indices.modules.get(&library) {
|
if let Some(ref module) = self.wam_prelude.indices.modules.get(&library) {
|
||||||
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
||||||
@@ -1232,7 +1232,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
let (stream, listing_src) = match module_src {
|
let (stream, listing_src) = match module_src {
|
||||||
ModuleSource::File(filename) => {
|
ModuleSource::File(filename) => {
|
||||||
let mut path_buf = PathBuf::from(filename.as_str());
|
let mut path_buf = PathBuf::from(&*filename.as_str());
|
||||||
path_buf.set_extension("pl");
|
path_buf.set_extension("pl");
|
||||||
let file = File::open(&path_buf)?;
|
let file = File::open(&path_buf)?;
|
||||||
|
|
||||||
@@ -1245,7 +1245,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
ListingSource::File(filename, path_buf),
|
ListingSource::File(filename, path_buf),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
|
ModuleSource::Library(library) => match LIBRARIES.borrow().get(&*library.as_str()) {
|
||||||
Some(code) => {
|
Some(code) => {
|
||||||
if self.wam_prelude.indices.modules.contains_key(&library) {
|
if self.wam_prelude.indices.modules.contains_key(&library) {
|
||||||
return self.import_qualified_module(library, exports);
|
return self.import_qualified_module(library, exports);
|
||||||
|
|||||||
@@ -1076,7 +1076,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
|
|
||||||
let export_list = machine_st.read_term_from_heap(cell)?;
|
let export_list = machine_st.read_term_from_heap(cell)?;
|
||||||
let atom_tbl = &mut LS::machine_st(&mut self.payload).atom_tbl;
|
let atom_tbl = &mut LS::machine_st(&mut self.payload).atom_tbl;
|
||||||
let export_list = setup_module_export_list(export_list, atom_tbl)?;
|
let export_list = setup_module_export_list(export_list, &mut atom_tbl.blocking_write())?;
|
||||||
|
|
||||||
Ok(export_list.into_iter().collect())
|
Ok(export_list.into_iter().collect())
|
||||||
}
|
}
|
||||||
@@ -1420,7 +1420,7 @@ impl MachineState {
|
|||||||
term_stack.push(Term::PartialString(Cell::default(), string, tail));
|
term_stack.push(Term::PartialString(Cell::default(), string, tail));
|
||||||
}
|
}
|
||||||
Ok((string, None)) => {
|
Ok((string, None)) => {
|
||||||
let atom = self.atom_tbl.build_with(&string);
|
let atom = self.atom_tbl.blocking_write().build_with(&string);
|
||||||
term_stack.push(Term::CompleteString(Cell::default(), atom));
|
term_stack.push(Term::CompleteString(Cell::default(), atom));
|
||||||
}
|
}
|
||||||
Err(cons_term) => term_stack.push(cons_term),
|
Err(cons_term) => term_stack.push(cons_term),
|
||||||
@@ -1855,7 +1855,7 @@ impl Machine {
|
|||||||
.store(self.machine_st.deref(self.machine_st.registers[2])));
|
.store(self.machine_st.deref(self.machine_st.registers[2])));
|
||||||
|
|
||||||
self.load_contexts
|
self.load_contexts
|
||||||
.push(LoadContext::new(path.as_str(), stream));
|
.push(LoadContext::new(&*path.as_str(), stream));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1917,7 +1917,11 @@ impl Machine {
|
|||||||
pub(crate) fn load_context_source(&mut self) {
|
pub(crate) fn load_context_source(&mut self) {
|
||||||
if let Some(load_context) = self.load_contexts.last() {
|
if let Some(load_context) = self.load_contexts.last() {
|
||||||
let path_str = load_context.path.to_str().unwrap();
|
let path_str = load_context.path.to_str().unwrap();
|
||||||
let path_atom = self.machine_st.atom_tbl.build_with(path_str);
|
let path_atom = self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(path_str);
|
||||||
|
|
||||||
self.machine_st
|
self.machine_st
|
||||||
.unify_atom(path_atom, self.machine_st.registers[1]);
|
.unify_atom(path_atom, self.machine_st.registers[1]);
|
||||||
@@ -1931,7 +1935,11 @@ impl Machine {
|
|||||||
match load_context.path.file_name() {
|
match load_context.path.file_name() {
|
||||||
Some(file_name) if load_context.path.is_file() => {
|
Some(file_name) if load_context.path.is_file() => {
|
||||||
let file_name_str = file_name.to_str().unwrap();
|
let file_name_str = file_name.to_str().unwrap();
|
||||||
let file_name_atom = self.machine_st.atom_tbl.build_with(file_name_str);
|
let file_name_atom = self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(file_name_str);
|
||||||
|
|
||||||
self.machine_st
|
self.machine_st
|
||||||
.unify_atom(file_name_atom, self.machine_st.registers[1]);
|
.unify_atom(file_name_atom, self.machine_st.registers[1]);
|
||||||
@@ -1950,7 +1958,11 @@ impl Machine {
|
|||||||
if let Some(load_context) = self.load_contexts.last() {
|
if let Some(load_context) = self.load_contexts.last() {
|
||||||
if let Some(directory) = load_context.path.parent() {
|
if let Some(directory) = load_context.path.parent() {
|
||||||
let directory_str = directory.to_str().unwrap();
|
let directory_str = directory.to_str().unwrap();
|
||||||
let directory_atom = self.machine_st.atom_tbl.build_with(directory_str);
|
let directory_atom = self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(directory_str);
|
||||||
|
|
||||||
self.machine_st
|
self.machine_st
|
||||||
.unify_atom(directory_atom, self.machine_st.registers[1]);
|
.unify_atom(directory_atom, self.machine_st.registers[1]);
|
||||||
|
|||||||
@@ -18,10 +18,12 @@ use crate::types::*;
|
|||||||
use crate::parser::dashu::Integer;
|
use crate::parser::dashu::Integer;
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub(crate) type Registers = [HeapCellValue; MAX_ARITY + 1];
|
pub(crate) type Registers = [HeapCellValue; MAX_ARITY + 1];
|
||||||
|
|
||||||
@@ -57,7 +59,7 @@ pub enum OnEOF {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct MachineState {
|
pub struct MachineState {
|
||||||
pub atom_tbl: AtomTable,
|
pub atom_tbl: Arc<RwLock<AtomTable>>,
|
||||||
pub arena: Arena,
|
pub arena: Arena,
|
||||||
pub(super) pdl: Vec<HeapCellValue>,
|
pub(super) pdl: Vec<HeapCellValue>,
|
||||||
pub(super) s: HeapPtr,
|
pub(super) s: HeapPtr,
|
||||||
@@ -529,7 +531,7 @@ impl MachineState {
|
|||||||
Some((var_name, var))
|
Some((var_name, var))
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
&mut self.atom_tbl,
|
&mut self.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let singleton_addr = self.registers[3];
|
let singleton_addr = self.registers[3];
|
||||||
@@ -615,7 +617,7 @@ impl MachineState {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
&mut self.atom_tbl,
|
&mut self.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
for var in term_write_result.var_dict.values_mut() {
|
for var in term_write_result.var_dict.values_mut() {
|
||||||
@@ -657,12 +659,10 @@ impl MachineState {
|
|||||||
stream: Stream,
|
stream: Stream,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
let atoms_ptr = (&self.atom_tbl.table) as *const indexmap::IndexSet<Atom>;
|
|
||||||
|
|
||||||
if let Stream::Readline(ptr) = stream {
|
if let Stream::Readline(ptr) = stream {
|
||||||
unsafe {
|
unsafe {
|
||||||
let readline = ptr.as_ptr().as_mut().unwrap();
|
let readline = ptr.as_ptr().as_mut().unwrap();
|
||||||
readline.set_atoms_for_completion(atoms_ptr);
|
readline.set_atoms_for_completion(&self.atom_tbl);
|
||||||
return self.read_term(
|
return self.read_term(
|
||||||
stream,
|
stream,
|
||||||
indices,
|
indices,
|
||||||
@@ -776,14 +776,14 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
(HeapCellValueTag::Atom, (name, _arity)) => {
|
(HeapCellValueTag::Atom, (name, _arity)) => {
|
||||||
debug_assert_eq!(_arity, 0);
|
debug_assert_eq!(_arity, 0);
|
||||||
var_names.insert(var, VarPtr::from(name.as_str()));
|
var_names.insert(var, VarPtr::from(&*name.as_str()));
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Str, s) => {
|
(HeapCellValueTag::Str, s) => {
|
||||||
let (name, arity) = cell_as_atom_cell!(self.heap[s])
|
let (name, arity) = cell_as_atom_cell!(self.heap[s])
|
||||||
.get_name_and_arity();
|
.get_name_and_arity();
|
||||||
|
|
||||||
debug_assert_eq!(arity, 0);
|
debug_assert_eq!(arity, 0);
|
||||||
var_names.insert(var, VarPtr::from(name.as_str()));
|
var_names.insert(var, VarPtr::from(&*name.as_str()));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
@@ -864,7 +864,7 @@ impl MachineState {
|
|||||||
|
|
||||||
let mut printer = HCPrinter::new(
|
let mut printer = HCPrinter::new(
|
||||||
&mut self.heap,
|
&mut self.heap,
|
||||||
&mut self.atom_tbl,
|
Arc::clone(&self.atom_tbl),
|
||||||
&mut self.stack,
|
&mut self.stack,
|
||||||
op_dir,
|
op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
|
|||||||
@@ -503,7 +503,7 @@ impl MachineState {
|
|||||||
} else {
|
} else {
|
||||||
self.pdl.clear();
|
self.pdl.clear();
|
||||||
return Some(
|
return Some(
|
||||||
n1.chars().next().cmp(&Some(c2))
|
n1.as_str().chars().next().cmp(&Some(c2))
|
||||||
.then(Ordering::Greater)
|
.then(Ordering::Greater)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -533,7 +533,7 @@ impl MachineState {
|
|||||||
} else {
|
} else {
|
||||||
self.pdl.clear();
|
self.pdl.clear();
|
||||||
return Some(
|
return Some(
|
||||||
Some(c1).cmp(&n2.chars().next())
|
Some(c1).cmp(&n2.as_str().chars().next())
|
||||||
.then(Ordering::Less)
|
.then(Ordering::Less)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -556,7 +556,7 @@ impl MachineState {
|
|||||||
} else {
|
} else {
|
||||||
self.pdl.clear();
|
self.pdl.clear();
|
||||||
return Some(
|
return Some(
|
||||||
Some(c1).cmp(&n2.chars().next())
|
Some(c1).cmp(&n2.as_str().chars().next())
|
||||||
.then(Ordering::Less)
|
.then(Ordering::Less)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -586,7 +586,7 @@ impl MachineState {
|
|||||||
} else {
|
} else {
|
||||||
self.pdl.clear();
|
self.pdl.clear();
|
||||||
return Some(
|
return Some(
|
||||||
n1.chars().next().cmp(&Some(c2))
|
n1.as_str().chars().next().cmp(&Some(c2))
|
||||||
.then(Ordering::Greater)
|
.then(Ordering::Greater)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -896,7 +896,7 @@ impl MachineState {
|
|||||||
|
|
||||||
let s = string.as_str();
|
let s = string.as_str();
|
||||||
|
|
||||||
match heap_pstr_iter.compare_pstr_to_string(s) {
|
match heap_pstr_iter.compare_pstr_to_string(&*s) {
|
||||||
Some(PStrPrefixCmpResult {
|
Some(PStrPrefixCmpResult {
|
||||||
focus,
|
focus,
|
||||||
offset,
|
offset,
|
||||||
@@ -1003,9 +1003,9 @@ impl MachineState {
|
|||||||
self.s_offset = 0;
|
self.s_offset = 0;
|
||||||
self.mode = MachineMode::Read;
|
self.mode = MachineMode::Read;
|
||||||
|
|
||||||
put_partial_string(&mut self.heap, pstr, &mut self.atom_tbl)
|
put_partial_string(&mut self.heap, pstr, &mut self.atom_tbl.blocking_write())
|
||||||
} else {
|
} else {
|
||||||
put_complete_string(&mut self.heap, pstr, &mut self.atom_tbl)
|
put_complete_string(&mut self.heap, pstr, &mut self.atom_tbl.blocking_write())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1097,7 +1097,7 @@ impl MachineState {
|
|||||||
(name, 0, 0)
|
(name, 0, 0)
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Char, c) => {
|
(HeapCellValueTag::Char, c) => {
|
||||||
(self.atom_tbl.build_with(&c.to_string()), 0, 0)
|
(self.atom_tbl.blocking_write().build_with(&c.to_string()), 0, 0)
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => {
|
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => {
|
||||||
let stub = functor_stub(atom!("call"), arity + 1);
|
let stub = functor_stub(atom!("call"), arity + 1);
|
||||||
@@ -1436,7 +1436,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Char, c) => {
|
(HeapCellValueTag::Char, c) => {
|
||||||
let c = self.atom_tbl.build_with(&c.to_string());
|
let c = self.atom_tbl.blocking_write().build_with(&c.to_string());
|
||||||
|
|
||||||
self.try_functor_fabricate_struct(
|
self.try_functor_fabricate_struct(
|
||||||
c,
|
c,
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ pub use crate::parser::ast::*;
|
|||||||
use crate::read::*;
|
use crate::read::*;
|
||||||
pub use crate::types::*;
|
pub use crate::types::*;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use crate::machine::copier::CopierTarget;
|
use crate::machine::copier::CopierTarget;
|
||||||
|
|
||||||
@@ -61,7 +63,7 @@ impl MockWAM {
|
|||||||
|
|
||||||
let mut printer = HCPrinter::new(
|
let mut printer = HCPrinter::new(
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
&mut self.machine_st.atom_tbl,
|
Arc::clone(&self.machine_st.atom_tbl),
|
||||||
&mut self.machine_st.stack,
|
&mut self.machine_st.stack,
|
||||||
&self.op_dir,
|
&self.op_dir,
|
||||||
PrinterOutputter::new(),
|
PrinterOutputter::new(),
|
||||||
|
|||||||
@@ -230,7 +230,8 @@ impl Machine {
|
|||||||
|
|
||||||
pub fn load_file(&mut self, path: &str, stream: Stream) {
|
pub fn load_file(&mut self, path: &str, stream: Stream) {
|
||||||
self.machine_st.registers[1] = stream_as_cell!(stream);
|
self.machine_st.registers[1] = stream_as_cell!(stream);
|
||||||
self.machine_st.registers[2] = atom_as_cell!(self.machine_st.atom_tbl.build_with(path));
|
self.machine_st.registers[2] =
|
||||||
|
atom_as_cell!(self.machine_st.atom_tbl.blocking_write().build_with(path));
|
||||||
|
|
||||||
self.run_module_predicate(atom!("loader"), (atom!("file_load"), 2));
|
self.run_module_predicate(atom!("loader"), (atom!("file_load"), 2));
|
||||||
}
|
}
|
||||||
@@ -295,7 +296,7 @@ impl Machine {
|
|||||||
arg_pstrs.push(put_complete_string(
|
arg_pstrs.push(put_complete_string(
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
&arg,
|
&arg,
|
||||||
&mut self.machine_st.atom_tbl,
|
&mut self.machine_st.atom_tbl.blocking_write(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ impl PartialString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn as_str_from(&self, n: usize) -> &str {
|
pub(crate) fn as_str_from(&self, n: usize) -> AtomString {
|
||||||
&self.0.as_str()[n..]
|
self.0.as_str().map(|str| &str[n..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
let s = &s[result.prefix_len..];
|
let s = &s[result.prefix_len..];
|
||||||
|
|
||||||
if s.len() >= t.len() {
|
if s.len() >= t.len() {
|
||||||
if s.starts_with(t) {
|
if (&*s).starts_with(&*t) {
|
||||||
result.prefix_len += t.len();
|
result.prefix_len += t.len();
|
||||||
result.offset += t.len();
|
result.offset += t.len();
|
||||||
} else {
|
} else {
|
||||||
@@ -229,7 +229,7 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
}
|
}
|
||||||
PStrIteratee::PStrSegment(_, pstr_atom, n) => {
|
PStrIteratee::PStrSegment(_, pstr_atom, n) => {
|
||||||
let pstr = PartialString::from(pstr_atom);
|
let pstr = PartialString::from(pstr_atom);
|
||||||
buf += pstr.as_str_from(n);
|
buf += &*pstr.as_str_from(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -714,7 +714,7 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
let str2 = pstr2.as_str_from(n2);
|
let str2 = pstr2.as_str_from(n2);
|
||||||
|
|
||||||
match str1.len().cmp(&str2.len()) {
|
match str1.len().cmp(&str2.len()) {
|
||||||
Ordering::Equal if str1 == str2 => {
|
Ordering::Equal if &*str1 == &*str2 => {
|
||||||
cycle_detection_step(i1, i2, &step_1);
|
cycle_detection_step(i1, i2, &step_1);
|
||||||
let both_cyclic = cycle_detection_step(i2, i1, &step_2);
|
let both_cyclic = cycle_detection_step(i2, i1, &step_2);
|
||||||
|
|
||||||
@@ -725,7 +725,7 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ordering::Less if str2.starts_with(str1) => {
|
Ordering::Less if str2.starts_with(&*str1) => {
|
||||||
step_2.iteratee =
|
step_2.iteratee =
|
||||||
PStrIteratee::PStrSegment(f2, pstr2_atom, n2 + str1.len());
|
PStrIteratee::PStrSegment(f2, pstr2_atom, n2 + str1.len());
|
||||||
let c1_result = cycle_detection_step(i1, i2, &step_1);
|
let c1_result = cycle_detection_step(i1, i2, &step_1);
|
||||||
@@ -735,7 +735,7 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ordering::Greater if str1.starts_with(str2) => {
|
Ordering::Greater if str1.starts_with(&*str2) => {
|
||||||
step_1.iteratee =
|
step_1.iteratee =
|
||||||
PStrIteratee::PStrSegment(f1, pstr1_atom, n1 + str2.len());
|
PStrIteratee::PStrSegment(f1, pstr1_atom, n1 + str2.len());
|
||||||
let c2_result = cycle_detection_step(i2, i1, &step_2);
|
let c2_result = cycle_detection_step(i2, i1, &step_2);
|
||||||
@@ -746,7 +746,7 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return PStrCmpResult::Ordered(str1.cmp(str2));
|
return PStrCmpResult::Ordered(str1.cmp(&*str2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -808,7 +808,7 @@ mod test {
|
|||||||
let pstr_var_cell = put_partial_string(
|
let pstr_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc ",
|
"abc ",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
||||||
@@ -831,7 +831,7 @@ mod test {
|
|||||||
let pstr_second_var_cell = put_partial_string(
|
let pstr_second_var_cell = put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"def",
|
"def",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
||||||
@@ -913,13 +913,21 @@ mod test {
|
|||||||
// construct a structurally similar but different cyclic partial string
|
// construct a structurally similar but different cyclic partial string
|
||||||
// matching the one beginning at wam.machine_st.heap[0].
|
// matching the one beginning at wam.machine_st.heap[0].
|
||||||
|
|
||||||
put_partial_string(&mut wam.machine_st.heap, "ab", &mut wam.machine_st.atom_tbl);
|
put_partial_string(
|
||||||
|
&mut wam.machine_st.heap,
|
||||||
|
"ab",
|
||||||
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
|
);
|
||||||
|
|
||||||
wam.machine_st.heap.pop();
|
wam.machine_st.heap.pop();
|
||||||
|
|
||||||
wam.machine_st.heap.push(pstr_loc_as_cell!(second_h + 2));
|
wam.machine_st.heap.push(pstr_loc_as_cell!(second_h + 2));
|
||||||
|
|
||||||
put_partial_string(&mut wam.machine_st.heap, "c ", &mut wam.machine_st.atom_tbl);
|
put_partial_string(
|
||||||
|
&mut wam.machine_st.heap,
|
||||||
|
"c ",
|
||||||
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
|
);
|
||||||
|
|
||||||
wam.machine_st.heap.pop();
|
wam.machine_st.heap.pop();
|
||||||
|
|
||||||
@@ -947,7 +955,7 @@ mod test {
|
|||||||
put_partial_string(
|
put_partial_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc ",
|
"abc ",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let pstr_cell = wam.machine_st.heap[0];
|
let pstr_cell = wam.machine_st.heap[0];
|
||||||
@@ -981,7 +989,7 @@ mod test {
|
|||||||
let cstr_var_cell = put_complete_string(
|
let cstr_var_cell = put_complete_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc",
|
"abc",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
wam.machine_st.heap.push(list_loc_as_cell!(2));
|
wam.machine_st.heap.push(list_loc_as_cell!(2));
|
||||||
@@ -1010,7 +1018,7 @@ mod test {
|
|||||||
let cstr_var_cell = put_complete_string(
|
let cstr_var_cell = put_complete_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc",
|
"abc",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
wam.machine_st.heap.push(list_loc_as_cell!(2));
|
wam.machine_st.heap.push(list_loc_as_cell!(2));
|
||||||
@@ -1040,8 +1048,11 @@ mod test {
|
|||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
let cstr_var_cell =
|
let cstr_var_cell = put_complete_string(
|
||||||
put_complete_string(&mut wam.machine_st.heap, "d", &mut wam.machine_st.atom_tbl);
|
&mut wam.machine_st.heap,
|
||||||
|
"d",
|
||||||
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
|
);
|
||||||
|
|
||||||
wam.machine_st.heap.push(list_loc_as_cell!(2));
|
wam.machine_st.heap.push(list_loc_as_cell!(2));
|
||||||
wam.machine_st.heap.push(char_as_cell!('d'));
|
wam.machine_st.heap.push(char_as_cell!('d'));
|
||||||
@@ -1058,7 +1069,7 @@ mod test {
|
|||||||
let cstr_var_cell = put_complete_string(
|
let cstr_var_cell = put_complete_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abc",
|
"abc",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
wam.machine_st.heap.push(list_loc_as_cell!(2));
|
wam.machine_st.heap.push(list_loc_as_cell!(2));
|
||||||
@@ -1089,7 +1100,7 @@ mod test {
|
|||||||
put_complete_string(
|
put_complete_string(
|
||||||
&mut wam.machine_st.heap,
|
&mut wam.machine_st.heap,
|
||||||
"abcdef",
|
"abcdef",
|
||||||
&mut wam.machine_st.atom_tbl,
|
&mut wam.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
wam.machine_st.heap.push(pstr_as_cell!(atom!("abc")));
|
wam.machine_st.heap.push(pstr_as_cell!(atom!("abc")));
|
||||||
|
|||||||
@@ -313,11 +313,17 @@ pub(super) fn setup_declaration<'a, LS: LoadState<'a>>(
|
|||||||
}
|
}
|
||||||
(atom!("module"), 2) => {
|
(atom!("module"), 2) => {
|
||||||
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
|
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
|
||||||
Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?))
|
Ok(Declaration::Module(setup_module_decl(
|
||||||
|
terms,
|
||||||
|
&mut atom_tbl.blocking_write(),
|
||||||
|
)?))
|
||||||
}
|
}
|
||||||
(atom!("op"), 3) => {
|
(atom!("op"), 3) => {
|
||||||
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
|
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
|
||||||
Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?))
|
Ok(Declaration::Op(setup_op_decl(
|
||||||
|
terms,
|
||||||
|
&mut atom_tbl.blocking_write(),
|
||||||
|
)?))
|
||||||
}
|
}
|
||||||
(atom!("non_counted_backtracking"), 1) => {
|
(atom!("non_counted_backtracking"), 1) => {
|
||||||
let (name, arity) = setup_predicate_indicator(&mut terms.pop().unwrap())?;
|
let (name, arity) = setup_predicate_indicator(&mut terms.pop().unwrap())?;
|
||||||
@@ -326,7 +332,8 @@ pub(super) fn setup_declaration<'a, LS: LoadState<'a>>(
|
|||||||
(atom!("use_module"), 1) => Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
|
(atom!("use_module"), 1) => Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
|
||||||
(atom!("use_module"), 2) => {
|
(atom!("use_module"), 2) => {
|
||||||
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
|
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
|
||||||
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
|
let (name, exports) =
|
||||||
|
setup_qualified_import(terms, &mut atom_tbl.blocking_write())?;
|
||||||
|
|
||||||
Ok(Declaration::UseQualifiedModule(name, exports))
|
Ok(Declaration::UseQualifiedModule(name, exports))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1853,7 +1853,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let file = match open_options.open(file_spec.as_str()) {
|
let file = match open_options.open(&*file_spec.as_str()) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
match err.kind() {
|
match err.kind() {
|
||||||
|
|||||||
@@ -1529,7 +1529,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Char, c) => {
|
(HeapCellValueTag::Char, c) => {
|
||||||
let name = self.machine_st.atom_tbl.build_with(&c.to_string());
|
let name = self.machine_st.atom_tbl.blocking_write().build_with(&c.to_string());
|
||||||
|
|
||||||
let h = self.machine_st.heap.len();
|
let h = self.machine_st.heap.len();
|
||||||
self.machine_st.heap.push(atom_as_cell!(name));
|
self.machine_st.heap.push(atom_as_cell!(name));
|
||||||
@@ -1804,7 +1804,7 @@ impl Machine {
|
|||||||
match hostname::get().ok() {
|
match hostname::get().ok() {
|
||||||
Some(host) => match host.to_str() {
|
Some(host) => match host.to_str() {
|
||||||
Some(host) => {
|
Some(host) => {
|
||||||
let hostname = self.machine_st.atom_tbl.build_with(host);
|
let hostname = self.machine_st.atom_tbl.blocking_write().build_with(host);
|
||||||
|
|
||||||
let a1 = self.deref_register(1);
|
let a1 = self.deref_register(1);
|
||||||
self.machine_st.unify_atom(hostname, a1);
|
self.machine_st.unify_atom(hostname, a1);
|
||||||
@@ -1895,14 +1895,15 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[1])
|
.value_to_str_like(self.machine_st.registers[1])
|
||||||
{
|
{
|
||||||
let path = std::path::Path::new(dir.as_str());
|
let str = dir.as_str();
|
||||||
|
let path = std::path::Path::new(&*str);
|
||||||
let mut files = Vec::new();
|
let mut files = Vec::new();
|
||||||
|
|
||||||
if let Ok(entries) = fs::read_dir(path) {
|
if let Ok(entries) = fs::read_dir(path) {
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
if let Ok(entry) = entry {
|
if let Ok(entry) = entry {
|
||||||
if let Some(name) = entry.file_name().to_str() {
|
if let Some(name) = entry.file_name().to_str() {
|
||||||
let name = self.machine_st.atom_tbl.build_with(name);
|
let name = self.machine_st.atom_tbl.blocking_write().build_with(name);
|
||||||
files.push(atom_as_cstr_cell!(name));
|
files.push(atom_as_cstr_cell!(name));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@@ -1937,7 +1938,7 @@ impl Machine {
|
|||||||
.value_to_str_like(self.machine_st.registers[1])
|
.value_to_str_like(self.machine_st.registers[1])
|
||||||
{
|
{
|
||||||
let len = Number::arena_from(
|
let len = Number::arena_from(
|
||||||
fs::metadata(file.as_str()).unwrap().len(),
|
fs::metadata(&*file.as_str()).unwrap().len(),
|
||||||
&mut self.machine_st.arena,
|
&mut self.machine_st.arena,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1963,8 +1964,8 @@ impl Machine {
|
|||||||
{
|
{
|
||||||
let file_str = file.as_str();
|
let file_str = file.as_str();
|
||||||
|
|
||||||
if !std::path::Path::new(file_str).exists()
|
if !std::path::Path::new(&*file_str).exists()
|
||||||
|| !fs::metadata(file_str).unwrap().is_file()
|
|| !fs::metadata(&*file_str).unwrap().is_file()
|
||||||
{
|
{
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
}
|
}
|
||||||
@@ -1981,7 +1982,9 @@ impl Machine {
|
|||||||
{
|
{
|
||||||
let dir_str = dir.as_str();
|
let dir_str = dir.as_str();
|
||||||
|
|
||||||
if !std::path::Path::new(dir_str).exists() || !fs::metadata(dir_str).unwrap().is_dir() {
|
if !std::path::Path::new(&*dir_str).exists()
|
||||||
|
|| !fs::metadata(&*dir_str).unwrap().is_dir()
|
||||||
|
{
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1997,7 +2000,7 @@ impl Machine {
|
|||||||
{
|
{
|
||||||
let which = cell_as_atom!(self.deref_register(2));
|
let which = cell_as_atom!(self.deref_register(2));
|
||||||
|
|
||||||
if let Ok(md) = fs::metadata(file.as_str()) {
|
if let Ok(md) = fs::metadata(&*file.as_str()) {
|
||||||
if let Ok(time) = match which {
|
if let Ok(time) = match which {
|
||||||
atom!("modification") => md.modified(),
|
atom!("modification") => md.modified(),
|
||||||
atom!("access") => md.accessed(),
|
atom!("access") => md.accessed(),
|
||||||
@@ -2031,7 +2034,7 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[1])
|
.value_to_str_like(self.machine_st.registers[1])
|
||||||
{
|
{
|
||||||
match fs::create_dir(dir.as_str()) {
|
match fs::create_dir(&*dir.as_str()) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
_ => {
|
_ => {
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
@@ -2048,7 +2051,7 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[1])
|
.value_to_str_like(self.machine_st.registers[1])
|
||||||
{
|
{
|
||||||
match fs::create_dir_all(dir.as_str()) {
|
match fs::create_dir_all(&*dir.as_str()) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
_ => {
|
_ => {
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
@@ -2065,7 +2068,7 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[1])
|
.value_to_str_like(self.machine_st.registers[1])
|
||||||
{
|
{
|
||||||
match fs::remove_file(file.as_str()) {
|
match fs::remove_file(&*file.as_str()) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
_ => {
|
_ => {
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
@@ -2084,7 +2087,7 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[2])
|
.value_to_str_like(self.machine_st.registers[2])
|
||||||
{
|
{
|
||||||
if fs::rename(file.as_str(), renamed.as_str()).is_ok() {
|
if fs::rename(&*file.as_str(), &*renamed.as_str()).is_ok() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2103,7 +2106,7 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[2])
|
.value_to_str_like(self.machine_st.registers[2])
|
||||||
{
|
{
|
||||||
if fs::copy(file.as_str(), copied.as_str()).is_ok() {
|
if fs::copy(&*file.as_str(), &*copied.as_str()).is_ok() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2118,7 +2121,7 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[1])
|
.value_to_str_like(self.machine_st.registers[1])
|
||||||
{
|
{
|
||||||
match fs::remove_dir(dir.as_str()) {
|
match fs::remove_dir(&*dir.as_str()) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
_ => {
|
_ => {
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
@@ -2141,7 +2144,11 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let current_atom = self.machine_st.atom_tbl.build_with(¤t);
|
let current_atom = self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(¤t);
|
||||||
|
|
||||||
let a1 = self.deref_register(1);
|
let a1 = self.deref_register(1);
|
||||||
self.machine_st.unify_complete_string(current_atom, a1);
|
self.machine_st.unify_complete_string(current_atom, a1);
|
||||||
@@ -2153,7 +2160,7 @@ impl Machine {
|
|||||||
let target = self.deref_register(2);
|
let target = self.deref_register(2);
|
||||||
|
|
||||||
if let Some(next) = self.machine_st.value_to_str_like(target) {
|
if let Some(next) = self.machine_st.value_to_str_like(target) {
|
||||||
if env::set_current_dir(std::path::Path::new(next.as_str())).is_ok() {
|
if env::set_current_dir(std::path::Path::new(&*next.as_str())).is_ok() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2169,7 +2176,7 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[1])
|
.value_to_str_like(self.machine_st.registers[1])
|
||||||
{
|
{
|
||||||
match fs::canonicalize(path.as_str()) {
|
match fs::canonicalize(&*path.as_str()) {
|
||||||
Ok(canonical) => {
|
Ok(canonical) => {
|
||||||
let cs = match canonical.to_str() {
|
let cs = match canonical.to_str() {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
@@ -2182,7 +2189,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let canonical_atom = self.machine_st.atom_tbl.build_with(cs);
|
let canonical_atom = self.machine_st.atom_tbl.blocking_write().build_with(cs);
|
||||||
|
|
||||||
let a2 = self.deref_register(2);
|
let a2 = self.deref_register(2);
|
||||||
self.machine_st.unify_complete_string(canonical_atom, a2);
|
self.machine_st.unify_complete_string(canonical_atom, a2);
|
||||||
@@ -2241,13 +2248,13 @@ impl Machine {
|
|||||||
let atom_cell = match str_like {
|
let atom_cell = match str_like {
|
||||||
AtomOrString::Atom(atom) => {
|
AtomOrString::Atom(atom) => {
|
||||||
atom_as_cell!(if atom == atom!("[]") {
|
atom_as_cell!(if atom == atom!("[]") {
|
||||||
self.machine_st.atom_tbl.build_with("")
|
self.machine_st.atom_tbl.blocking_write().build_with("")
|
||||||
} else {
|
} else {
|
||||||
atom
|
atom
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
AtomOrString::String(string) => {
|
AtomOrString::String(string) => {
|
||||||
atom_as_cell!(self.machine_st.atom_tbl.build_with(&string))
|
atom_as_cell!(self.machine_st.atom_tbl.blocking_write().build_with(&string))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2278,6 +2285,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
(HeapCellValueTag::Atom, (name, arity)) => {
|
(HeapCellValueTag::Atom, (name, arity)) => {
|
||||||
if arity == 0 {
|
if arity == 0 {
|
||||||
|
let name = name.as_str();
|
||||||
let iter = name.chars()
|
let iter = name.chars()
|
||||||
.map(|c| fixnum_as_cell!(Fixnum::build_with(c as i64)));
|
.map(|c| fixnum_as_cell!(Fixnum::build_with(c as i64)));
|
||||||
|
|
||||||
@@ -2292,6 +2300,7 @@ impl Machine {
|
|||||||
.get_name_and_arity();
|
.get_name_and_arity();
|
||||||
|
|
||||||
if arity == 0 {
|
if arity == 0 {
|
||||||
|
let name = name.as_str();
|
||||||
let iter = name.chars()
|
let iter = name.chars()
|
||||||
.map(|c| fixnum_as_cell!(Fixnum::build_with(c as i64)));
|
.map(|c| fixnum_as_cell!(Fixnum::build_with(c as i64)));
|
||||||
|
|
||||||
@@ -2307,7 +2316,7 @@ impl Machine {
|
|||||||
match self.machine_st.try_from_list(self.machine_st.registers[2], stub_gen) {
|
match self.machine_st.try_from_list(self.machine_st.registers[2], stub_gen) {
|
||||||
Ok(addrs) => {
|
Ok(addrs) => {
|
||||||
let string = self.machine_st.codes_to_string(addrs.into_iter(), stub_gen)?;
|
let string = self.machine_st.codes_to_string(addrs.into_iter(), stub_gen)?;
|
||||||
let atom = self.machine_st.atom_tbl.build_with(&string);
|
let atom = self.machine_st.atom_tbl.blocking_write().build_with(&string);
|
||||||
|
|
||||||
self.machine_st.bind(a1.as_var().unwrap(), atom_as_cell!(atom));
|
self.machine_st.bind(a1.as_var().unwrap(), atom_as_cell!(atom));
|
||||||
}
|
}
|
||||||
@@ -2334,7 +2343,7 @@ impl Machine {
|
|||||||
.get_name_and_arity();
|
.get_name_and_arity();
|
||||||
|
|
||||||
if arity == 0 {
|
if arity == 0 {
|
||||||
name.chars().count() as i64
|
name.as_str().chars().count() as i64
|
||||||
} else {
|
} else {
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
return;
|
return;
|
||||||
@@ -2342,7 +2351,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
(HeapCellValueTag::Atom, (name, arity)) => {
|
(HeapCellValueTag::Atom, (name, arity)) => {
|
||||||
if arity == 0 {
|
if arity == 0 {
|
||||||
name.chars().count() as i64
|
name.as_str().chars().count() as i64
|
||||||
} else {
|
} else {
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
return;
|
return;
|
||||||
@@ -2392,7 +2401,7 @@ impl Machine {
|
|||||||
let atom_or_string = self.machine_st.value_to_str_like(a1).unwrap();
|
let atom_or_string = self.machine_st.value_to_str_like(a1).unwrap();
|
||||||
|
|
||||||
self.machine_st
|
self.machine_st
|
||||||
.parse_number_from_string(atom_or_string.as_str(), &self.indices, stub_gen)
|
.parse_number_from_string(&*atom_or_string.as_str(), &self.indices, stub_gen)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -2801,7 +2810,11 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let chars_atom = self.machine_st.atom_tbl.build_with(&string.trim());
|
let chars_atom = self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(&string.trim());
|
||||||
self.machine_st.unify_complete_string(chars_atom, chs);
|
self.machine_st.unify_complete_string(chars_atom, chs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3027,14 +3040,14 @@ impl Machine {
|
|||||||
match (name, arity) {
|
match (name, arity) {
|
||||||
(atom!("to_upper"), 1) => {
|
(atom!("to_upper"), 1) => {
|
||||||
let reg = self.machine_st.deref(self.machine_st.heap[s+1]);
|
let reg = self.machine_st.deref(self.machine_st.heap[s+1]);
|
||||||
let atom = self.machine_st.atom_tbl.build_with(&c.to_uppercase().to_string());
|
let atom = self.machine_st.atom_tbl.blocking_write().build_with(&c.to_uppercase().to_string());
|
||||||
let upper_str = string_as_cstr_cell!(atom);
|
let upper_str = string_as_cstr_cell!(atom);
|
||||||
unify!(self.machine_st, reg, upper_str);
|
unify!(self.machine_st, reg, upper_str);
|
||||||
self.machine_st.fail = false;
|
self.machine_st.fail = false;
|
||||||
}
|
}
|
||||||
(atom!("to_lower"), 1) => {
|
(atom!("to_lower"), 1) => {
|
||||||
let reg = self.machine_st.deref(self.machine_st.heap[s+1]);
|
let reg = self.machine_st.deref(self.machine_st.heap[s+1]);
|
||||||
let atom = self.machine_st.atom_tbl.build_with(&c.to_lowercase().to_string());
|
let atom = self.machine_st.atom_tbl.blocking_write().build_with(&c.to_lowercase().to_string());
|
||||||
let lower_str = string_as_cstr_cell!(atom);
|
let lower_str = string_as_cstr_cell!(atom);
|
||||||
unify!(self.machine_st, reg, lower_str);
|
unify!(self.machine_st, reg, lower_str);
|
||||||
self.machine_st.fail = false;
|
self.machine_st.fail = false;
|
||||||
@@ -3557,7 +3570,11 @@ impl Machine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let output = self.deref_register(3);
|
let output = self.deref_register(3);
|
||||||
let atom = self.machine_st.atom_tbl.build_with(&string);
|
let atom = self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(&string);
|
||||||
|
|
||||||
self.machine_st.unify_complete_string(atom, output);
|
self.machine_st.unify_complete_string(atom, output);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -4052,7 +4069,7 @@ impl Machine {
|
|||||||
cell_as_atom!(self.machine_st.heap[s])
|
cell_as_atom!(self.machine_st.heap[s])
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Char, c) => {
|
(HeapCellValueTag::Char, c) => {
|
||||||
self.machine_st.atom_tbl.build_with(&c.to_string())
|
self.machine_st.atom_tbl.blocking_write().build_with(&c.to_string())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -4374,7 +4391,7 @@ impl Machine {
|
|||||||
(HeapCellValueTag::Str, s) => {
|
(HeapCellValueTag::Str, s) => {
|
||||||
let name = cell_as_atom_cell!(self.machine_st.heap[s]).get_name();
|
let name = cell_as_atom_cell!(self.machine_st.heap[s]).get_name();
|
||||||
let value = self.machine_st.value_to_str_like(self.machine_st.heap[s + 1]).unwrap();
|
let value = self.machine_st.value_to_str_like(self.machine_st.heap[s + 1]).unwrap();
|
||||||
header_map.insert(HeaderName::from_str(name.as_str()).unwrap(), HeaderValue::from_str(value.as_str()).unwrap());
|
header_map.insert(HeaderName::from_str(&*name.as_str()).unwrap(), HeaderValue::from_str(&*value.as_str()).unwrap());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -4414,10 +4431,14 @@ impl Machine {
|
|||||||
let h = self.machine_st.heap.len();
|
let h = self.machine_st.heap.len();
|
||||||
|
|
||||||
let header_term = functor!(
|
let header_term = functor!(
|
||||||
self.machine_st.atom_tbl.build_with(header_name.as_str()),
|
self.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(header_name.as_str()),
|
||||||
[cell(string_as_cstr_cell!(self
|
[cell(string_as_cstr_cell!(self
|
||||||
.machine_st
|
.machine_st
|
||||||
.atom_tbl
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
.build_with(header_value.to_str().unwrap())))]
|
.build_with(header_value.to_str().unwrap())))]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -4437,7 +4458,10 @@ impl Machine {
|
|||||||
let reader = resp.bytes().unwrap().reader();
|
let reader = resp.bytes().unwrap().reader();
|
||||||
|
|
||||||
let mut stream = Stream::from_http_stream(
|
let mut stream = Stream::from_http_stream(
|
||||||
self.machine_st.atom_tbl.build_with(&address_string),
|
self.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(&address_string),
|
||||||
Box::new(reader),
|
Box::new(reader),
|
||||||
&mut self.machine_st.arena,
|
&mut self.machine_st.arena,
|
||||||
);
|
);
|
||||||
@@ -4554,14 +4578,14 @@ impl Machine {
|
|||||||
Method::HEAD => atom!("head"),
|
Method::HEAD => atom!("head"),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let path_atom = self.machine_st.atom_tbl.build_with(request.request.uri().path());
|
let path_atom = self.machine_st.atom_tbl.blocking_write().build_with(request.request.uri().path());
|
||||||
let path_cell = atom_as_cstr_cell!(path_atom);
|
let path_cell = atom_as_cstr_cell!(path_atom);
|
||||||
let headers: Vec<HeapCellValue> = request.request.headers().iter().map(|(header_name, header_value)| {
|
let headers: Vec<HeapCellValue> = request.request.headers().iter().map(|(header_name, header_value)| {
|
||||||
let h = self.machine_st.heap.len();
|
let h = self.machine_st.heap.len();
|
||||||
|
|
||||||
let header_term = functor!(
|
let header_term = functor!(
|
||||||
self.machine_st.atom_tbl.build_with(header_name.as_str()),
|
self.machine_st.atom_tbl.blocking_write().build_with(header_name.as_str()),
|
||||||
[cell(string_as_cstr_cell!(self.machine_st.atom_tbl.build_with(header_value.to_str().unwrap())))]
|
[cell(string_as_cstr_cell!(self.machine_st.atom_tbl.blocking_write().build_with(header_value.to_str().unwrap())))]
|
||||||
);
|
);
|
||||||
|
|
||||||
self.machine_st.heap.extend(header_term.into_iter());
|
self.machine_st.heap.extend(header_term.into_iter());
|
||||||
@@ -4571,7 +4595,7 @@ impl Machine {
|
|||||||
let headers_list = iter_to_heap_list(&mut self.machine_st.heap, headers.into_iter());
|
let headers_list = iter_to_heap_list(&mut self.machine_st.heap, headers.into_iter());
|
||||||
|
|
||||||
let query_str = request.request.uri().query().unwrap_or("");
|
let query_str = request.request.uri().query().unwrap_or("");
|
||||||
let query_atom = self.machine_st.atom_tbl.build_with(query_str);
|
let query_atom = self.machine_st.atom_tbl.blocking_write().build_with(query_str);
|
||||||
let query_cell = string_as_cstr_cell!(query_atom);
|
let query_cell = string_as_cstr_cell!(query_atom);
|
||||||
|
|
||||||
let hyper_req = request.request;
|
let hyper_req = request.request;
|
||||||
@@ -4642,7 +4666,7 @@ impl Machine {
|
|||||||
(HeapCellValueTag::Str, s) => {
|
(HeapCellValueTag::Str, s) => {
|
||||||
let name = cell_as_atom_cell!(self.machine_st.heap[s]).get_name();
|
let name = cell_as_atom_cell!(self.machine_st.heap[s]).get_name();
|
||||||
let value = self.machine_st.value_to_str_like(self.machine_st.heap[s + 1]).unwrap();
|
let value = self.machine_st.value_to_str_like(self.machine_st.heap[s + 1]).unwrap();
|
||||||
header_map.insert(HeaderName::from_str(name.as_str()).unwrap(), HeaderValue::from_str(value.as_str()).unwrap());
|
header_map.insert(HeaderName::from_str(&*name.as_str()).unwrap(), HeaderValue::from_str(&*value.as_str()).unwrap());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -4722,7 +4746,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
if let Ok(_) = self
|
if let Ok(_) = self
|
||||||
.foreign_function_table
|
.foreign_function_table
|
||||||
.load_library(library_name.as_str(), &functions)
|
.load_library(&*library_name.as_str(), &functions)
|
||||||
{
|
{
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -4752,7 +4776,7 @@ impl Machine {
|
|||||||
_ => {
|
_ => {
|
||||||
let stub_gen = || functor_stub(atom!("foreign_call"), 3);
|
let stub_gen = || functor_stub(atom!("foreign_call"), 3);
|
||||||
if let Some(string) = machine_st.value_to_str_like(source) {
|
if let Some(string) = machine_st.value_to_str_like(source) {
|
||||||
Value::CString(CString::new(string.as_str()).unwrap())
|
Value::CString(CString::new(&*string.as_str()).unwrap())
|
||||||
} else {
|
} else {
|
||||||
match machine_st.try_from_list(source, stub_gen) {
|
match machine_st.try_from_list(source, stub_gen) {
|
||||||
Ok(args) => {
|
Ok(args) => {
|
||||||
@@ -4785,7 +4809,7 @@ impl Machine {
|
|||||||
.collect();
|
.collect();
|
||||||
match self
|
match self
|
||||||
.foreign_function_table
|
.foreign_function_table
|
||||||
.exec(function_name.as_str(), args)
|
.exec(&*function_name.as_str(), args)
|
||||||
{
|
{
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
match result {
|
match result {
|
||||||
@@ -4801,8 +4825,11 @@ impl Machine {
|
|||||||
unify!(self.machine_st, return_value, struct_value);
|
unify!(self.machine_st, return_value, struct_value);
|
||||||
}
|
}
|
||||||
Value::CString(cstr) => {
|
Value::CString(cstr) => {
|
||||||
let cstr =
|
let cstr = self
|
||||||
self.machine_st.atom_tbl.build_with(cstr.to_str().unwrap());
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(cstr.to_str().unwrap());
|
||||||
self.machine_st.unify_complete_string(cstr, return_value);
|
self.machine_st.unify_complete_string(cstr, return_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4834,6 +4861,7 @@ impl Machine {
|
|||||||
Value::CString(cstr) => atom_as_cell!(self
|
Value::CString(cstr) => atom_as_cell!(self
|
||||||
.machine_st
|
.machine_st
|
||||||
.atom_tbl
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
.build_with(&cstr.into_string().unwrap())),
|
.build_with(&cstr.into_string().unwrap())),
|
||||||
Value::Struct(name, struct_args) => self.build_struct(&name, struct_args),
|
Value::Struct(name, struct_args) => self.build_struct(&name, struct_args),
|
||||||
})
|
})
|
||||||
@@ -4863,7 +4891,7 @@ impl Machine {
|
|||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
};
|
};
|
||||||
self.foreign_function_table
|
self.foreign_function_table
|
||||||
.define_struct(struct_name.as_str(), fields);
|
.define_struct(&*struct_name.as_str(), fields);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
@@ -4890,7 +4918,7 @@ impl Machine {
|
|||||||
let src_sink = self.deref_register(1);
|
let src_sink = self.deref_register(1);
|
||||||
|
|
||||||
if let Some(file_spec) = self.machine_st.value_to_str_like(src_sink) {
|
if let Some(file_spec) = self.machine_st.value_to_str_like(src_sink) {
|
||||||
let file_spec = file_spec.as_atom(&mut self.machine_st.atom_tbl);
|
let file_spec = file_spec.as_atom(&mut self.machine_st.atom_tbl.blocking_write());
|
||||||
|
|
||||||
let mut stream =
|
let mut stream =
|
||||||
self.machine_st
|
self.machine_st
|
||||||
@@ -4933,7 +4961,7 @@ impl Machine {
|
|||||||
|
|
||||||
let op = read_heap_cell!(self.deref_register(3),
|
let op = read_heap_cell!(self.deref_register(3),
|
||||||
(HeapCellValueTag::Char, c) => {
|
(HeapCellValueTag::Char, c) => {
|
||||||
self.machine_st.atom_tbl.build_with(&c.to_string())
|
self.machine_st.atom_tbl.blocking_write().build_with(&c.to_string())
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Atom, (name, _arity)) => {
|
(HeapCellValueTag::Atom, (name, _arity)) => {
|
||||||
name
|
name
|
||||||
@@ -6103,7 +6131,7 @@ impl Machine {
|
|||||||
write_term_to_heap(
|
write_term_to_heap(
|
||||||
&term,
|
&term,
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
&mut self.machine_st.atom_tbl,
|
&mut self.machine_st.atom_tbl.blocking_write(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -6268,7 +6296,7 @@ impl Machine {
|
|||||||
name
|
name
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.machine_st.atom_tbl.build_with(&match Number::try_from(port) {
|
self.machine_st.atom_tbl.blocking_write().build_with(&match Number::try_from(port) {
|
||||||
Ok(Number::Fixnum(n)) => n.get_num().to_string(),
|
Ok(Number::Fixnum(n)) => n.get_num().to_string(),
|
||||||
Ok(Number::Integer(n)) => n.to_string(),
|
Ok(Number::Integer(n)) => n.to_string(),
|
||||||
_ => {
|
_ => {
|
||||||
@@ -6282,7 +6310,10 @@ impl Machine {
|
|||||||
atom!("127.0.0.1:80")
|
atom!("127.0.0.1:80")
|
||||||
} else {
|
} else {
|
||||||
let buffer = format!("{}:{}", socket_atom.as_str(), port.as_str());
|
let buffer = format!("{}:{}", socket_atom.as_str(), port.as_str());
|
||||||
self.machine_st.atom_tbl.build_with(&buffer)
|
self.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(&buffer)
|
||||||
};
|
};
|
||||||
|
|
||||||
let alias = self.machine_st.registers[4];
|
let alias = self.machine_st.registers[4];
|
||||||
@@ -6310,7 +6341,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let stream = match TcpStream::connect(socket_addr.as_str()).map_err(|e| e.kind()) {
|
let stream = match TcpStream::connect(&*socket_addr.as_str()).map_err(|e| e.kind()) {
|
||||||
Ok(tcp_stream) => {
|
Ok(tcp_stream) => {
|
||||||
let mut stream =
|
let mut stream =
|
||||||
Stream::from_tcp_stream(socket_addr, tcp_stream, &mut self.machine_st.arena);
|
Stream::from_tcp_stream(socket_addr, tcp_stream, &mut self.machine_st.arena);
|
||||||
@@ -6464,7 +6495,7 @@ impl Machine {
|
|||||||
(ArenaHeaderTag::TcpListener, tcp_listener) => {
|
(ArenaHeaderTag::TcpListener, tcp_listener) => {
|
||||||
match tcp_listener.accept().ok() {
|
match tcp_listener.accept().ok() {
|
||||||
Some((tcp_stream, socket_addr)) => {
|
Some((tcp_stream, socket_addr)) => {
|
||||||
let client = self.machine_st.atom_tbl.build_with(&socket_addr.to_string());
|
let client = self.machine_st.atom_tbl.blocking_write().build_with(&socket_addr.to_string());
|
||||||
|
|
||||||
let mut tcp_stream = Stream::from_tcp_stream(
|
let mut tcp_stream = Stream::from_tcp_stream(
|
||||||
client,
|
client,
|
||||||
@@ -6520,7 +6551,7 @@ impl Machine {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
let connector = TlsConnector::new().unwrap();
|
let connector = TlsConnector::new().unwrap();
|
||||||
let stream = match connector.connect(hostname.as_str(), stream0) {
|
let stream = match connector.connect(&*hostname.as_str(), stream0) {
|
||||||
Ok(tls_stream) => tls_stream,
|
Ok(tls_stream) => tls_stream,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return Err(self.machine_st.open_permission_error(
|
return Err(self.machine_st.open_permission_error(
|
||||||
@@ -6555,7 +6586,7 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[2])
|
.value_to_str_like(self.machine_st.registers[2])
|
||||||
{
|
{
|
||||||
let identity = match Identity::from_pkcs12(&pkcs12, password.as_str()) {
|
let identity = match Identity::from_pkcs12(&pkcs12, &*password.as_str()) {
|
||||||
Ok(identity) => identity,
|
Ok(identity) => identity,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return Err(self.machine_st.open_permission_error(
|
return Err(self.machine_st.open_permission_error(
|
||||||
@@ -7088,7 +7119,7 @@ impl Machine {
|
|||||||
let chars = put_complete_string(
|
let chars = put_complete_string(
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
&result,
|
&result,
|
||||||
&mut self.machine_st.atom_tbl,
|
&mut self.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let result_addr = self.deref_register(1);
|
let result_addr = self.deref_register(1);
|
||||||
@@ -7107,7 +7138,7 @@ impl Machine {
|
|||||||
use git_version::git_version;
|
use git_version::git_version;
|
||||||
|
|
||||||
let buffer = git_version!(cargo_prefix = "cargo:", fallback = "unknown");
|
let buffer = git_version!(cargo_prefix = "cargo:", fallback = "unknown");
|
||||||
let buffer_atom = self.machine_st.atom_tbl.build_with(buffer);
|
let buffer_atom = self.machine_st.atom_tbl.blocking_write().build_with(buffer);
|
||||||
|
|
||||||
let a1 = self.deref_register(1);
|
let a1 = self.deref_register(1);
|
||||||
self.machine_st.unify_complete_string(buffer_atom, a1);
|
self.machine_st.unify_complete_string(buffer_atom, a1);
|
||||||
@@ -7472,7 +7503,11 @@ impl Machine {
|
|||||||
if buffer.len() == 0 {
|
if buffer.len() == 0 {
|
||||||
empty_list_as_cell!()
|
empty_list_as_cell!()
|
||||||
} else {
|
} else {
|
||||||
atom_as_cstr_cell!(self.machine_st.atom_tbl.build_with(&buffer))
|
atom_as_cstr_cell!(self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(&buffer))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -7609,7 +7644,11 @@ impl Machine {
|
|||||||
if let Some(string) = self.machine_st.value_to_str_like(addr) {
|
if let Some(string) = self.machine_st.value_to_str_like(addr) {
|
||||||
for c in string.as_str().chars() {
|
for c in string.as_str().chars() {
|
||||||
if c as u32 > 255 {
|
if c as u32 > 255 {
|
||||||
let non_octet = self.machine_st.atom_tbl.build_with(&c.to_string());
|
let non_octet = self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(&c.to_string());
|
||||||
self.machine_st
|
self.machine_st
|
||||||
.unify_atom(non_octet, self.machine_st.registers[2]);
|
.unify_atom(non_octet, self.machine_st.registers[2]);
|
||||||
return;
|
return;
|
||||||
@@ -7641,7 +7680,7 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[1])
|
.value_to_str_like(self.machine_st.registers[1])
|
||||||
{
|
{
|
||||||
match roxmltree::Document::parse(string.as_str()) {
|
match roxmltree::Document::parse(&*string.as_str()) {
|
||||||
Ok(doc) => {
|
Ok(doc) => {
|
||||||
let result = self.xml_node_to_term(doc.root_element());
|
let result = self.xml_node_to_term(doc.root_element());
|
||||||
unify!(self.machine_st, self.machine_st.registers[2], result);
|
unify!(self.machine_st, self.machine_st.registers[2], result);
|
||||||
@@ -7661,12 +7700,12 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[1])
|
.value_to_str_like(self.machine_st.registers[1])
|
||||||
{
|
{
|
||||||
match env::var(key.as_str()) {
|
match env::var(&*key.as_str()) {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
let cstr = put_complete_string(
|
let cstr = put_complete_string(
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
&value,
|
&value,
|
||||||
&mut self.machine_st.atom_tbl,
|
&mut self.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
unify!(self.machine_st, self.machine_st.registers[2], cstr);
|
unify!(self.machine_st, self.machine_st.registers[2], cstr);
|
||||||
@@ -7691,7 +7730,7 @@ impl Machine {
|
|||||||
.value_to_str_like(self.machine_st.registers[2])
|
.value_to_str_like(self.machine_st.registers[2])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
env::set_var(key.as_str(), value.as_str());
|
env::set_var(&*key.as_str(), &*value.as_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -7700,7 +7739,7 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[1])
|
.value_to_str_like(self.machine_st.registers[1])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
env::remove_var(key.as_str());
|
env::remove_var(&*key.as_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -7756,7 +7795,7 @@ impl Machine {
|
|||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
let command = process::Command::new(&value)
|
let command = process::Command::new(&value)
|
||||||
.arg("-c")
|
.arg("-c")
|
||||||
.arg(command.as_str())
|
.arg(&*command.as_str())
|
||||||
.status();
|
.status();
|
||||||
command_result(&mut self.machine_st, command);
|
command_result(&mut self.machine_st, command);
|
||||||
}
|
}
|
||||||
@@ -7764,7 +7803,7 @@ impl Machine {
|
|||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
let command = process::Command::new(&value)
|
let command = process::Command::new(&value)
|
||||||
.arg("/C")
|
.arg("/C")
|
||||||
.arg(command.as_str())
|
.arg(&*command.as_str())
|
||||||
.status();
|
.status();
|
||||||
command_result(&mut self.machine_st, command);
|
command_result(&mut self.machine_st, command);
|
||||||
}
|
}
|
||||||
@@ -7799,7 +7838,7 @@ impl Machine {
|
|||||||
.machine_st
|
.machine_st
|
||||||
.value_to_str_like(self.machine_st.registers[2])
|
.value_to_str_like(self.machine_st.registers[2])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let bytes = base64::decode_config(b64.as_str(), config);
|
let bytes = base64::decode_config(&*b64.as_str(), config);
|
||||||
|
|
||||||
match bytes {
|
match bytes {
|
||||||
Ok(bs) => {
|
Ok(bs) => {
|
||||||
@@ -7839,7 +7878,7 @@ impl Machine {
|
|||||||
|
|
||||||
use crate::machine::LIBRARIES;
|
use crate::machine::LIBRARIES;
|
||||||
|
|
||||||
match LIBRARIES.borrow().get(library_name.as_str()) {
|
match LIBRARIES.borrow().get(&*library_name.as_str()) {
|
||||||
Some(library) => {
|
Some(library) => {
|
||||||
let lib_stream = Stream::from_static_string(library, &mut self.machine_st.arena);
|
let lib_stream = Stream::from_static_string(library, &mut self.machine_st.arena);
|
||||||
unify!(
|
unify!(
|
||||||
@@ -7851,10 +7890,14 @@ impl Machine {
|
|||||||
let mut path_buf = machine::current_dir();
|
let mut path_buf = machine::current_dir();
|
||||||
|
|
||||||
path_buf.push("/lib");
|
path_buf.push("/lib");
|
||||||
path_buf.push(library_name.as_str());
|
path_buf.push(&*library_name.as_str());
|
||||||
|
|
||||||
let library_path_str = path_buf.to_str().unwrap();
|
let library_path_str = path_buf.to_str().unwrap();
|
||||||
let library_path = self.machine_st.atom_tbl.build_with(library_path_str);
|
let library_path = self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(library_path_str);
|
||||||
|
|
||||||
self.machine_st
|
self.machine_st
|
||||||
.unify_atom(library_path, self.machine_st.registers[3]);
|
.unify_atom(library_path, self.machine_st.registers[3]);
|
||||||
@@ -7954,7 +7997,7 @@ impl Machine {
|
|||||||
let path_string = put_complete_string(
|
let path_string = put_complete_string(
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
path,
|
path,
|
||||||
&mut self.machine_st.atom_tbl,
|
&mut self.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
unify!(self.machine_st, self.machine_st.registers[1], path_string);
|
unify!(self.machine_st, self.machine_st.registers[1], path_string);
|
||||||
@@ -8001,7 +8044,7 @@ impl Machine {
|
|||||||
fstr.push_str("finis].");
|
fstr.push_str("finis].");
|
||||||
let s = datetime.format(&fstr).to_string();
|
let s = datetime.format(&fstr).to_string();
|
||||||
|
|
||||||
self.machine_st.atom_tbl.build_with(&s)
|
self.machine_st.atom_tbl.blocking_write().build_with(&s)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn string_encoding_bytes(
|
pub(super) fn string_encoding_bytes(
|
||||||
@@ -8025,17 +8068,21 @@ impl Machine {
|
|||||||
put_complete_string(
|
put_complete_string(
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
node.text().unwrap(),
|
node.text().unwrap(),
|
||||||
&mut self.machine_st.atom_tbl,
|
&mut self.machine_st.atom_tbl.blocking_write(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let mut avec = Vec::new();
|
let mut avec = Vec::new();
|
||||||
|
|
||||||
for attr in node.attributes() {
|
for attr in node.attributes() {
|
||||||
let name = self.machine_st.atom_tbl.build_with(attr.name());
|
let name = self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(attr.name());
|
||||||
let value = put_complete_string(
|
let value = put_complete_string(
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
&attr.value(),
|
&attr.value(),
|
||||||
&mut self.machine_st.atom_tbl,
|
&mut self.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
avec.push(str_loc_as_cell!(self.machine_st.heap.len()));
|
avec.push(str_loc_as_cell!(self.machine_st.heap.len()));
|
||||||
@@ -8061,7 +8108,11 @@ impl Machine {
|
|||||||
cvec.into_iter()
|
cvec.into_iter()
|
||||||
));
|
));
|
||||||
|
|
||||||
let tag = self.machine_st.atom_tbl.build_with(node.tag_name().name());
|
let tag = self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(node.tag_name().name());
|
||||||
|
|
||||||
let result = str_loc_as_cell!(self.machine_st.heap.len());
|
let result = str_loc_as_cell!(self.machine_st.heap.len());
|
||||||
|
|
||||||
@@ -8081,17 +8132,17 @@ impl Machine {
|
|||||||
None => put_complete_string(
|
None => put_complete_string(
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
&node.text(),
|
&node.text(),
|
||||||
&mut self.machine_st.atom_tbl,
|
&mut self.machine_st.atom_tbl.blocking_write(),
|
||||||
),
|
),
|
||||||
Some(name) => {
|
Some(name) => {
|
||||||
let mut avec = Vec::new();
|
let mut avec = Vec::new();
|
||||||
|
|
||||||
for attr in node.attrs() {
|
for attr in node.attrs() {
|
||||||
let name = self.machine_st.atom_tbl.build_with(attr.0);
|
let name = self.machine_st.atom_tbl.blocking_write().build_with(attr.0);
|
||||||
let value = put_complete_string(
|
let value = put_complete_string(
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
&attr.1,
|
&attr.1,
|
||||||
&mut self.machine_st.atom_tbl,
|
&mut self.machine_st.atom_tbl.blocking_write(),
|
||||||
);
|
);
|
||||||
|
|
||||||
avec.push(str_loc_as_cell!(self.machine_st.heap.len()));
|
avec.push(str_loc_as_cell!(self.machine_st.heap.len()));
|
||||||
@@ -8117,7 +8168,7 @@ impl Machine {
|
|||||||
cvec.into_iter()
|
cvec.into_iter()
|
||||||
));
|
));
|
||||||
|
|
||||||
let tag = self.machine_st.atom_tbl.build_with(name);
|
let tag = self.machine_st.atom_tbl.blocking_write().build_with(name);
|
||||||
let result = str_loc_as_cell!(self.machine_st.heap.len());
|
let result = str_loc_as_cell!(self.machine_st.heap.len());
|
||||||
|
|
||||||
self.machine_st
|
self.machine_st
|
||||||
@@ -8138,7 +8189,11 @@ impl Machine {
|
|||||||
if buffer.len() == 0 {
|
if buffer.len() == 0 {
|
||||||
empty_list_as_cell!()
|
empty_list_as_cell!()
|
||||||
} else {
|
} else {
|
||||||
atom_as_cstr_cell!(self.machine_st.atom_tbl.build_with(&buffer))
|
atom_as_cstr_cell!(self
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(&buffer))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -638,7 +638,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
|
|||||||
Ok(Token::Literal(Literal::Atom(atom!("[]"))))
|
Ok(Token::Literal(Literal::Atom(atom!("[]"))))
|
||||||
} else {
|
} else {
|
||||||
Ok(Token::Literal(Literal::Atom(
|
Ok(Token::Literal(Literal::Atom(
|
||||||
self.machine_st.atom_tbl.build_with(&token),
|
self.machine_st.atom_tbl.blocking_write().build_with(&token),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1083,7 +1083,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
|
|||||||
|
|
||||||
if c == '"' {
|
if c == '"' {
|
||||||
let s = self.char_code_list_token(c)?;
|
let s = self.char_code_list_token(c)?;
|
||||||
let atom = self.machine_st.atom_tbl.build_with(&s);
|
let atom = self.machine_st.atom_tbl.blocking_write().build_with(&s);
|
||||||
|
|
||||||
return if let DoubleQuotes::Atom = self.machine_st.flags.double_quotes {
|
return if let DoubleQuotes::Atom = self.machine_st.flags.double_quotes {
|
||||||
Ok(Token::Literal(Literal::Atom(atom)))
|
Ok(Token::Literal(Literal::Atom(atom)))
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ pub(crate) fn as_partial_string(
|
|||||||
tail_ref = tail;
|
tail_ref = tail;
|
||||||
}
|
}
|
||||||
Term::CompleteString(_, cstr) => {
|
Term::CompleteString(_, cstr) => {
|
||||||
string += cstr.as_str();
|
string += &*cstr.as_str();
|
||||||
tail = Term::Literal(Cell::default(), Literal::Atom(atom!("[]")));
|
tail = Term::Literal(Cell::default(), Literal::Atom(atom!("[]")));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ pub(crate) fn as_partial_string(
|
|||||||
Term::AnonVar | Term::Var(..) => Ok((string, Some(Box::new(tail)))),
|
Term::AnonVar | Term::Var(..) => Ok((string, Some(Box::new(tail)))),
|
||||||
Term::Literal(_, Literal::Atom(atom!("[]"))) => Ok((string, None)),
|
Term::Literal(_, Literal::Atom(atom!("[]"))) => Ok((string, None)),
|
||||||
Term::Literal(_, Literal::String(tail)) => {
|
Term::Literal(_, Literal::String(tail)) => {
|
||||||
string += tail.as_str();
|
string += &*tail.as_str();
|
||||||
Ok((string, None))
|
Ok((string, None))
|
||||||
}
|
}
|
||||||
_ => Ok((string, Some(Box::new(tail)))),
|
_ => Ok((string, Some(Box::new(tail)))),
|
||||||
@@ -568,16 +568,19 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
let idx = self.terms.len() - arity;
|
let idx = self.terms.len() - arity;
|
||||||
|
|
||||||
if TokenType::Term == self.stack[stack_len].tt {
|
if TokenType::Term == self.stack[stack_len].tt {
|
||||||
if atomize_term(&mut self.lexer.machine_st.atom_tbl, &self.terms[idx - 1]).is_some() {
|
if atomize_term(
|
||||||
|
&mut self.lexer.machine_st.atom_tbl.blocking_write(),
|
||||||
|
&self.terms[idx - 1],
|
||||||
|
)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
self.stack.truncate(stack_len + 1);
|
self.stack.truncate(stack_len + 1);
|
||||||
|
|
||||||
let mut subterms: Vec<_> = self.terms.drain(idx..).collect();
|
let mut subterms: Vec<_> = self.terms.drain(idx..).collect();
|
||||||
|
|
||||||
if let Some(name) = self
|
if let Some(name) = self.terms.pop().and_then(|t| {
|
||||||
.terms
|
atomize_term(&mut self.lexer.machine_st.atom_tbl.blocking_write(), &t)
|
||||||
.pop()
|
}) {
|
||||||
.and_then(|t| atomize_term(&mut self.lexer.machine_st.atom_tbl, &t))
|
|
||||||
{
|
|
||||||
// reduce the '.' functor to a cons cell if it applies.
|
// reduce the '.' functor to a cons cell if it applies.
|
||||||
if name == atom!(".") && subterms.len() == 2 {
|
if name == atom!(".") && subterms.len() == 2 {
|
||||||
let tail = subterms.pop().unwrap();
|
let tail = subterms.pop().unwrap();
|
||||||
@@ -588,7 +591,12 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
Term::PartialString(Cell::default(), string_buf, tail)
|
Term::PartialString(Cell::default(), string_buf, tail)
|
||||||
}
|
}
|
||||||
Ok((string_buf, None)) => {
|
Ok((string_buf, None)) => {
|
||||||
let atom = self.lexer.machine_st.atom_tbl.build_with(&string_buf);
|
let atom = self
|
||||||
|
.lexer
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(&string_buf);
|
||||||
Term::CompleteString(Cell::default(), atom)
|
Term::CompleteString(Cell::default(), atom)
|
||||||
}
|
}
|
||||||
Err(term) => term,
|
Err(term) => term,
|
||||||
@@ -755,7 +763,12 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
Term::PartialString(Cell::default(), string_buf, tail)
|
Term::PartialString(Cell::default(), string_buf, tail)
|
||||||
}
|
}
|
||||||
Ok((string_buf, None)) => {
|
Ok((string_buf, None)) => {
|
||||||
let atom = self.lexer.machine_st.atom_tbl.build_with(&string_buf);
|
let atom = self
|
||||||
|
.lexer
|
||||||
|
.machine_st
|
||||||
|
.atom_tbl
|
||||||
|
.blocking_write()
|
||||||
|
.build_with(&string_buf);
|
||||||
Term::CompleteString(Cell::default(), atom)
|
Term::CompleteString(Cell::default(), atom)
|
||||||
}
|
}
|
||||||
Err(term) => term,
|
Err(term) => term,
|
||||||
@@ -971,7 +984,9 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
|n, arena| Literal::from(float_alloc!(n, arena)),
|
|n, arena| Literal::from(float_alloc!(n, arena)),
|
||||||
),
|
),
|
||||||
Token::Literal(c) => {
|
Token::Literal(c) => {
|
||||||
if let Some(name) = atomize_constant(&mut self.lexer.machine_st.atom_tbl, c) {
|
let atomized =
|
||||||
|
atomize_constant(&mut self.lexer.machine_st.atom_tbl.blocking_write(), c);
|
||||||
|
if let Some(name) = atomized {
|
||||||
if !self.shift_op(name, op_dir)? {
|
if !self.shift_op(name, op_dir)? {
|
||||||
self.shift(Token::Literal(c), 0, TERM);
|
self.shift(Token::Literal(c), 0, TERM);
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/read.rs
28
src/read.rs
@@ -16,7 +16,9 @@ use crate::types::*;
|
|||||||
|
|
||||||
use fxhash::FxBuildHasher;
|
use fxhash::FxBuildHasher;
|
||||||
|
|
||||||
use indexmap::IndexSet;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[cfg(feature = "repl")]
|
#[cfg(feature = "repl")]
|
||||||
use rustyline::error::ReadlineError;
|
use rustyline::error::ReadlineError;
|
||||||
@@ -79,7 +81,7 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inner.add_lines_read(num_lines_read);
|
inner.add_lines_read(num_lines_read);
|
||||||
write_term_to_heap(&term, &mut self.heap, &mut self.atom_tbl)
|
write_term_to_heap(&term, &mut self.heap, &mut self.atom_tbl.blocking_write())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,9 +114,10 @@ pub struct ReadlineStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ReadlineStream {
|
impl ReadlineStream {
|
||||||
#[cfg(feature = "repl")]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(pending_input: &str, add_history: bool) -> Self {
|
pub fn new(pending_input: &str, add_history: bool) -> Self {
|
||||||
|
#[cfg(feature = "repl")]
|
||||||
|
{
|
||||||
let config = Config::builder().check_cursor_position(true).build();
|
let config = Config::builder().check_cursor_position(true).build();
|
||||||
|
|
||||||
let helper = Helper::new();
|
let helper = Helper::new();
|
||||||
@@ -137,22 +140,21 @@ impl ReadlineStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "repl"))]
|
#[cfg(not(feature = "repl"))]
|
||||||
#[inline]
|
{
|
||||||
pub fn new(pending_input: &str, add_history: bool) -> Self {
|
|
||||||
ReadlineStream {
|
ReadlineStream {
|
||||||
pending_input: CharReader::new(Cursor::new(pending_input.to_owned())),
|
pending_input: CharReader::new(Cursor::new(pending_input.to_owned())),
|
||||||
add_history: add_history,
|
add_history: add_history,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "repl")]
|
|
||||||
pub fn set_atoms_for_completion(&mut self, atoms: *const IndexSet<Atom>) {
|
|
||||||
let helper = self.rl.helper_mut().unwrap();
|
|
||||||
helper.atoms = atoms;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "repl"))]
|
pub fn set_atoms_for_completion(&mut self, atoms: &Arc<RwLock<AtomTable>>) {
|
||||||
pub fn set_atoms_for_completion(&mut self, atoms: *const IndexSet<Atom>) {}
|
#[cfg(feature = "repl")]
|
||||||
|
{
|
||||||
|
let helper = self.rl.helper_mut().unwrap();
|
||||||
|
helper.atoms = Arc::downgrade(atoms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
@@ -433,7 +435,7 @@ impl<'a, 'b> TermWriter<'a, 'b> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
&TermRef::CompleteString(_, _, ref src) => {
|
&TermRef::CompleteString(_, _, ref src) => {
|
||||||
put_complete_string(self.heap, src.as_str(), self.atom_tbl);
|
put_complete_string(self.heap, &src.as_str(), self.atom_tbl);
|
||||||
}
|
}
|
||||||
&TermRef::PartialString(lvl, _, ref src, _) => {
|
&TermRef::PartialString(lvl, _, ref src, _) => {
|
||||||
if let Level::Root = lvl {
|
if let Level::Root = lvl {
|
||||||
|
|||||||
@@ -1,23 +1,26 @@
|
|||||||
use indexmap::IndexSet;
|
use rustyline::completion::Completer;
|
||||||
use rustyline::completion::{Candidate, Completer};
|
|
||||||
use rustyline::highlight::{Highlighter, MatchingBracketHighlighter};
|
use rustyline::highlight::{Highlighter, MatchingBracketHighlighter};
|
||||||
use rustyline::hint::Hinter;
|
use rustyline::hint::Hinter;
|
||||||
use rustyline::validate::Validator;
|
use rustyline::validate::Validator;
|
||||||
use rustyline::{Context, Helper as RlHelper, Result};
|
use rustyline::{Context, Helper as RlHelper, Result};
|
||||||
|
|
||||||
use crate::atom_table::{Atom, STATIC_ATOMS_MAP};
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
|
use std::sync::Weak;
|
||||||
|
|
||||||
|
use crate::atom_table::{AtomString, AtomTable, STATIC_ATOMS_MAP};
|
||||||
|
|
||||||
// TODO: Maybe add validation to the helper
|
// TODO: Maybe add validation to the helper
|
||||||
pub struct Helper {
|
pub struct Helper {
|
||||||
highligher: MatchingBracketHighlighter,
|
highligher: MatchingBracketHighlighter,
|
||||||
pub atoms: *const IndexSet<Atom>,
|
pub atoms: Weak<RwLock<AtomTable>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Helper {
|
impl Helper {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
highligher: MatchingBracketHighlighter::new(),
|
highligher: MatchingBracketHighlighter::new(),
|
||||||
atoms: std::ptr::null(),
|
atoms: Weak::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,20 +57,8 @@ fn get_prefix(line: &str, pos: usize) -> Option<usize> {
|
|||||||
start_of_atom
|
start_of_atom
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StrPtr(*const str);
|
|
||||||
|
|
||||||
impl Candidate for StrPtr {
|
|
||||||
fn display(&self) -> &str {
|
|
||||||
unsafe { self.0.as_ref().unwrap() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn replacement(&self) -> &str {
|
|
||||||
unsafe { self.0.as_ref().unwrap() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Completer for Helper {
|
impl Completer for Helper {
|
||||||
type Candidate = StrPtr;
|
type Candidate = AtomString<'static>;
|
||||||
|
|
||||||
fn complete(
|
fn complete(
|
||||||
&self,
|
&self,
|
||||||
@@ -78,17 +69,21 @@ impl Completer for Helper {
|
|||||||
let start_of_prefix = get_prefix(line, pos);
|
let start_of_prefix = get_prefix(line, pos);
|
||||||
if let Some(idx) = start_of_prefix {
|
if let Some(idx) = start_of_prefix {
|
||||||
let sub_str = line.get(idx..pos).unwrap();
|
let sub_str = line.get(idx..pos).unwrap();
|
||||||
Ok((idx, unsafe {
|
|
||||||
let mut matching = (*self.atoms)
|
let guard = tokio::runtime::Handle::current()
|
||||||
|
.block_on(self.atoms.upgrade().unwrap().read_owned());
|
||||||
|
|
||||||
|
let mut matching = guard
|
||||||
|
.table
|
||||||
.iter()
|
.iter()
|
||||||
.chain(STATIC_ATOMS_MAP.values())
|
.chain(STATIC_ATOMS_MAP.values())
|
||||||
.filter(|a| a.as_str().starts_with(sub_str))
|
.map(|a| a.as_str())
|
||||||
.map(|s| StrPtr(s.as_str()))
|
.filter(|a| a.starts_with(sub_str))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
matching.sort_unstable_by(|a, b| Ord::cmp(&(*a.0).len(), &(*b.0).len()));
|
matching.sort_unstable_by(|a, b| Ord::cmp(&a.len(), &b.len()));
|
||||||
matching
|
|
||||||
}))
|
Ok((idx, matching))
|
||||||
} else {
|
} else {
|
||||||
Ok((0, vec![]))
|
Ok((0, vec![]))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user