use OffsetTableImpl without synchronization by default

This commit is contained in:
Mark Thom
2025-05-22 23:49:57 -07:00
committed by Mark Thom
parent 725def07cd
commit 1332611f83
28 changed files with 1005 additions and 990 deletions

View File

@@ -2698,7 +2698,7 @@ pub fn generate_instructions_rs() -> TokenStream {
if ident == "Named" {
clause_type_from_name_and_arity_arms.push(quote! {
(name, arity) => ClauseType::Named(arity, name, CodeIndex::default(arena))
(name, arity) => ClauseType::Named(arity, name, CodeIndex::default(&mut arena.code_index_tbl))
});
clause_type_to_instr_arms.push(quote! {

View File

@@ -21,7 +21,6 @@ use std::ops::{Deref, DerefMut};
use std::ptr;
use std::ptr::addr_of_mut;
use std::ptr::NonNull;
use std::sync::Arc;
macro_rules! arena_alloc {
($e:expr, $arena:expr) => {{
@@ -32,8 +31,7 @@ macro_rules! arena_alloc {
macro_rules! float_alloc {
($e:expr, $arena:expr) => {{
let result = $e;
unsafe { $arena.f64_tbl.build_with(OrderedFloat(result)).as_ptr() }
$arena.f64_tbl.build_with(OrderedFloat($e))
}};
}
@@ -458,8 +456,8 @@ impl Drop for UntypedArenaSlab {
#[derive(Debug)]
pub struct Arena {
base: Option<UntypedArenaSlab>,
pub f64_tbl: Arc<F64Table>,
pub code_index_tbl: Arc<CodeIndexTable>,
pub f64_tbl: F64Table,
pub code_index_tbl: CodeIndexTable,
}
unsafe impl Send for Arena {}
@@ -584,23 +582,27 @@ mod tests {
#[test]
fn float_ptr_cast() {
let wam = MockWAM::new();
let mut wam = MockWAM::new();
let f = 0f64;
let fp = float_alloc!(f, wam.machine_st.arena);
let mut cell = HeapCellValue::from(fp.clone());
let mut cell = HeapCellValue::from(fp);
assert_eq!(cell.get_tag(), HeapCellValueTag::F64);
assert_eq!(cell.get_tag(), HeapCellValueTag::F64Offset);
assert!(!cell.get_mark_bit());
assert_eq!(fp.deref(), &OrderedFloat(f));
assert_eq!(
wam.machine_st.arena.f64_tbl.lookup(fp).deref(),
&OrderedFloat(f)
);
cell.set_mark_bit(true);
assert!(cell.get_mark_bit());
read_heap_cell!(cell,
(HeapCellValueTag::F64, ptr) => {
assert_eq!(OrderedFloat(*ptr), OrderedFloat(f))
(HeapCellValueTag::F64Offset, offset) => {
let fp = wam.machine_st.arena.f64_tbl.lookup(offset.into());
assert_eq!(*fp, OrderedFloat(0f64))
}
_ => { unreachable!() }
);
@@ -825,7 +827,7 @@ mod tests {
let float_ptr = float_alloc!(float, wam.machine_st.arena);
let cell = HeapCellValue::from(float_ptr);
assert_eq!(cell.get_tag(), HeapCellValueTag::F64);
assert_eq!(cell.get_tag(), HeapCellValueTag::F64Offset);
// char

View File

@@ -138,6 +138,7 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
#[derive(Debug)]
pub(crate) struct ArithmeticEvaluator<'a> {
marker: &'a mut DebrayAllocator,
f64_tbl: &'a F64Table,
interm: Vec<ArithmeticTerm>,
interm_c: usize,
}
@@ -156,11 +157,18 @@ impl<'a> ArithmeticTermIter<'a> for &'a Term {
}
}
fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: &Literal) -> Result<(), ArithmeticError> {
fn push_literal(
f64_tbl: &F64Table,
interm: &mut Vec<ArithmeticTerm>,
c: &Literal,
) -> Result<(), ArithmeticError> {
match c {
Literal::Fixnum(n) => interm.push(ArithmeticTerm::Number(Number::Fixnum(*n))),
Literal::Integer(n) => interm.push(ArithmeticTerm::Number(Number::Integer(*n))),
Literal::Float(n) => interm.push(ArithmeticTerm::Number(Number::Float(*n.as_ptr()))),
&Literal::F64Offset(offset) => {
let n = *f64_tbl.lookup(offset);
interm.push(ArithmeticTerm::Number(Number::Float(n)));
}
Literal::Rational(n) => interm.push(ArithmeticTerm::Number(Number::Rational(*n))),
Literal::Atom(name) if name == &atom!("e") => interm.push(ArithmeticTerm::Number(
Number::Float(OrderedFloat(std::f64::consts::E)),
@@ -178,9 +186,14 @@ fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: &Literal) -> Result<(), Ari
}
impl<'a> ArithmeticEvaluator<'a> {
pub(crate) fn new(marker: &'a mut DebrayAllocator, target_int: usize) -> Self {
pub(crate) fn new(
marker: &'a mut DebrayAllocator,
f64_tbl: &'a F64Table,
target_int: usize,
) -> Self {
ArithmeticEvaluator {
marker,
f64_tbl,
interm: Vec::new(),
interm_c: target_int,
}
@@ -318,7 +331,7 @@ impl<'a> ArithmeticEvaluator<'a> {
for term_ref in src.iter()? {
match term_ref? {
ArithTermRef::Literal(c) => push_literal(&mut self.interm, &c)?,
ArithTermRef::Literal(c) => push_literal(self.f64_tbl, &mut self.interm, &c)?,
ArithTermRef::Var(lvl, cell, name) => {
let var_num = name.to_var_num().unwrap();
@@ -652,11 +665,11 @@ impl Ord for Number {
}
}
impl TryFrom<HeapCellValue> for Number {
impl TryFrom<(HeapCellValue, &'_ F64Table)> for Number {
type Error = ();
#[inline]
fn try_from(value: HeapCellValue) -> Result<Number, Self::Error> {
fn try_from((value, f64_tbl): (HeapCellValue, &F64Table)) -> Result<Number, Self::Error> {
read_heap_cell!(value,
(HeapCellValueTag::Cons, c) => {
match_untyped_arena_ptr!(c,
@@ -671,8 +684,9 @@ impl TryFrom<HeapCellValue> for Number {
}
)
}
(HeapCellValueTag::F64, n) => {
Ok(Number::Float(*n))
(HeapCellValueTag::F64Offset, offset) => {
let n = *f64_tbl.lookup(offset.into());
Ok(Number::Float(n))
}
(HeapCellValueTag::Fixnum | HeapCellValueTag::CutPoint, n) => {
Ok(Number::Fixnum(n))

View File

@@ -6,6 +6,7 @@ use crate::forms::*;
use crate::indexing::*;
use crate::instructions::*;
use crate::iterators::*;
use crate::offset_table::F64Table;
use crate::parser::ast::*;
use crate::targets::*;
use crate::types::*;
@@ -269,9 +270,10 @@ impl CodeGenSettings {
}
#[derive(Debug)]
pub(crate) struct CodeGenerator {
pub(crate) struct CodeGenerator<'f64_tbl> {
marker: DebrayAllocator,
settings: CodeGenSettings,
f64_tbl: &'f64_tbl F64Table,
pub(crate) skeleton: PredicateSkeleton,
}
@@ -323,7 +325,7 @@ trait AddToFreeList<'a, Target: CompilationTarget<'a>> {
fn add_subterm_to_free_list(&mut self, term: &Term);
}
impl<'a> AddToFreeList<'a, FactInstruction> for CodeGenerator {
impl<'a> AddToFreeList<'a, FactInstruction> for CodeGenerator<'_> {
fn add_term_to_free_list(&mut self, r: RegType) {
self.marker.add_reg_to_free_list(r);
}
@@ -331,7 +333,7 @@ impl<'a> AddToFreeList<'a, FactInstruction> for CodeGenerator {
fn add_subterm_to_free_list(&mut self, _term: &Term) {}
}
impl<'a> AddToFreeList<'a, QueryInstruction> for CodeGenerator {
impl<'a> AddToFreeList<'a, QueryInstruction> for CodeGenerator<'_> {
#[inline(always)]
fn add_term_to_free_list(&mut self, _r: RegType) {}
@@ -353,11 +355,12 @@ fn structure_cell(term: &Term) -> Option<&Cell<RegType>> {
}
}
impl CodeGenerator {
pub(crate) fn new(settings: CodeGenSettings) -> Self {
impl<'f64_tbl> CodeGenerator<'f64_tbl> {
pub(crate) fn new(f64_tbl: &'f64_tbl F64Table, settings: CodeGenSettings) -> Self {
CodeGenerator {
marker: DebrayAllocator::new(),
settings,
f64_tbl,
skeleton: PredicateSkeleton::new(),
}
}
@@ -427,7 +430,7 @@ impl CodeGenerator {
where
Target: crate::targets::CompilationTarget<'a>,
Iter: Iterator<Item = TermRef<'a>>,
CodeGenerator: AddToFreeList<'a, Target>,
CodeGenerator<'f64_tbl>: AddToFreeList<'a, Target>,
{
let mut target = CodeDeque::new();
@@ -443,7 +446,7 @@ impl CodeGenerator {
}
TermRef::Clause(lvl, cell, name, terms) => {
let terms_range =
if let Some(subterm @ Term::Literal(_, Literal::CodeIndex(_))) =
if let Some(subterm @ Term::Literal(_, Literal::CodeIndexOffset(_))) =
terms.last()
{
self.subterm_to_instr::<Target>(subterm, context, &mut target);
@@ -666,7 +669,7 @@ impl CodeGenerator {
}
},
InlinedClauseType::IsFloat(..) => match terms[0] {
Term::Literal(_, Literal::Float(_)) => {
Term::Literal(_, Literal::F64Offset(_)) => {
instr!("$succeed")
}
Term::Var(ref vr, ref name) => {
@@ -687,7 +690,7 @@ impl CodeGenerator {
}
},
InlinedClauseType::IsNumber(..) => match terms[0] {
Term::Literal(_, Literal::Float(_))
Term::Literal(_, Literal::F64Offset(_))
| Term::Literal(_, Literal::Rational(_))
| Term::Literal(_, Literal::Integer(_))
| Term::Literal(_, Literal::Fixnum(_)) => {
@@ -791,7 +794,7 @@ impl CodeGenerator {
term_loc: GenContext,
arg: usize,
) -> Result<ArithCont, ArithmeticError> {
let mut evaluator = ArithmeticEvaluator::new(&mut self.marker, target_int);
let mut evaluator = ArithmeticEvaluator::new(&mut self.marker, self.f64_tbl, target_int);
evaluator.compile_is(term, term_loc, arg)
}
@@ -861,7 +864,7 @@ impl CodeGenerator {
Term::Literal(
_,
c @ Literal::Integer(_)
| c @ Literal::Float(_)
| c @ Literal::F64Offset(_)
| c @ Literal::Rational(_)
| c @ Literal::Fixnum(_),
) => {

View File

@@ -6,6 +6,7 @@ use crate::machine::disjuncts::VarData;
use crate::machine::loader::PredicateQueue;
use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*;
use crate::offset_table::OffsetTable;
use crate::parser::ast::*;
use crate::parser::dashu::{Integer, Rational};
use crate::parser::parser::CompositeOpDesc;
@@ -742,7 +743,7 @@ impl ArenaFrom<Number> for HeapCellValue {
match value {
Number::Fixnum(n) => fixnum_as_cell!(n),
Number::Integer(n) => typed_arena_ptr_as_cell!(n),
Number::Float(OrderedFloat(n)) => HeapCellValue::from(float_alloc!(n, arena)),
Number::Float(n) => HeapCellValue::from(arena.f64_tbl.build_with(n)),
Number::Rational(n) => typed_arena_ptr_as_cell!(n),
}
}

View File

@@ -8,7 +8,6 @@ use crate::parser::dashu::{ibig, Integer, Rational};
use crate::forms::*;
use crate::heap_iter::*;
use crate::machine::heap::*;
use crate::machine::machine_indices::*;
use crate::machine::partial_string::*;
use crate::machine::stack::*;
use crate::machine::streams::*;
@@ -389,17 +388,20 @@ fn is_numbered_var(name: Atom, arity: usize) -> bool {
#[inline]
fn negated_op_needs_bracketing(
iter: &StackfulPreOrderHeapIter<ListElider>,
f64_tbl: &F64Table,
op_dir: &OpDir,
op: &Option<DirectedOp>,
) -> bool {
if let Some(ref op) = op {
op.is_negative_sign()
&& iter.leftmost_leaf_has_property(op_dir, |addr| match Number::try_from(addr) {
Ok(Number::Fixnum(n)) => n.get_num() > 0,
Ok(Number::Float(OrderedFloat(f))) => f > 0f64,
Ok(Number::Integer(n)) => n.is_positive(),
Ok(Number::Rational(n)) => n.is_positive(),
_ => false,
&& iter.leftmost_leaf_has_property(op_dir, |addr| {
match Number::try_from((addr, f64_tbl)) {
Ok(Number::Fixnum(n)) => n.get_num() > 0,
Ok(Number::Float(OrderedFloat(f))) => f > 0f64,
Ok(Number::Integer(n)) => n.is_positive(),
Ok(Number::Rational(n)) => n.is_positive(),
_ => false,
}
})
} else {
false
@@ -473,6 +475,7 @@ pub fn fmt_float(mut fl: f64) -> String {
pub struct HCPrinter<'a, Outputter> {
outputter: Outputter,
iter: StackfulPreOrderHeapIter<'a, ListElider>,
arena: &'a Arena,
op_dir: &'a OpDir,
state_stack: Vec<TokenOrRedirect>,
toplevel_spec: Option<DirectedOp>,
@@ -530,19 +533,39 @@ pub(crate) fn numbervar(offset: &Integer, addr: HeapCellValue) -> Option<String>
}
}
match Number::try_from(addr) {
Ok(Number::Fixnum(n)) if n.get_num() >= 0 => {
Some(numbervar(offset + Integer::from(n.get_num())))
read_heap_cell!(addr,
(HeapCellValueTag::Cons, c) => {
match_untyped_arena_ptr!(c,
(ArenaHeaderTag::Integer, n) => {
if !n.is_negative() {
Some(numbervar(Integer::from(offset + &*n)))
} else {
None
}
}
_ => {
None
}
)
}
Ok(Number::Integer(n)) if !n.is_negative() => Some(numbervar(Integer::from(offset + &*n))),
_ => None,
}
(HeapCellValueTag::Fixnum, n) => {
if n.get_num() >= 0 {
Some(numbervar(offset + Integer::from(n.get_num())))
} else {
None
}
}
_ => {
None
}
)
}
impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
pub fn new(
heap: &'a mut Heap,
stack: &'a mut Stack,
arena: &'a Arena,
op_dir: &'a OpDir,
output: Outputter,
term_loc: usize,
@@ -550,6 +573,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
HCPrinter {
outputter: output,
iter: stackful_preorder_iter(heap, stack, term_loc),
arena,
op_dir,
state_stack: vec![],
toplevel_spec: None,
@@ -1280,11 +1304,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let at_cdr = self.outputter.ends_with("|");
if self.double_quotes && !self.ignore_ops && !is_cyclic {
if end_cell.is_string_terminator(self.iter.heap) {
self.remove_list_children(focus.value() as usize);
return self.print_proper_string(focus.value() as usize, max_depth);
}
if self.double_quotes
&& !self.ignore_ops
&& !is_cyclic
&& end_cell.is_string_terminator(self.iter.heap)
{
self.remove_list_children(focus.value() as usize);
return self.print_proper_string(focus.value() as usize, max_depth);
}
if self.ignore_ops {
@@ -1426,7 +1452,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|| if let Some(ref op) = op {
if self.numbervars && arity == 1 && name == atom!("$VAR") {
!self.iter.immediate_leaf_has_property(|addr| {
match Number::try_from(addr) {
match Number::try_from((addr, &self.arena.f64_tbl)) {
Ok(Number::Integer(n)) => (*n).sign() == Sign::Positive,
Ok(Number::Fixnum(n)) => n.get_num() >= 0,
Ok(Number::Float(f)) => f >= OrderedFloat(0f64),
@@ -1511,28 +1537,29 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
}
}
fn print_index_ptr(&mut self, idx: CodeIndex, max_depth: usize) {
fn print_index_ptr(&mut self, idx: CodeIndexOffset, max_depth: usize) {
if self.format_struct(max_depth, 1, atom!("$index_ptr")) {
let atom = self.state_stack.pop().unwrap();
self.state_stack.pop();
self.state_stack.pop();
let idx_ptr = idx.as_ptr();
let idx_ptr = self.arena.code_index_tbl.lookup(idx);
let offset = if idx_ptr.is_undefined() || idx_ptr.is_dynamic_undefined() {
TokenOrRedirect::Atom(atom!("undefined"))
} else {
let idx_ptr_p = idx_ptr.p() as i64;
TokenOrRedirect::NumberFocus(
max_depth,
NumberFocus::Unfocused(Number::Fixnum(
/* FIXME this is not safe */
unsafe { Fixnum::build_with_unchecked(idx_ptr_p) },
)),
None,
)
if let Ok(n) = Fixnum::build_with_checked(idx_ptr_p) {
TokenOrRedirect::NumberFocus(
max_depth,
NumberFocus::Unfocused(Number::Fixnum(n)),
None,
)
} else {
TokenOrRedirect::Atom(atom!("out_of_bounds_idx_ptr"))
}
};
self.state_stack.push(offset);
@@ -1612,7 +1639,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
is_functor_redirect: bool,
mut max_depth: usize,
) {
let negated_operand = negated_op_needs_bracketing(&self.iter, self.op_dir, &op);
let negated_operand =
negated_op_needs_bracketing(&self.iter, &self.arena.f64_tbl, self.op_dir, &op);
let addr = match self.check_for_seen(&mut max_depth) {
Some(addr) => addr,
@@ -1714,14 +1742,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
});
}
}
(HeapCellValueTag::CodeIndex, idx) => {
(HeapCellValueTag::CodeIndexOffset, idx) => {
self.print_index_ptr(idx, self.max_depth);
}
(HeapCellValueTag::Fixnum | HeapCellValueTag::CutPoint, n) => {
self.print_number(max_depth, NumberFocus::Unfocused(Number::Fixnum(n)), &op);
}
(HeapCellValueTag::F64, f) => {
self.print_number(max_depth, NumberFocus::Unfocused(Number::Float(*f)), &op);
(HeapCellValueTag::F64Offset, offset) => {
let f = *self.arena.f64_tbl.lookup(offset.into());
self.print_number(max_depth, NumberFocus::Unfocused(Number::Float(f)), &op);
}
(HeapCellValueTag::PStrLoc) => {
self.print_list_like(max_depth);
@@ -1885,6 +1914,7 @@ mod tests {
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
&wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
3,
@@ -1917,6 +1947,7 @@ mod tests {
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
&wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
5,
@@ -1944,6 +1975,7 @@ mod tests {
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
&wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
0,
@@ -1956,6 +1988,7 @@ mod tests {
let mut printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
&wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
0,
@@ -1999,6 +2032,7 @@ mod tests {
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
&wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
0,
@@ -2017,6 +2051,7 @@ mod tests {
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
&wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
0,
@@ -2033,6 +2068,7 @@ mod tests {
let mut printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
&wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
0,
@@ -2069,6 +2105,7 @@ mod tests {
let mut printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
&wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
0,
@@ -2094,6 +2131,7 @@ mod tests {
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
&wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
2,
@@ -2123,6 +2161,7 @@ mod tests {
let mut printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
&wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
2,

View File

@@ -1124,7 +1124,7 @@ impl MachineState {
&ArithmeticTerm::Reg(r) => {
let value = self.store(self.deref(self[r]));
match Number::try_from(value) {
match Number::try_from((value, &self.arena.f64_tbl)) {
Ok(n) => Ok(n),
Err(_) => {
self.heap[0] = value;
@@ -1388,7 +1388,8 @@ impl MachineState {
(HeapCellValueTag::Fixnum, n) => {
self.interms.push(Number::Fixnum(n));
}
(HeapCellValueTag::F64, fl) => {
(HeapCellValueTag::F64Offset, offset) => {
let fl = self.arena.f64_tbl.lookup(offset);
self.interms.push(Number::Float(*fl));
}
(HeapCellValueTag::Cons, ptr) => {

View File

@@ -700,31 +700,25 @@ fn remove_non_leading_clause(
}
}
fn finalize_retract(
fn finalize_retract<'a, LS: LoadState<'a>>(
payload: &mut <LS as LoadState<'a>>::LoaderFieldType,
key: PredicateKey,
compilation_target: CompilationTarget,
skeleton: &mut PredicateSkeleton,
code_index: CodeIndex,
target_pos: usize,
index_ptr_opt: Option<IndexPtr>,
retraction_info: &mut RetractionInfo,
) -> usize {
let clause_clause_loc = delete_from_skeleton(
compilation_target,
key,
skeleton,
target_pos,
retraction_info,
&mut payload.retraction_info,
);
if let Some(index_ptr) = index_ptr_opt {
set_code_index(
retraction_info,
&compilation_target,
key,
code_index,
index_ptr,
);
set_code_index::<LS>(payload, &compilation_target, key, code_index, index_ptr);
}
clause_clause_loc
@@ -1239,7 +1233,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut preprocessor = Preprocessor::new(settings);
let clause = preprocessor.try_term_to_tl(self, term)?;
let mut cg = CodeGenerator::new(settings);
let f64_tbl = &LS::machine_st(&mut self.payload).arena.f64_tbl;
let mut cg = CodeGenerator::new(f64_tbl, settings);
let clause_code = cg.compile_predicate(vec![clause])?;
Ok(StandaloneCompileResult {
@@ -1254,7 +1250,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
mut predicates: PredicateQueue,
settings: CodeGenSettings,
) -> Result<CodeIndex, SessionError> {
let code_index = self.get_or_insert_code_index(key, predicates.compilation_target);
let code_idx = self.get_or_insert_code_index(key, predicates.compilation_target);
LS::err_on_builtin_overwrite(self, key)?;
@@ -1268,7 +1264,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
clauses.push(preprocessor.try_term_to_tl(self, term)?);
}
let mut cg = CodeGenerator::new(settings);
let f64_tbl = &LS::machine_st(&mut self.payload).arena.f64_tbl;
let mut cg = CodeGenerator::new(f64_tbl, settings);
let mut code = cg.compile_predicate(clauses)?;
if settings.is_extensible {
@@ -1327,9 +1325,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
);
}
let index_ptr = LS::machine_st(&mut self.payload)
.arena
.code_index_tbl
.lookup(code_idx.into());
print_overwrite_warning(
&predicates.compilation_target,
code_index.get(),
*index_ptr,
key,
settings.is_dynamic(),
);
@@ -1340,16 +1343,16 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
IndexPtr::index(code_ptr)
};
set_code_index(
&mut self.payload.retraction_info,
set_code_index::<LS>(
&mut self.payload,
&predicates.compilation_target,
key,
code_index,
code_idx,
index_ptr,
);
self.wam_prelude.code.extend(code);
Ok(code_index)
Ok(code_idx)
}
fn extend_local_predicate_skeleton(
@@ -1551,19 +1554,19 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
self.push_back_to_local_predicate_skeleton(&compilation_target, &key, code_len);
let code_index = self.get_or_insert_code_index(key, compilation_target);
let code_idx = self.get_or_insert_code_index(key, compilation_target);
if let Some(new_code_ptr) = result {
set_code_index(
&mut self.payload.retraction_info,
set_code_index::<LS>(
&mut self.payload,
&compilation_target,
key,
code_index,
code_idx,
new_code_ptr,
);
}
Ok(code_index)
Ok(code_idx)
}
AppendOrPrepend::Prepend => {
let clause_index_info = standalone_skeleton.clauses.pop_back().unwrap();
@@ -1593,17 +1596,17 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
self.push_front_to_local_predicate_skeleton(&compilation_target, &key, code_len);
let code_index = self.get_or_insert_code_index(key, compilation_target);
let code_idx = self.get_or_insert_code_index(key, compilation_target);
set_code_index(
&mut self.payload.retraction_info,
set_code_index::<LS>(
&mut self.payload,
&compilation_target,
key,
code_index,
code_idx,
new_code_ptr,
);
Ok(code_index)
Ok(code_idx)
}
}
}
@@ -1651,7 +1654,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
pub(super) fn retract_clause(&mut self, key: PredicateKey, target_pos: usize) -> usize {
let payload_compilation_target = self.payload.compilation_target;
let code_index = self.get_or_insert_code_index(key, payload_compilation_target);
let code_idx_offset = self.get_or_insert_code_index(key, payload_compilation_target);
let skeleton = self
.wam_prelude
@@ -1729,14 +1732,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
None
};
return finalize_retract(
return finalize_retract::<LS>(
&mut self.payload,
key,
payload_compilation_target,
skeleton,
code_index,
code_idx_offset,
target_pos,
index_ptr_opt,
&mut self.payload.retraction_info,
);
}
None => {
@@ -1758,14 +1761,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
)
};
return finalize_retract(
return finalize_retract::<LS>(
&mut self.payload,
key,
payload_compilation_target,
skeleton,
code_index,
code_idx_offset,
target_pos,
index_ptr_opt,
&mut self.payload.retraction_info,
);
}
}
@@ -1988,14 +1991,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
};
finalize_retract(
finalize_retract::<LS>(
&mut self.payload,
key,
payload_compilation_target,
skeleton,
code_index,
code_idx_offset,
target_pos,
index_ptr_opt,
&mut self.payload.retraction_info,
)
}
}
@@ -2222,18 +2225,23 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
};
let predicates = self.payload.predicates.take();
let code_index = self.compile(key, predicates, settings)?;
let offset = self.compile(key, predicates, settings)?;
if let Some(filename) = self.listing_src_file_name() {
if let Some(ref mut module) = self.wam_prelude.indices.modules.get_mut(&filename) {
let index_ptr = code_index.get();
let code_index = *module.code_dir.entry(key).or_insert(code_index);
let code_idx = LS::machine_st(&mut self.payload)
.arena
.code_index_tbl
.lookup_mut(offset.into());
set_code_index(
&mut self.payload.retraction_info,
let index_ptr = *code_idx;
let offset = *module.code_dir.entry(key).or_insert(offset);
set_code_index::<LS>(
&mut self.payload,
&CompilationTarget::Module(filename),
key,
code_index,
offset,
index_ptr,
);
}

View File

@@ -579,7 +579,7 @@ impl VariableClassifier {
mut terms,
) if terms.len() == 3 => {
if let Some(last_arg) = terms.last() {
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
if let Term::Literal(_, Literal::CodeIndexOffset(_)) = last_arg {
terms.pop();
state_stack.push(TraversalState::Term(Term::Clause(
Cell::default(),

View File

@@ -232,13 +232,11 @@ impl MachineState {
}
(HeapCellValueTag::PStrLoc |
HeapCellValueTag::Lis) => {
// HeapCellValueTag::CStr) => {
l
}
(HeapCellValueTag::Fixnum |
HeapCellValueTag::CutPoint |
// HeapCellValueTag::Char |
HeapCellValueTag::F64) => {
HeapCellValueTag::F64Offset) => {
c
}
(HeapCellValueTag::Atom, (_name, arity)) => {
@@ -548,19 +546,33 @@ impl Machine {
let p = self.machine_st.p;
// Find the boundaries of the current predicate
self.indices.code_dir.sort_by(|_, a, _, b| a.cmp(b));
self.indices.code_dir.sort_by(|_, a, _, b| {
let a = *self.machine_st.arena.code_index_tbl.lookup((*a).into());
let b = *self.machine_st.arena.code_index_tbl.lookup((*b).into());
a.cmp(&b)
});
let predicate_idx = self
.indices
.code_dir
.binary_search_by_key(&p, |_, x| x.get().p() as usize)
.binary_search_by_key(&p, |_, x| -> usize {
self.machine_st.arena.code_index_tbl.lookup((*x).into()).p()
as usize
})
.unwrap_or_else(|x| x - 1);
let current_pred_start = self
.indices
.code_dir
.get_index(predicate_idx)
.map(|x| x.1.as_ptr().p() as usize)
.map(|idx| {
self.machine_st
.arena
.code_index_tbl
.lookup((*idx.1).into())
.p() as usize
})
.unwrap();
debug_assert!(current_pred_start <= p);
@@ -569,7 +581,13 @@ impl Machine {
.indices
.code_dir
.get_index(predicate_idx + 1)
.map(|x| x.1.as_ptr().p() as usize)
.map(|idx| {
self.machine_st
.arena
.code_index_tbl
.lookup((*idx.1).into())
.p() as usize
})
.unwrap_or(self.code.len());
debug_assert!(current_pred_end >= p);
@@ -2343,7 +2361,7 @@ impl Machine {
.store(self.machine_st.deref(self.machine_st[r]));
read_heap_cell!(d,
(HeapCellValueTag::Fixnum | HeapCellValueTag::F64 |
(HeapCellValueTag::Fixnum | HeapCellValueTag::F64Offset |
HeapCellValueTag::Cons) => {
self.machine_st.p += 1;
}
@@ -2375,7 +2393,7 @@ impl Machine {
.store(self.machine_st.deref(self.machine_st[r]));
read_heap_cell!(d,
(HeapCellValueTag::Fixnum | HeapCellValueTag::F64 |
(HeapCellValueTag::Fixnum | HeapCellValueTag::F64Offset |
HeapCellValueTag::Cons) => {
self.machine_st.p = self.machine_st.cp;
}
@@ -2472,7 +2490,7 @@ impl Machine {
.machine_st
.store(self.machine_st.deref(self.machine_st[r]));
match Number::try_from(d) {
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(_) | Number::Integer(_)) => {
self.machine_st.p += 1;
}
@@ -2493,7 +2511,7 @@ impl Machine {
.machine_st
.store(self.machine_st.deref(self.machine_st[r]));
match Number::try_from(d) {
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(_) | Number::Integer(_)) => {
self.machine_st.p = self.machine_st.cp;
}
@@ -2514,7 +2532,7 @@ impl Machine {
.machine_st
.store(self.machine_st.deref(self.machine_st[r]));
match Number::try_from(d) {
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
Ok(_) => {
self.machine_st.p += 1;
}
@@ -2528,7 +2546,7 @@ impl Machine {
.machine_st
.store(self.machine_st.deref(self.machine_st[r]));
match Number::try_from(d) {
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
Ok(_) => {
self.machine_st.p = self.machine_st.cp;
}
@@ -2590,7 +2608,7 @@ impl Machine {
.machine_st
.store(self.machine_st.deref(self.machine_st[r]));
match Number::try_from(d) {
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Float(_)) => {
self.machine_st.p += 1;
}
@@ -2604,7 +2622,7 @@ impl Machine {
.machine_st
.store(self.machine_st.deref(self.machine_st[r]));
match Number::try_from(d) {
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Float(_)) => {
self.machine_st.p = self.machine_st.cp;
}
@@ -2677,10 +2695,10 @@ impl Machine {
}
}
}
&Instruction::CallNamed(arity, name, ref idx) => {
let idx = idx.get();
&Instruction::CallNamed(arity, name, idx) => {
let idx = self.machine_st.arena.code_index_tbl.lookup(idx.into());
try_or_throw!(self.machine_st, self.try_call(name, arity, idx));
try_or_throw!(self.machine_st, self.try_call(name, arity, *idx));
if self.machine_st.fail {
self.machine_st.backtrack();
@@ -2688,10 +2706,10 @@ impl Machine {
increment_call_count!(self.machine_st);
}
}
&Instruction::ExecuteNamed(arity, name, ref idx) => {
let idx = idx.get();
&Instruction::ExecuteNamed(arity, name, idx) => {
let idx = self.machine_st.arena.code_index_tbl.lookup(idx.into());
try_or_throw!(self.machine_st, self.try_execute(name, arity, idx));
try_or_throw!(self.machine_st, self.try_execute(name, arity, *idx));
if self.machine_st.fail {
self.machine_st.backtrack();
@@ -2699,19 +2717,19 @@ impl Machine {
increment_call_count!(self.machine_st);
}
}
&Instruction::DefaultCallNamed(arity, name, ref idx) => {
let idx = idx.get();
&Instruction::DefaultCallNamed(arity, name, idx) => {
let idx = self.machine_st.arena.code_index_tbl.lookup(idx.into());
try_or_throw!(self.machine_st, self.try_call(name, arity, idx));
try_or_throw!(self.machine_st, self.try_call(name, arity, *idx));
if self.machine_st.fail {
self.machine_st.backtrack();
}
}
&Instruction::DefaultExecuteNamed(arity, name, ref idx) => {
let idx = idx.get();
&Instruction::DefaultExecuteNamed(arity, name, idx) => {
let idx = self.machine_st.arena.code_index_tbl.lookup(idx.into());
try_or_throw!(self.machine_st, self.try_execute(name, arity, idx));
try_or_throw!(self.machine_st, self.try_execute(name, arity, *idx));
if self.machine_st.fail {
self.machine_st.backtrack();
@@ -5251,7 +5269,7 @@ impl Machine {
let l = self.machine_st.registers[3];
let l = self.machine_st.store(self.machine_st.deref(l));
let l = match Number::try_from(l) {
let l = match Number::try_from((l, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(l)) => l.get_num() as usize,
_ => unreachable!(),
};
@@ -5259,7 +5277,7 @@ impl Machine {
let p = self.machine_st.registers[4];
let p = self.machine_st.store(self.machine_st.deref(p));
let p = match Number::try_from(p) {
let p = match Number::try_from((p, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(p)) => p.get_num() as usize,
_ => unreachable!(),
};
@@ -5297,7 +5315,7 @@ impl Machine {
let l = self.machine_st.registers[3];
let l = self.machine_st.store(self.machine_st.deref(l));
let l = match Number::try_from(l) {
let l = match Number::try_from((l, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(l)) => l.get_num() as usize,
_ => unreachable!(),
};
@@ -5305,7 +5323,7 @@ impl Machine {
let p = self.machine_st.registers[4];
let p = self.machine_st.store(self.machine_st.deref(p));
let p = match Number::try_from(p) {
let p = match Number::try_from((p, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(p)) => p.get_num() as usize,
_ => unreachable!(),
};

View File

@@ -1,6 +1,6 @@
use crate::atom_table::*;
use crate::forms::*;
use crate::functor_macro::*;
use crate::machine::{ArenaHeaderTag, Fixnum, Integer};
use crate::types::*;
use std::alloc;
@@ -717,7 +717,7 @@ impl Heap {
pub(crate) fn slice_to_str(&self, slice_loc: usize, slice_len: usize) -> &str {
unsafe {
let slice = std::slice::from_raw_parts(self.inner.ptr.add(slice_loc), slice_len);
std::str::from_utf8_unchecked(&slice)
std::str::from_utf8_unchecked(slice)
}
}
@@ -824,7 +824,7 @@ impl Heap {
let s = unsafe {
let char_ptr = self.inner.ptr.add(byte_idx);
let slice = std::slice::from_raw_parts(char_ptr, size_of::<char>());
std::str::from_utf8_unchecked(&slice)
std::str::from_utf8_unchecked(slice)
};
s.chars().next().unwrap()
@@ -1158,14 +1158,24 @@ pub fn sized_iter_to_heap_list<SrcT: Into<HeapCellValue>>(
pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<usize> {
let extract_integer = |s: usize| -> Option<usize> {
match Number::try_from(heap[s]) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
Ok(Number::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
Some(value)
read_heap_cell!(heap[s],
(HeapCellValueTag::Cons, c) => {
match_untyped_arena_ptr!(c,
(ArenaHeaderTag::Integer, n) => {
(&*n).try_into().ok()
}
_ => {
None
}
)
}
_ => None,
}
(HeapCellValueTag::Fixnum, n) => {
usize::try_from(n.get_num()).ok()
}
_ => {
None
}
)
};
read_heap_cell!(addr,

View File

@@ -277,14 +277,15 @@ impl Term {
},
}
}
(HeapCellValueTag::F64, f) => {
term_stack.push(Term::Float((*f).into()));
(HeapCellValueTag::F64Offset, offset) => {
let f = *machine.machine_st.arena.f64_tbl.lookup(offset);
term_stack.push(Term::Float(f.into()));
}
(HeapCellValueTag::Fixnum, n) => {
term_stack.push(Term::Integer(n.into()));
}
(HeapCellValueTag::Cons, ptr) => {
if let Ok(n) = Number::try_from(addr) {
if let Ok(n) = Number::try_from((addr, &machine.machine_st.arena.f64_tbl)) {
match n {
Number::Integer(i) => term_stack.push(Term::Integer((*i).clone())),
Number::Rational(r) => term_stack.push(Term::Rational((*r).clone())),
@@ -312,31 +313,6 @@ impl Term {
}
}
(HeapCellValueTag::Atom, (name, arity)) => {
//let h = iter.focus().value() as usize;
//let mut arity = arity;
// Not sure why/if this is needed.
// Might find out with better testing later.
/*
if iter.heap.len() > h + arity + 1 {
let value = iter.heap[h + arity + 1];
if let Some(idx) = get_structure_index(value) {
// in the second condition, arity == 0,
// meaning idx cannot pertain to this atom
// if it is the direct subterm of a larger
// structure.
if arity > 0 || !iter.direct_subterm_of_str(h) {
term_stack.push(
Term::Literal(Cell::default(), Literal::CodeIndex(idx))
);
arity += 1;
}
}
}
*/
if arity == 0 {
let atom_name = name.as_str().to_string();
if atom_name == "[]" {
@@ -621,9 +597,15 @@ impl Machine {
.indices
.code_dir
.get(&(atom!("call"), 1))
.expect("couldn't get code index")
.local()
.unwrap();
.cloned()
.map(|offset| {
self.machine_st
.arena
.code_index_tbl
.lookup(offset.into())
.p() as usize
})
.expect("couldn't get code index");
self.machine_st.execute_at_index(1, call_index_p);

View File

@@ -15,35 +15,40 @@ use std::mem;
pub(super) type ModuleOpExports = Vec<(OpDecl, Option<OpDesc>)>;
pub(super) fn set_code_index(
retraction_info: &mut RetractionInfo,
pub(super) fn set_code_index<'a, LS: LoadState<'a>>(
payload: &mut <LS as LoadState<'a>>::LoaderFieldType,
compilation_target: &CompilationTarget,
key: PredicateKey,
mut code_index: CodeIndex,
code_idx: CodeIndex,
code_ptr: IndexPtr,
) {
let mut code_idx_ptr = LS::machine_st(payload)
.arena
.code_index_tbl
.lookup_mut(code_idx.into());
let record = match compilation_target {
CompilationTarget::User => {
if IndexPtrTag::Undefined == code_index.get().tag() {
code_index.set(code_ptr);
if IndexPtrTag::Undefined == code_idx_ptr.tag() {
code_idx_ptr.set(code_ptr);
RetractionRecord::AddedUserPredicate(key)
} else {
let replaced = code_index.replace(code_ptr);
let replaced = code_idx_ptr.replace(code_ptr);
RetractionRecord::ReplacedUserPredicate(key, replaced)
}
}
CompilationTarget::Module(ref module_name) => {
if IndexPtrTag::Undefined == code_index.get().tag() {
code_index.set(code_ptr);
if IndexPtrTag::Undefined == code_idx_ptr.tag() {
code_idx_ptr.set(code_ptr);
RetractionRecord::AddedModulePredicate(*module_name, key)
} else {
let replaced = code_index.replace(code_ptr);
let replaced = code_idx_ptr.replace(code_ptr);
RetractionRecord::ReplacedModulePredicate(*module_name, key, replaced)
}
}
};
retraction_info.push_record(record);
payload.retraction_info.push_record(record);
}
fn add_op_decl_as_module_export<'a, LS: LoadState<'a>>(
@@ -133,21 +138,28 @@ pub(super) fn import_module_exports<'a, LS: LoadState<'a>>(
}
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
let arena = &mut LS::machine_st(payload).arena;
let code_idx_tbl = &mut LS::machine_st(payload).arena.code_index_tbl;
let target_code_index = *code_dir
.entry(key)
.or_insert_with(|| CodeIndex::default(arena));
.or_insert_with(|| CodeIndex::default(code_idx_tbl));
set_code_index(
&mut payload.retraction_info,
let src_code_index_ptr = *code_idx_tbl.lookup(src_code_index.into());
set_code_index::<LS>(
payload,
compilation_target,
key,
target_code_index,
src_code_index.get(),
src_code_index_ptr,
);
if src_code_index.as_ptr().is_dynamic_undefined() {
if LS::machine_st(payload)
.arena
.code_index_tbl
.lookup(src_code_index.into())
.is_dynamic_undefined()
{
code_dir.insert(key, src_code_index);
}
} else {
@@ -189,19 +201,20 @@ fn import_module_exports_into_module<'a, LS: LoadState<'a>>(
meta_predicates.insert(key, meta_specs.clone());
}
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
let arena = &mut LS::machine_st(payload).arena;
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
let code_index_tbl = &mut LS::machine_st(payload).arena.code_index_tbl;
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
let target_code_index = *code_dir
.entry(key)
.or_insert_with(|| CodeIndex::default(arena));
.or_insert_with(|| CodeIndex::default(code_index_tbl));
set_code_index(
&mut payload.retraction_info,
set_code_index::<LS>(
payload,
compilation_target,
key,
target_code_index,
src_code_index.get(),
src_code_ptr,
);
} else {
return Err(SessionError::ModuleDoesNotContainExport(
@@ -242,21 +255,21 @@ fn import_qualified_module_exports<'a, LS: LoadState<'a>>(
.insert(key, meta_specs.clone());
}
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
let arena = &mut LS::machine_st(payload).arena;
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
let code_index_tbl = &mut LS::machine_st(payload).arena.code_index_tbl;
let target_code_index = *wam_prelude
.indices
.code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
let target_code_index =
*wam_prelude.indices.code_dir.entry(key).or_insert_with(|| {
CodeIndex::new(IndexPtr::undefined(), code_index_tbl)
});
set_code_index(
&mut payload.retraction_info,
set_code_index::<LS>(
payload,
compilation_target,
key,
target_code_index,
src_code_index.get(),
src_code_ptr,
);
} else {
return Err(SessionError::ModuleDoesNotContainExport(
@@ -303,19 +316,20 @@ fn import_qualified_module_exports_into_module<'a, LS: LoadState<'a>>(
meta_predicates.insert(key, meta_specs.clone());
}
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
let arena = &mut LS::machine_st(payload).arena;
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
let code_index_tbl = &mut LS::machine_st(payload).arena.code_index_tbl;
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
let target_code_index = *code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), code_index_tbl));
set_code_index(
&mut payload.retraction_info,
set_code_index::<LS>(
payload,
&payload_compilation_target,
key,
target_code_index,
src_code_index.get(),
src_code_ptr,
);
} else {
return Err(SessionError::ModuleDoesNotContainExport(
@@ -468,11 +482,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.indices
.get_predicate_skeleton(local_compilation_target, key)
{
let old_index_ptr = code_index.replace(if global_skeleton.core.is_dynamic {
IndexPtr::dynamic_undefined()
} else {
IndexPtr::undefined()
});
let old_index_ptr = code_index.replace(
&mut LS::machine_st(&mut self.payload).arena.code_index_tbl,
if global_skeleton.core.is_dynamic {
IndexPtr::dynamic_undefined()
} else {
IndexPtr::undefined()
},
);
self.payload.retraction_info.push_record(
RetractionRecord::ReplacedModulePredicate(module_name, *key, old_index_ptr),
@@ -486,8 +503,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
continue;
}
if !code_index.as_ptr().is_undefined() && !code_index.as_ptr().is_dynamic_undefined() {
let old_index_ptr = code_index.replace(IndexPtr::undefined());
let code_index_tbl = &mut LS::machine_st(&mut self.payload).arena.code_index_tbl;
let code_ptr = code_index_tbl.lookup((*code_index).into());
if !code_ptr.is_undefined() && !code_ptr.is_dynamic_undefined() {
let old_index_ptr = code_index.replace(code_index_tbl, IndexPtr::undefined());
self.payload.retraction_info.push_record(
RetractionRecord::ReplacedModulePredicate(module_name, *key, old_index_ptr),
@@ -517,25 +537,34 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
None => return,
};
fn remove_module_exports(
fn remove_module_exports<'b, LS: LoadState<'b>>(
payload: &mut <LS as LoadState<'b>>::LoaderFieldType,
removed_module: &Module,
code_dir: &mut CodeDir,
op_dir: &mut OpDir,
retraction_info: &mut RetractionInfo,
predicate_retractor: impl Fn(PredicateKey, IndexPtr) -> RetractionRecord,
op_retractor: impl Fn(OpDecl, OpDesc) -> RetractionRecord,
) {
for export in removed_module.module_decl.exports.iter() {
match export {
ModuleExport::PredicateKey(ref key) => {
match (removed_module.code_dir.get(key), code_dir.get_mut(key)) {
(Some(module_code_index), Some(target_code_index))
if module_code_index.get() == target_code_index.get() =>
{
let old_index_ptr =
target_code_index.replace(IndexPtr::undefined());
retraction_info
.push_record(predicate_retractor(*key, old_index_ptr));
match (
removed_module.code_dir.get(key).cloned(),
code_dir.get_mut(key).cloned(),
) {
(Some(module_code_idx), Some(target_code_idx)) => {
let code_index_tbl =
&mut LS::machine_st(payload).arena.code_index_tbl;
let module_code_ptr = code_index_tbl.lookup(module_code_idx.into());
let target_code_ptr = code_index_tbl.lookup(target_code_idx.into());
if module_code_ptr == target_code_ptr {
let old_index_ptr = target_code_idx
.replace(code_index_tbl, IndexPtr::undefined());
payload
.retraction_info
.push_record(predicate_retractor(*key, old_index_ptr));
}
}
_ => {}
}
@@ -545,7 +574,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.swap_remove(&(op_decl.name, op_decl.op_desc.get_spec().fixity()));
if let Some(op_desc) = op_dir_value_opt {
retraction_info.push_record(op_retractor(*op_decl, op_desc));
payload
.retraction_info
.push_record(op_retractor(*op_decl, op_desc));
}
}
}
@@ -554,11 +585,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
match self.payload.compilation_target {
CompilationTarget::User => {
remove_module_exports(
remove_module_exports::<LS>(
&mut self.payload,
&removed_module,
&mut self.wam_prelude.indices.code_dir,
&mut self.wam_prelude.indices.op_dir,
&mut self.payload.retraction_info,
RetractionRecord::ReplacedUserPredicate,
RetractionRecord::ReplacedUserOp,
);
@@ -578,11 +609,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.modules
.get_mut(&target_module_name)
{
remove_module_exports(
remove_module_exports::<LS>(
&mut self.payload,
&removed_module,
&mut module.code_dir,
&mut module.op_dir,
&mut self.payload.retraction_info,
predicate_retractor,
op_retractor,
);
@@ -608,7 +639,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
Some(ref mut module) => *module.code_dir.entry(key).or_insert_with(|| {
CodeIndex::new(
IndexPtr::undefined(),
&mut LS::machine_st(&mut self.payload).arena,
&mut LS::machine_st(&mut self.payload).arena.code_index_tbl,
)
}),
None => {
@@ -618,7 +649,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
Some(ref mut module) => *module.code_dir.entry(key).or_insert_with(|| {
CodeIndex::new(
IndexPtr::undefined(),
&mut LS::machine_st(&mut self.payload).arena,
&mut LS::machine_st(&mut self.payload).arena.code_index_tbl,
)
}),
None => {
@@ -634,7 +665,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
key: PredicateKey,
compilation_target: CompilationTarget,
) -> CodeIndex {
let arena = &mut LS::machine_st(&mut self.payload).arena;
let code_index_tbl = &mut LS::machine_st(&mut self.payload).arena.code_index_tbl;
match compilation_target {
CompilationTarget::User => *self
@@ -642,7 +673,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.indices
.code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena)),
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), code_index_tbl)),
CompilationTarget::Module(module_name) => {
self.get_or_insert_local_code_index(module_name, key)
}
@@ -654,7 +685,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
module_name: Atom,
key: PredicateKey,
) -> CodeIndex {
let arena = &mut LS::machine_st(&mut self.payload).arena;
let code_index_tbl = &mut LS::machine_st(&mut self.payload).arena.code_index_tbl;
if module_name == atom!("user") {
return *self
@@ -662,7 +693,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.indices
.code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), code_index_tbl));
} else {
self.get_or_insert_local_code_index(module_name, key)
}

View File

@@ -720,7 +720,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
self.wam_prelude.indices.modules.get_mut(&module_name)
{
if let Some(code_idx) = module.code_dir.get_mut(&key) {
code_idx.set(old_code_idx)
let code_index_tbl =
&mut LS::machine_st(&mut self.payload).arena.code_index_tbl;
code_idx.set(code_index_tbl, old_code_idx);
}
}
}
@@ -741,7 +743,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
RetractionRecord::ReplacedUserPredicate(key, old_code_idx) => {
if let Some(code_idx) = self.wam_prelude.indices.code_dir.get_mut(&key) {
code_idx.set(old_code_idx)
let code_index_tbl =
&mut LS::machine_st(&mut self.payload).arena.code_index_tbl;
code_idx.set(code_index_tbl, old_code_idx)
}
}
RetractionRecord::AddedIndex(index_key, clause_loc) => {
@@ -1217,14 +1221,18 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
* but to multifile and discontiguous predicates as well.
*/
let code_index = self.get_or_insert_code_index(key, compilation_target);
let offset = self.get_or_insert_code_index(key, compilation_target);
let code_idx_ptr = LS::machine_st(&mut self.payload)
.arena
.code_index_tbl
.lookup_mut(offset.into());
if code_index.as_ptr().is_undefined() {
set_code_index(
&mut self.payload.retraction_info,
if code_idx_ptr.is_undefined() {
set_code_index::<LS>(
&mut self.payload,
&compilation_target,
key,
code_index,
offset,
IndexPtr::dynamic_undefined(),
);
}
@@ -1395,7 +1403,7 @@ impl MachineState {
Err(cons_term) => term_stack.push(cons_term),
}
}
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | HeapCellValueTag::F64) => {
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | HeapCellValueTag::F64Offset) => {
term_stack.push(Term::Literal(Cell::default(), Literal::try_from(addr).unwrap()));
}
(HeapCellValueTag::StackVar, h) => {
@@ -1410,7 +1418,7 @@ impl MachineState {
let value = iter.heap[h.saturating_sub(1)];
if let Some(idx) = get_structure_index(value) {
term_stack.push(Term::Literal(Cell::default(), Literal::CodeIndex(idx)));
term_stack.push(Term::Literal(Cell::default(), Literal::CodeIndexOffset(idx.into())));
arity += 1;
}
@@ -1588,7 +1596,7 @@ impl Machine {
let predicate_name = cell_as_atom!(self.deref_register(2));
let arity = self.deref_register(3);
let arity = match Number::try_from(arity) {
let arity = match Number::try_from((arity, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Integer(n)) if *n >= Integer::ZERO && *n <= Integer::from(MAX_ARITY) => {
let value: usize = (&*n).try_into().unwrap();
Ok(value)
@@ -1999,7 +2007,15 @@ impl Machine {
.wam_prelude
.indices
.get_predicate_code_index(name, arity, module_name)
.map(|code_idx| code_idx.get_tag())
.map(|offset| {
loader
.payload
.machine_st
.arena
.code_index_tbl
.lookup(offset.into())
.tag()
})
.unwrap_or(IndexPtrTag::DynamicUndefined);
if idx_tag == IndexPtrTag::Index {
@@ -2142,9 +2158,15 @@ impl Machine {
.indices
.remove_predicate_skeleton(&compilation_target, &key);
let mut code_index = loader.get_or_insert_code_index(key, compilation_target);
let offset = loader.get_or_insert_code_index(key, compilation_target);
let mut code_idx = loader
.payload
.machine_st
.arena
.code_index_tbl
.lookup_mut(offset.into());
code_index.set(IndexPtr::undefined());
code_idx.set(IndexPtr::undefined());
loader.payload.compilation_target = clause_clause_compilation_target;
@@ -2174,7 +2196,7 @@ impl Machine {
.machine_st
.store(self.machine_st.deref(self.machine_st[temp_v!(3)]));
let target_pos = match Number::try_from(target_pos) {
let target_pos = match Number::try_from((target_pos, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
value

View File

@@ -2,7 +2,6 @@
use crate::parser::ast::*;
use crate::arena::*;
use crate::atom_table::*;
use crate::forms::*;
use crate::machine::loader::*;
@@ -19,7 +18,6 @@ use scryer_modular_bitfield::{bitfield, BitfieldSpecifier};
use std::cmp::Ordering;
use std::collections::BTreeSet;
use std::ops::Deref;
use crate::types::*;
@@ -127,9 +125,18 @@ impl IndexPtr {
pub(crate) fn is_dynamic_undefined(&self) -> bool {
matches!(self.tag(), IndexPtrTag::DynamicUndefined)
}
#[inline]
pub(crate) fn local(&self) -> Option<usize> {
match self.tag() {
IndexPtrTag::Index => Some(self.p() as usize),
IndexPtrTag::DynamicIndex => Some(self.p() as usize),
_ => None,
}
}
}
#[derive(Debug, Clone, Copy, Ord, Hash, PartialOrd, Eq, PartialEq)]
#[derive(Debug, Clone, Copy)] // , Ord, Hash, PartialOrd, Eq, PartialEq)]
pub struct CodeIndex(CodeIndexOffset);
#[cfg(target_pointer_width = "32")]
@@ -141,7 +148,7 @@ const_assert!(std::mem::align_of::<CodeIndex>() == 8);
impl From<CodeIndex> for HeapCellValue {
#[inline(always)]
fn from(idx: CodeIndex) -> HeapCellValue {
HeapCellValue::from(idx.as_ptr())
HeapCellValue::from(idx.0)
}
}
@@ -152,48 +159,39 @@ impl From<CodeIndexOffset> for CodeIndex {
}
}
impl Into<CodeIndexOffset> for CodeIndex {
#[inline(always)]
fn into(self) -> CodeIndexOffset {
self.0
}
}
impl Into<CodeIndexOffset> for &'_ CodeIndex {
#[inline(always)]
fn into(self) -> CodeIndexOffset {
self.0
}
}
impl CodeIndex {
#[inline]
pub(crate) fn new(ptr: IndexPtr, arena: &mut Arena) -> Self {
unsafe { CodeIndex(arena.code_index_tbl.build_with(ptr)) }
pub(crate) fn new(ptr: IndexPtr, code_index_tbl: &mut CodeIndexTable) -> Self {
CodeIndex(code_index_tbl.build_with(ptr))
}
#[inline(always)]
pub(crate) fn default(arena: &mut Arena) -> Self {
CodeIndex::new(IndexPtr::undefined(), arena)
}
pub(crate) fn local(&self) -> Option<usize> {
match self.0.as_ptr().tag() {
IndexPtrTag::Index => Some(self.get().p() as usize),
IndexPtrTag::DynamicIndex => Some(self.get().p() as usize),
_ => None,
}
pub(crate) fn default(code_index_tbl: &mut CodeIndexTable) -> Self {
CodeIndex::new(IndexPtr::undefined(), code_index_tbl)
}
#[inline(always)]
pub(crate) fn get(&self) -> IndexPtr {
*self.as_ptr().deref()
pub(crate) fn set(&self, code_index_tbl: &mut CodeIndexTable, value: IndexPtr) {
code_index_tbl.lookup_mut(self.0).set(value);
}
#[inline(always)]
pub(crate) fn set(&mut self, value: IndexPtr) {
self.as_ptr().set(value);
}
#[inline(always)]
pub(crate) fn get_tag(self) -> IndexPtrTag {
self.get().tag()
}
#[inline(always)]
pub(crate) fn replace(&mut self, value: IndexPtr) -> IndexPtr {
self.as_ptr().replace(value)
}
#[inline(always)]
pub(crate) fn as_ptr(&self) -> CodeIndexPtr {
self.0.as_ptr()
pub(crate) fn replace(&self, code_index_tbl: &mut CodeIndexTable, value: IndexPtr) -> IndexPtr {
code_index_tbl.lookup_mut(self.0).replace(value)
}
}

View File

@@ -952,6 +952,7 @@ impl MachineState {
let mut printer = HCPrinter::new(
&mut self.heap,
&mut self.stack,
&self.arena,
op_dir,
PrinterOutputter::new(),
0,
@@ -962,7 +963,7 @@ impl MachineState {
printer.quoted = quoted;
printer.double_quotes = double_quotes;
match Number::try_from(max_depth) {
match Number::try_from((max_depth, &self.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => {
if let Ok(n) = usize::try_from(n.get_num()) {
printer.max_depth = n;

View File

@@ -288,7 +288,7 @@ impl MachineState {
unifier.unify_big_rational(n1, value);
}
pub fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
pub fn unify_f64(&mut self, f1: F64Offset, value: HeapCellValue) {
let mut unifier = DefaultUnifier::from(self);
unifier.unify_f64(f1, value);
}
@@ -409,8 +409,11 @@ impl MachineState {
}
}
Some(TermOrderCategory::FloatingPoint) => {
let v1 = cell_as_f64_ptr!(v1);
let v2 = cell_as_f64_ptr!(v2);
let v1 = cell_as_f64_offset!(v1);
let v2 = cell_as_f64_offset!(v2);
let v1 = self.arena.f64_tbl.lookup(v1);
let v2 = self.arena.f64_tbl.lookup(v2);
if v1 != v2 {
self.pdl.clear();
@@ -418,8 +421,8 @@ impl MachineState {
}
}
Some(TermOrderCategory::Integer) => {
let v1 = Number::try_from(v1).unwrap();
let v2 = Number::try_from(v2).unwrap();
let v1 = Number::try_from((v1, &self.arena.f64_tbl)).unwrap();
let v2 = Number::try_from((v2, &self.arena.f64_tbl)).unwrap();
if v1 != v2 {
self.pdl.clear();
@@ -436,22 +439,6 @@ impl MachineState {
return Some(n1.cmp(&n2));
}
}
/*
(HeapCellValueTag::Char, c2) => {
if let Some(c1) = n1.as_char() {
if c1 != c2 {
self.pdl.clear();
return Some(c1.cmp(&c2));
}
} else {
self.pdl.clear();
return Some(
n1.as_str().chars().next().cmp(&Some(c2))
.then(Ordering::Greater)
);
}
}
*/
(HeapCellValueTag::Str, s) => {
let n2 = cell_as_atom_cell!(self.heap[s])
.get_name();
@@ -466,52 +453,6 @@ impl MachineState {
}
)
}
/*
(HeapCellValueTag::Char, c1) => {
read_heap_cell!(v2,
(HeapCellValueTag::Atom, (n2, _a2)) => {
if let Some(c2) = n2.as_char() {
if c1 != c2 {
self.pdl.clear();
return Some(c1.cmp(&c2));
}
} else {
self.pdl.clear();
return Some(
Some(c1).cmp(&n2.as_str().chars().next())
.then(Ordering::Less)
);
}
}
(HeapCellValueTag::Char, c2) => {
if c1 != c2 {
self.pdl.clear();
return Some(c1.cmp(&c2));
}
}
(HeapCellValueTag::Str, s) => {
let n2 = cell_as_atom_cell!(self.heap[s])
.get_name();
if let Some(c2) = n2.as_char() {
if c1 != c2 {
self.pdl.clear();
return Some(c1.cmp(&c2));
}
} else {
self.pdl.clear();
return Some(
Some(c1).cmp(&n2.as_str().chars().next())
.then(Ordering::Less)
);
}
}
_ => {
unreachable!()
}
)
}
*/
(HeapCellValueTag::Str, s) => {
let n1 = cell_as_atom_cell!(self.heap[s])
.get_name();
@@ -523,22 +464,6 @@ impl MachineState {
return Some(n1.cmp(&n2));
}
}
/*
(HeapCellValueTag::Char, c2) => {
if let Some(c1) = n1.as_char() {
if c1 != c2 {
self.pdl.clear();
return Some(c1.cmp(&c2));
}
} else {
self.pdl.clear();
return Some(
n1.as_str().chars().next().cmp(&Some(c2))
.then(Ordering::Greater)
);
}
}
*/
(HeapCellValueTag::Str, s) => {
let n2 = cell_as_atom_cell!(self.heap[s])
.get_name();
@@ -865,7 +790,7 @@ impl MachineState {
return Err(self.error_form(err, stub_gen()));
}
_ => {
let n = match Number::try_from(n) {
let n = match Number::try_from((n, &self.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => Number::Fixnum(n),
Ok(Number::Integer(n)) => Number::Integer(n),
_ => {
@@ -917,46 +842,18 @@ impl MachineState {
(HeapCellValueTag::PStrLoc, pstr_loc) => {
if n == 1 || n == 2 {
let a3 = self.registers[3];
// let (h, offset) = pstr_loc_and_offset(&self.heap, pstr_loc);
let mut char_iter = self.heap.char_iter(pstr_loc);
// let pstr = cell_as_string!(self.heap[h]);
// let offset = offset.get_num() as usize;
if let Some(c) = char_iter.next() { // pstr.as_str_from(offset).chars().next() {
if let Some(c) = char_iter.next() {
if n == 1 {
self.unify_char(c, a3);
} else {
// let offset = (offset + c.len_utf8()) as i64;
// let h_len = self.heap.len();
// let pstr_atom: Atom = pstr.into();
if char_iter.next().is_some() {
unify_fn!(*self, pstr_loc_as_cell!(pstr_loc + c.len_utf8()), a3);
} else {
let tail_idx = Heap::pstr_tail_idx(pstr_loc + c.len_utf8());
unify_fn!(*self, self.heap[tail_idx], a3);
}
/*
if pstr_atom.len() > offset as usize {
self.heap.push(pstr_offset_as_cell!(h));
self.heap.push(fixnum_as_cell!(Fixnum::build_with_unchecked(offset as i64)));
unify_fn!(*self, pstr_loc_as_cell!(h_len), a3);
} else {
match self.heap[h].get_tag() {
HeapCellValueTag::CStr => {
self.unify_atom(atom!("[]"), self.store(self.deref(a3)));
}
HeapCellValueTag::PStr => {
unify_fn!(*self, self.heap[h+1], a3);
}
_ => {
unreachable!();
}
}
}
*/
}
} else {
unreachable!()
@@ -965,34 +862,6 @@ impl MachineState {
self.fail = true;
}
}
/*
(HeapCellValueTag::CStr, cstr_atom) => {
let cstr = PartialString::from(cstr_atom);
if let Some(c) = cstr.as_str_from(0).chars().next() {
if n == 1 {
self.unify_char(c, self.store(self.deref(self.registers[3])));
} else if n == 2 {
let offset = c.len_utf8();
let h_len = self.heap.len();
if cstr_atom.len() > offset{
self.heap.push(atom_as_cstr_cell!(cstr_atom));
self.heap.push(pstr_offset_as_cell!(h_len));
self.heap.push(fixnum_as_cell!(Fixnum::build_with_unchecked(offset as i64)));
unify_fn!(*self, pstr_loc_as_cell!(h_len+1), self.registers[3]);
} else {
self.unify_atom(atom!("[]"), self.store(self.deref(self.registers[3])));
}
} else {
self.fail = true;
}
} else {
unreachable!()
}
}
*/
_ => {
// 8.5.2.3 d)
let err = self.type_error(ValidType::Compound, term);
@@ -1077,7 +946,7 @@ impl MachineState {
read_heap_cell!(a1,
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | // | HeapCellValueTag::Char
HeapCellValueTag::F64) => {
HeapCellValueTag::F64Offset) => {
self.try_functor_unify_components(a1, 0);
}
(HeapCellValueTag::Atom, (_name, arity)) => {
@@ -1103,17 +972,17 @@ impl MachineState {
return Err(self.error_form(err, stub_gen()));
}
let mut type_error = |arity| {
let err = self.type_error(ValidType::Integer, arity);
Err(self.error_form(err, stub_gen()))
let type_error = |machine_st: &mut Self, arity| {
let err = machine_st.type_error(ValidType::Integer, arity);
Err(machine_st.error_form(err, stub_gen()))
};
let arity = match Number::try_from(arity) {
let arity = match Number::try_from((arity, &self.arena.f64_tbl)) {
Ok(Number::Float(_)) => {
return type_error(arity);
return type_error(self, arity);
}
Ok(Number::Rational(n)) if !n.denominator().is_one() => {
return type_error(arity);
return type_error(self, arity);
}
Ok(n) if n > MAX_ARITY => {
// 8.5.1.3 f)
@@ -1135,15 +1004,15 @@ impl MachineState {
value
},
Err(_) => {
return type_error(arity);
return type_error(self, arity);
}
};
read_heap_cell!(store_name,
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | // HeapCellValueTag::Char |
HeapCellValueTag::F64) if arity == 0 => {
self.bind(a1.as_var().unwrap(), deref_name);
}
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | HeapCellValueTag::F64Offset)
if arity == 0 => {
self.bind(a1.as_var().unwrap(), deref_name);
}
(HeapCellValueTag::Atom, (name, atom_arity)) => {
debug_assert_eq!(atom_arity, 0);
resource_error_call_result!(
@@ -1173,22 +1042,8 @@ impl MachineState {
return Err(self.error_form(err, stub_gen()));
}
}
/*
(HeapCellValueTag::Char, c) => {
let c = AtomTable::build_with(&self.atom_tbl, &c.to_string());
resource_error_call_result!(
self,
self.try_functor_fabricate_struct(
c,
arity as usize,
a1.as_var().unwrap(),
)
);
}
*/
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum |
HeapCellValueTag::F64) if arity != 0 => {
HeapCellValueTag::F64Offset) if arity != 0 => {
let err = self.type_error(ValidType::Atom, store_name);
return Err(self.error_form(err, stub_gen())); // 8.5.1.3 e)
}
@@ -1243,12 +1098,6 @@ impl MachineState {
Err(self.error_form(err, stub_gen()))
}
}
/*
(HeapCellValueTag::CStr, cstr_atom) => {
let cstr = cstr_atom.as_str();
Ok(cstr.chars().map(|c| char_as_cell!(c)).collect())
}
*/
_ => {
let err = self.type_error(ValidType::List, value);
Err(self.error_form(err, stub_gen()))
@@ -1372,7 +1221,7 @@ impl MachineState {
for addr in addrs {
let addr = self.store(self.deref(addr));
match Number::try_from(addr) {
match Number::try_from((addr, &self.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => {
if let Ok(b) = u8::try_from(n.get_num()) {
bytes.push(b)

View File

@@ -56,6 +56,7 @@ impl MockWAM {
let mut printer = HCPrinter::new(
&mut self.machine_st.heap,
&mut self.machine_st.stack,
&mut self.machine_st.arena,
&self.op_dir,
PrinterOutputter::new(),
term_write_result.heap_loc,

View File

@@ -208,8 +208,8 @@ pub(crate) fn import_builtin_impls(code_dir: &CodeDir, builtins: &mut Module) {
#[inline]
pub(crate) fn get_structure_index(value: HeapCellValue) -> Option<CodeIndex> {
read_heap_cell!(value,
(HeapCellValueTag::CodeIndex, ip) => {
return Some(ip);
(HeapCellValueTag::CodeIndexOffset, offset) => {
return Some(CodeIndex::from(offset));
}
_ => {
}
@@ -242,7 +242,7 @@ impl Machine {
}
/// Runs the predicate `key` in `module_name` until completion.
/// Siltently ignores failure, thrown errors and choice points.
/// Silently ignores failure, thrown errors and choice points.
///
/// Consider using [`Machine::run_query`] if you wish to handle
/// predicates that may fail, leave a choice point or throw.
@@ -252,8 +252,10 @@ impl Machine {
key: PredicateKey,
) -> std::process::ExitCode {
if let Some(module) = self.indices.modules.get(&module_name) {
if let Some(code_index) = module.code_dir.get(&key) {
let p = code_index.local().unwrap();
if let Some(code_idx) = module.code_dir.get(&key) {
let index_ptr = self.machine_st.arena.code_index_tbl.lookup(code_idx.into());
let p = index_ptr.local().unwrap();
// Leave a halting choice point to backtrack to in case the predicate fails or throws.
self.allocate_stub_choice_point();
@@ -324,8 +326,9 @@ impl Machine {
self.load_file(path_buf.to_str().unwrap(), stream);
if let Some(module) = self.indices.modules.get(&atom!("$atts")) {
if let Some(code_index) = module.code_dir.get(&(atom!("driver"), 2)) {
self.machine_st.attr_var_init.verify_attrs_loc = code_index.local().unwrap();
if let Some(code_idx) = module.code_dir.get(&(atom!("driver"), 2)) {
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(code_idx.into());
self.machine_st.attr_var_init.verify_attrs_loc = index_ptr.local().unwrap();
}
}
}
@@ -339,13 +342,16 @@ impl Machine {
for arity in 1..66 {
let key = (atom!("call"), arity);
match loader.code_dir.get(&key) {
match loader.code_dir.get(&key).cloned() {
Some(src_code_index) => {
let target_code_index = target_code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
let code_index_tbl = &mut arena.code_index_tbl;
target_code_index.set(src_code_index.get());
let target_code_index = target_code_dir.entry(key).or_insert_with(|| {
CodeIndex::new(IndexPtr::undefined(), code_index_tbl)
});
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
target_code_index.set(code_index_tbl, src_code_ptr);
}
None => {
unreachable!();
@@ -454,7 +460,7 @@ impl Machine {
key,
CodeIndex::new(
IndexPtr::index(p + impls_offset),
&mut self.machine_st.arena,
&mut self.machine_st.arena.code_index_tbl,
),
);
}
@@ -535,37 +541,8 @@ impl Machine {
if cell.is_var() {
offset += 1;
/*
} else if lit.get_tag() == HeapCellValueTag::CStr {
read_heap_cell!(cell,
(HeapCellValueTag::CStr) => {
if cell == lit {
offset += 1;
} else {
return false;
}
}
(HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc) => {
offset += 1;
}
(HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
.get_name_and_arity();
if name == atom!(".") && arity == 2 {
offset += 1;
} else {
return false;
}
}
_ => {
return false;
}
);
*/
} else {
unify!(self.machine_st, cell, lit);
// self.machine_st.write_literal_to_var(cell, lit);
if self.machine_st.fail {
self.machine_st.fail = false;
@@ -1068,13 +1045,15 @@ impl Machine {
if module_name == atom!("user") {
if let Some(idx) = self.indices.code_dir.get(&(name, arity)).cloned() {
self.try_call(name, arity, idx.get())
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
self.try_call(name, arity, index_ptr)
} else {
Err(self.machine_st.throw_undefined_error(name, arity))
}
} else if let Some(module) = self.indices.modules.get(&module_name) {
if let Some(idx) = module.code_dir.get(&(name, arity)).cloned() {
self.try_call(name, arity, idx.get())
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
self.try_call(name, arity, index_ptr)
} else {
self.undefined_procedure(name, arity)
}
@@ -1098,13 +1077,15 @@ impl Machine {
if module_name == atom!("user") {
if let Some(idx) = self.indices.code_dir.get(&(name, arity)).cloned() {
self.try_execute(name, arity, idx.get())
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
self.try_execute(name, arity, index_ptr)
} else {
self.undefined_procedure(name, arity)
}
} else if let Some(module) = self.indices.modules.get(&module_name) {
if let Some(idx) = module.code_dir.get(&(name, arity)).cloned() {
self.try_execute(name, arity, idx.get())
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
self.try_execute(name, arity, index_ptr)
} else {
self.undefined_procedure(name, arity)
}
@@ -1146,12 +1127,24 @@ impl Machine {
let r_c_w_h = self
.indices
.get_predicate_code_index(r_c_w_h_atom, 0, iso_ext)
.and_then(|item| item.local())
.and_then(|code_idx| {
self.machine_st
.arena
.code_index_tbl
.lookup(code_idx.into())
.local()
})
.unwrap();
let r_c_wo_h = self
.indices
.get_predicate_code_index(r_c_wo_h_atom, 1, iso_ext)
.and_then(|item| item.local())
.and_then(|code_idx| {
self.machine_st
.arena
.code_index_tbl
.lookup(code_idx.into())
.local()
})
.unwrap();
(r_c_w_h, r_c_wo_h)
});

View File

@@ -424,7 +424,7 @@ fn build_meta_predicate_clause<'a, LS: LoadState<'a>>(
let term = match term {
Term::Clause(cell, name, mut terms) => {
if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() {
if let Some(Term::Literal(_, Literal::CodeIndexOffset(_))) = terms.last() {
arg_terms
.push(process_term(module_name, Term::Clause(cell, name, terms)));
@@ -433,7 +433,10 @@ fn build_meta_predicate_clause<'a, LS: LoadState<'a>>(
let idx = loader.get_or_insert_qualified_code_index(module_name, key);
terms.push(Term::Literal(Cell::default(), Literal::CodeIndex(idx)));
terms.push(Term::Literal(
Cell::default(),
Literal::CodeIndexOffset(idx.into()),
));
process_term(module_name, Term::Clause(cell, name, terms))
}
Term::Literal(cell, Literal::Atom(name)) => {
@@ -444,7 +447,10 @@ fn build_meta_predicate_clause<'a, LS: LoadState<'a>>(
Term::Clause(
cell,
name,
vec![Term::Literal(Cell::default(), Literal::CodeIndex(idx))],
vec![Term::Literal(
Cell::default(),
Literal::CodeIndexOffset(idx.into()),
)],
),
)
}
@@ -469,7 +475,7 @@ pub(super) fn clause_to_query_term<'a, LS: LoadState<'a>>(
mut terms: Vec<Term>,
call_policy: CallPolicy,
) -> QueryTerm {
if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() {
if let Some(Term::Literal(_, Literal::CodeIndexOffset(_))) = terms.last() {
// supplementary code vector indices are unnecessary for
// root-level clauses.
terms.pop();
@@ -504,7 +510,7 @@ pub(super) fn qualified_clause_to_query_term<'a, LS: LoadState<'a>>(
mut terms: Vec<Term>,
call_policy: CallPolicy,
) -> QueryTerm {
if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() {
if let Some(Term::Literal(_, Literal::CodeIndexOffset(_))) = terms.last() {
// supplementary code vector indices are unnecessary for
// root-level clauses.
terms.pop();

View File

@@ -25,6 +25,7 @@ use crate::machine::partial_string::*;
use crate::machine::stack::*;
use crate::machine::streams::*;
use crate::machine::{get_structure_index, Machine, VERIFY_ATTR_INTERRUPT_LOC};
use crate::offset_table::*;
use crate::parser::ast::*;
use crate::parser::char_reader::*;
use crate::parser::dashu::Integer;
@@ -821,7 +822,7 @@ impl MachineState {
let mut max_old = -1i64;
if !max_steps.is_var() {
let max_steps = Number::try_from(max_steps);
let max_steps = Number::try_from((max_steps, &self.arena.f64_tbl));
let max_steps_n = match max_steps {
Ok(Number::Fixnum(n)) => Some(n.get_num()),
@@ -1132,7 +1133,7 @@ impl MachineState {
for addr in addrs {
let addr = self.store(self.deref(addr));
match Number::try_from(addr) {
match Number::try_from((addr, &self.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => {
if let Ok(n) = u32::try_from(n.get_num()) {
if let Some(c) = std::char::from_u32(n) {
@@ -1241,7 +1242,13 @@ impl Machine {
let mut bp = self
.indices
.get_predicate_code_index(atom!("$clause"), 2, module_name)
.and_then(|idx| idx.local())
.and_then(|idx| {
self.machine_st
.arena
.code_index_tbl
.lookup(idx.into())
.local()
})
.unwrap();
macro_rules! extract_ptr {
@@ -1431,7 +1438,7 @@ impl Machine {
self.machine_st.error_form(err, stub)
})?;
let index_cell = if index_cell_opt.is_some() {
let index_cell_opt = if index_cell_opt.is_some() {
index_cell_opt
} else {
let is_internal_call = name == atom!("$call") && goal_arity > 0;
@@ -1469,11 +1476,13 @@ impl Machine {
}
};
if let Some(code_index) = index_cell {
if !code_index.as_ptr().is_undefined() {
if let Some(code_idx) = index_cell_opt {
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(code_idx.into());
if !index_ptr.is_undefined() {
load_registers(&mut self.machine_st, goal, goal_arity);
self.machine_st.neck_cut();
return call_at_index(self, name, arity, code_index.get());
return call_at_index(self, name, arity, index_ptr);
}
}
@@ -1653,7 +1662,7 @@ impl Machine {
let idx = CodeIndex::new(
IndexPtr::index(helper_clause_loc),
&mut self.machine_st.arena,
&mut self.machine_st.arena.code_index_tbl,
);
writer.write_with(|section| {
@@ -1694,7 +1703,7 @@ impl Machine {
let idx_cell = self.machine_st.heap[s.saturating_sub(1)];
if HeapCellValueTag::CodeIndex == idx_cell.get_tag() {
if HeapCellValueTag::CodeIndexOffset == idx_cell.get_tag() {
return true;
}
}
@@ -1846,7 +1855,7 @@ impl Machine {
#[inline(always)]
pub(crate) fn bind_from_register(&mut self) {
let reg = self.deref_register(2);
let n = match Number::try_from(reg) {
let n = match Number::try_from((reg, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
Ok(Number::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
@@ -2608,7 +2617,7 @@ impl Machine {
let addr = match addr {
addr if addr.is_var() => addr,
addr => match Number::try_from(addr) {
addr => match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Integer(n)) => {
let result: Result<u8, _> = (&*n).try_into();
if let Ok(value) = result {
@@ -2797,7 +2806,7 @@ impl Machine {
a2
}
_ => {
match Number::try_from(a2) {
match Number::try_from((a2, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Integer(n)) => {
let n: u32 = (&*n).try_into().unwrap();
@@ -2864,7 +2873,7 @@ impl Machine {
let n = self.deref_register(1);
let chs = self.deref_register(2);
let string = match Number::try_from(n) {
let string = match Number::try_from((n, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Float(OrderedFloat(n))) => fmt_float(n),
Ok(Number::Fixnum(n)) => n.get_num().to_string(),
Ok(Number::Integer(n)) => n.to_string(),
@@ -2892,7 +2901,7 @@ impl Machine {
let n = self.deref_register(1);
let chs = self.machine_st.registers[2];
let string = match Number::try_from(n) {
let string = match Number::try_from((n, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Float(OrderedFloat(n))) => {
format!("{0:<20?}", n)
}
@@ -2979,13 +2988,8 @@ impl Machine {
debug_assert_eq!(arity, 0);
name.as_char().unwrap()
}
/*
(HeapCellValueTag::Char, c) => {
c
}
*/
_ => {
match Number::try_from(a2) {
match Number::try_from((a2, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Integer(n)) => {
let n: u32 = (&*n).try_into().unwrap();
let n = std::char::from_u32(n);
@@ -3223,7 +3227,7 @@ impl Machine {
let err = self.machine_st.instantiation_error();
Err(self.machine_st.error_form(err, stub_gen()))
} else {
match Number::try_from(addr) {
match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Integer(n)) => {
let n: u32 = (&*n).try_into().unwrap();
let n = char::try_from(n);
@@ -3370,7 +3374,7 @@ impl Machine {
let err = self.machine_st.instantiation_error();
return Err(self.machine_st.error_form(err, stub_gen()));
} else {
match Number::try_from(addr) {
match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Integer(n)) => {
let n: u8 = (&*n).try_into().unwrap();
@@ -3449,7 +3453,7 @@ impl Machine {
let addr = if addr.is_var() {
addr
} else {
match Number::try_from(addr) {
match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Integer(ref n)) if (**n).num_eq(&1_i64) => {
fixnum_as_cell!(Fixnum::build_with(-1))
}
@@ -3603,7 +3607,7 @@ impl Machine {
3,
)?;
let num = match Number::try_from(self.deref_register(2)) {
let num = match Number::try_from((self.deref_register(2), &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
Ok(u) => u,
@@ -3704,7 +3708,7 @@ impl Machine {
let addr = if addr.is_var() {
addr
} else {
match Number::try_from(addr) {
match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Integer(n)) => {
let n: u32 = (&*n).try_into().unwrap();
let n = std::char::from_u32(n);
@@ -4040,7 +4044,7 @@ impl Machine {
} else {
arity_match = |arity_1, arity_2| arity_1 == arity_2;
let arity = match Number::try_from(arity) {
let arity = match Number::try_from((arity, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => Some(n.get_num() as usize),
Ok(Number::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
@@ -4299,7 +4303,10 @@ impl Machine {
pub(crate) fn random_integer(&mut self) {
let a1 = self.deref_register(1);
let a2 = self.deref_register(2);
let value = match (Number::try_from(a1), Number::try_from(a2)) {
let value = match (
Number::try_from((a1, &self.machine_st.arena.f64_tbl)),
Number::try_from((a2, &self.machine_st.arena.f64_tbl)),
) {
(Ok(Number::Fixnum(lower)), Ok(Number::Fixnum(upper))) => {
let (lower, upper) = (lower.get_num(), upper.get_num());
if lower >= upper {
@@ -4390,7 +4397,7 @@ impl Machine {
let stub_gen = || functor_stub(atom!("length"), 2);
let len = self.deref_register(2);
let n = match Number::try_from(len) {
let n = match Number::try_from((len, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => n.get_num() as usize,
Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
Ok(n) => n,
@@ -4581,23 +4588,24 @@ impl Machine {
let tls_cert = self.deref_register(4);
let content_length_limit = self.deref_register(5);
const CONTENT_LENGTH_LIMIT_DEFAULT: u64 = 32768;
let content_length_limit = match Number::try_from(content_length_limit) {
Ok(Number::Fixnum(n)) => {
if n.get_num() >= 0 {
n.get_num() as u64
} else {
CONTENT_LENGTH_LIMIT_DEFAULT
let content_length_limit =
match Number::try_from((content_length_limit, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => {
if n.get_num() >= 0 {
n.get_num() as u64
} else {
CONTENT_LENGTH_LIMIT_DEFAULT
}
}
}
Ok(Number::Integer(n)) => {
let n: Result<u64, _> = (&*n).try_into();
match n {
Ok(u) => u,
Err(_) => CONTENT_LENGTH_LIMIT_DEFAULT,
Ok(Number::Integer(n)) => {
let n: Result<u64, _> = (&*n).try_into();
match n {
Ok(u) => u,
Err(_) => CONTENT_LENGTH_LIMIT_DEFAULT,
}
}
}
_ => CONTENT_LENGTH_LIMIT_DEFAULT,
};
_ => CONTENT_LENGTH_LIMIT_DEFAULT,
};
let ssl_server: Option<(String, String)> = {
match self.machine_st.value_to_str_like(tls_key) {
@@ -4864,7 +4872,8 @@ impl Machine {
pub(crate) fn http_answer(&mut self) -> CallResult {
let culprit = self.deref_register(1);
let status_code = self.deref_register(2);
let status_code: u16 = match Number::try_from(status_code) {
let status_code: u16 = match Number::try_from((status_code, &self.machine_st.arena.f64_tbl))
{
Ok(Number::Fixnum(n)) => n.get_num() as u16,
Ok(Number::Integer(n)) => {
let n: Result<u16, _> = (&*n).try_into();
@@ -4994,7 +5003,7 @@ impl Machine {
if let Some(function_name) = self.machine_st.value_to_str_like(function_name) {
let stub_gen = || functor_stub(atom!("foreign_call"), 3);
fn map_arg(machine_st: &mut MachineState, source: HeapCellValue) -> crate::ffi::Value {
match Number::try_from(source) {
match Number::try_from((source, &machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => Value::Int(n.get_num()),
Ok(Number::Float(n)) => Value::Float(n.into_inner()),
_ => {
@@ -5297,7 +5306,7 @@ impl Machine {
let priority = self.deref_register(1);
let specifier = cell_as_atom_cell!(self.deref_register(2)).get_name();
let priority = match Number::try_from(priority) {
let priority = match Number::try_from((priority, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Integer(n)) => {
let n: u16 = (&*n).try_into().unwrap();
n
@@ -5465,7 +5474,7 @@ impl Machine {
pub(crate) fn get_attr_var_queue_beyond(&mut self) {
let addr = self.deref_register(1);
let b = match Number::try_from(addr) {
let b = match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
Some(value)
@@ -5892,7 +5901,7 @@ impl Machine {
pub(crate) fn halt(&mut self) -> std::process::ExitCode {
let code = self.deref_register(1);
let code = match Number::try_from(code) {
let code = match Number::try_from((code, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => u8::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => {
let n: u8 = (&*n).try_into().unwrap();
@@ -5929,7 +5938,7 @@ impl Machine {
let a1 = self.deref_register(1);
let a2 = self.deref_register(2);
let n = match Number::try_from(a2) {
let n = match Number::try_from((a2, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(bp)) => Integer::from(bp.get_num() as usize),
Ok(Number::Integer(n)) => (*n).clone(),
_ => {
@@ -5974,7 +5983,7 @@ impl Machine {
let name = cell_as_atom!(self.deref_register(2));
let a3 = self.deref_register(3);
let arity = match Number::try_from(a3) {
let arity = match Number::try_from((a3, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => n.get_num() as usize,
Ok(Number::Integer(n)) => {
let result = (&*n).try_into();
@@ -5992,7 +6001,14 @@ impl Machine {
self.indices
.get_predicate_code_index(name, arity, module_name)
.map(|index| index.local().is_some())
.map(|idx| {
self.machine_st
.arena
.code_index_tbl
.lookup(idx.into())
.local()
.is_some()
})
.unwrap_or(false)
}
@@ -6014,7 +6030,10 @@ impl Machine {
arity,
module_name,
)
.map(|index| index.get())
.map(|idx| *self.machine_st
.arena
.code_index_tbl
.lookup(idx.into()))
.unwrap_or(IndexPtr::dynamic_undefined());
!matches!(index.tag(), IndexPtrTag::DynamicUndefined | IndexPtrTag::Undefined)
@@ -6031,7 +6050,10 @@ impl Machine {
0,
module_name,
)
.map(|index| index.get())
.map(|idx| *self.machine_st
.arena
.code_index_tbl
.lookup(idx.into()))
.unwrap_or(IndexPtr::dynamic_undefined());
!matches!(index.tag(), IndexPtrTag::DynamicUndefined)
@@ -6667,7 +6689,7 @@ impl Machine {
pub(crate) fn set_seed(&mut self) {
let seed = self.deref_register(1);
match Number::try_from(seed) {
match Number::try_from((seed, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => {
let n: u64 = Integer::from(n).try_into().unwrap();
let rng: StdRng = SeedableRng::seed_from_u64(n);
@@ -6695,7 +6717,7 @@ impl Machine {
pub(crate) fn sleep(&mut self) {
let time = self.deref_register(1);
let time = match Number::try_from(time) {
let time = match Number::try_from((time, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Float(n)) => n.into_inner(),
Ok(Number::Fixnum(n)) => n.get_num() as f64,
Ok(Number::Integer(n)) => n.to_f64().value(),
@@ -6730,7 +6752,7 @@ impl Machine {
name
}
_ => {
AtomTable::build_with(&self.machine_st.atom_tbl, &match Number::try_from(port) {
AtomTable::build_with(&self.machine_st.atom_tbl, &match Number::try_from((port, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => n.get_num().to_string(),
Ok(Number::Integer(n)) => n.to_string(),
_ => {
@@ -6829,7 +6851,7 @@ impl Machine {
let port = if port.is_var() {
String::from("0")
} else {
match Number::try_from(port) {
match Number::try_from((port, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => n.get_num().to_string(),
Ok(Number::Integer(n)) => n.to_string(),
_ => {
@@ -7107,7 +7129,7 @@ impl Machine {
let position = self.deref_register(2);
let position = match Number::try_from(position) {
let position = match Number::try_from((position, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => n.get_num() as u64,
Ok(Number::Integer(n)) => {
let n: Result<u64, _> = (&*n).try_into();
@@ -7426,7 +7448,7 @@ impl Machine {
let name = cell_as_atom!(self.deref_register(2));
let arity = self.deref_register(3);
let arity = match Number::try_from(arity) {
let arity = match Number::try_from((arity, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => n.get_num() as usize,
Ok(Number::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
@@ -7454,22 +7476,23 @@ impl Machine {
},
};
let first_idx = match first_idx {
Some(idx) if idx.local().is_some() => {
if let Some(idx) = idx.local() {
idx
} else {
unreachable!()
}
}
_ => {
let stub = functor_stub(name, arity);
let err = self
.machine_st
.existence_error(ExistenceError::Procedure(name, arity));
let first_idx = first_idx.and_then(|first_idx| {
self.machine_st
.arena
.code_index_tbl
.lookup(first_idx.into())
.local()
});
return Err(self.machine_st.error_form(err, stub));
}
let first_idx = if let Some(idx) = first_idx {
idx
} else {
let stub = functor_stub(name, arity);
let err = self
.machine_st
.existence_error(ExistenceError::Procedure(name, arity));
return Err(self.machine_st.error_form(err, stub));
};
let listing =
@@ -7484,7 +7507,7 @@ impl Machine {
#[inline(always)]
pub(crate) fn inlined_instructions(&mut self) {
let index_ptr = self.deref_register(1);
let index_ptr = match Number::try_from(index_ptr) {
let index_ptr = match Number::try_from((index_ptr, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => n.get_num() as usize,
Ok(Number::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
@@ -7843,7 +7866,7 @@ impl Machine {
let length = self.deref_register(6);
let length = match Number::try_from(length) {
let length = match Number::try_from((length, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
Ok(u) => u,
@@ -7909,7 +7932,7 @@ impl Machine {
let iterations = self.deref_register(3);
let iterations = match Number::try_from(iterations) {
let iterations = match Number::try_from((iterations, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => u64::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => {
let n: Result<u64, _> = (&*n).try_into();
@@ -8555,7 +8578,10 @@ impl Machine {
#[inline(always)]
pub(crate) fn pop_count(&mut self) {
let number = self.deref_register(1);
let pop_count = integer_as_cell!(match Number::try_from(number) {
let pop_count = integer_as_cell!(match Number::try_from((
number,
&self.machine_st.arena.f64_tbl
)) {
Ok(Number::Fixnum(n)) => {
Number::Fixnum(Fixnum::build_with(n.get_num().count_ones()))
}

View File

@@ -216,7 +216,9 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
return;
}
match Number::try_from(value) {
let machine_st = self.deref();
match Number::try_from((value, &machine_st.arena.f64_tbl)) {
Ok(n2) => match n2 {
Number::Fixnum(n2) if n1.get_num() == n2.get_num() => {}
Number::Integer(n2) if (*n2).num_eq(&n1.get_num()) => {}
@@ -237,7 +239,9 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
return;
}
match Number::try_from(value) {
let machine_st = self.deref();
match Number::try_from((value, &machine_st.arena.f64_tbl)) {
Ok(n2) => match n2 {
Number::Fixnum(n2) if (*n1).num_eq(&n2.get_num()) => {}
Number::Integer(n2) if (*n1).num_eq(&*n2) => {}
@@ -258,7 +262,9 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
return;
}
match Number::try_from(value) {
let machine_st = self.deref_mut();
match Number::try_from((value, &machine_st.arena.f64_tbl)) {
Ok(n2) => match n2 {
Number::Fixnum(n2) if (*n1).num_eq(&Integer::from(n2.get_num())) => {}
Number::Integer(n2) if (*n1).num_eq(&*n2) => {}
@@ -273,14 +279,19 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
}
}
fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
fn unify_f64(&mut self, f1: F64Offset, value: HeapCellValue) {
if let Some(r) = value.as_var() {
Self::bind(self, r, HeapCellValue::from(f1));
return;
}
read_heap_cell!(value,
(HeapCellValueTag::F64, f2) => {
(HeapCellValueTag::F64Offset, f2) => {
let machine_st = self.deref_mut();
let f1 = machine_st.arena.f64_tbl.lookup(f1);
let f2 = machine_st.arena.f64_tbl.lookup(f2.into());
self.fail = **f1 != **f2;
}
_ => {
@@ -414,17 +425,12 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
tabu_list.insert((d1, d2));
}
}
(HeapCellValueTag::F64, f1) => {
(HeapCellValueTag::F64Offset, f1) => {
Self::unify_f64(self, f1, d2);
}
(HeapCellValueTag::Fixnum, n1) => {
Self::unify_fixnum(self, n1, d2);
}
/*
(HeapCellValueTag::Char, c1) => {
Self::unify_char(self, c1, d2);
}
*/
(HeapCellValueTag::Cons, ptr_1) => {
Self::unify_constant(self, ptr_1, d2);
}

View File

@@ -53,17 +53,17 @@ macro_rules! cell_as_atom_cell {
};
}
macro_rules! cell_as_f64_ptr {
macro_rules! cell_as_f64_offset {
($cell:expr) => {{
let offset = $cell.get_value() as usize;
F64Ptr::from_offset(F64Offset::from(offset))
F64Offset::from(offset)
}};
}
macro_rules! cell_as_code_index {
macro_rules! cell_as_code_index_offset {
($cell:expr) => {{
let offset = $cell.get_value() as usize;
CodeIndex::from(CodeIndexOffset::from(offset))
CodeIndexOffset::from(offset)
}};
}
@@ -266,13 +266,13 @@ macro_rules! read_heap_cell_pat_body {
#[allow(unused_braces)]
$code
}};
($cell:ident, F64, $n:ident, $code:expr) => {{
let $n = cell_as_f64_ptr!($cell);
($cell:ident, F64Offset, $n:ident, $code:expr) => {{
let $n = cell_as_f64_offset!($cell);
#[allow(unused_braces)]
$code
}};
($cell:ident, CodeIndex, $n:ident, $code:expr) => {{
let $n = cell_as_code_index!($cell);
($cell:ident, CodeIndexOffset, $n:ident, $code:expr) => {{
let $n = cell_as_code_index_offset!($cell);
#[allow(unused_braces)]
$code
}};
@@ -281,26 +281,6 @@ macro_rules! read_heap_cell_pat_body {
#[allow(unused_braces)]
$code
}};
($cell:ident, PStr, $atom:ident, $code:expr) => {{
let $atom = cell_as_atom!($cell);
#[allow(unused_braces)]
$code
}};
($cell:ident, CStr, $atom:ident, $code:expr) => {{
let $atom = cell_as_atom!($cell);
#[allow(unused_braces)]
$code
}};
($cell:ident, CStr | PStr, $atom:ident, $code:expr) => {{
let $atom = cell_as_atom!($cell);
#[allow(unused_braces)]
$code
}};
($cell:ident, PStr | CStr, $atom:ident, $code:expr) => {{
let $atom = cell_as_atom!($cell);
#[allow(unused_braces)]
$code
}};
($cell:ident, Fixnum, $value:ident, $code:expr) => {{
let $value = Fixnum::from_bytes($cell.into_bytes());
#[allow(unused_braces)]
@@ -321,11 +301,6 @@ macro_rules! read_heap_cell_pat_body {
#[allow(unused_braces)]
$code
}};
($cell:ident, Char, $value:ident, $code:expr) => {{
let $value = unsafe { char::from_u32_unchecked($cell.get_value() as u32) };
#[allow(unused_braces)]
$code
}};
($cell:ident, $($tags:tt)|+, $value:ident, $code:expr) => {{
let $value = $cell.get_value() as usize;
#[allow(unused_braces)]

View File

@@ -1,8 +1,6 @@
use std::cell::UnsafeCell;
use std::hash::{Hash, Hasher};
use std::ops::{Deref, DerefMut};
use std::sync::RwLock;
use std::sync::Weak;
use std::sync::{Arc, Mutex};
use std::{fmt, mem, ptr};
@@ -23,19 +21,7 @@ const F64_TABLE_ALIGN: usize = 8;
const CODE_INDEX_TABLE_INIT_SIZE: usize = 1 << 16;
const CODE_INDEX_TABLE_ALIGN: usize = 8;
#[derive(Debug)]
pub struct OffsetTableImpl<T>
where
OffsetTableImpl<T>: RawBlockTraits,
{
block: Arcu<RawBlock<OffsetTableImpl<T>>, GlobalEpochCounterPool>,
update: Mutex<()>,
}
pub type F64Table = OffsetTableImpl<OrderedFloat<f64>>;
pub type CodeIndexTable = OffsetTableImpl<IndexPtr>;
impl RawBlockTraits for F64Table {
impl RawBlockTraits for OrderedFloat<f64> {
#[inline]
fn init_size() -> usize {
F64_TABLE_INIT_SIZE
@@ -47,7 +33,7 @@ impl RawBlockTraits for F64Table {
}
}
impl RawBlockTraits for CodeIndexTable {
impl RawBlockTraits for IndexPtr {
#[inline]
fn init_size() -> usize {
CODE_INDEX_TABLE_INIT_SIZE
@@ -59,72 +45,159 @@ impl RawBlockTraits for CodeIndexTable {
}
}
pub trait OffsetTable: RawBlockTraits {
type Offset: Copy + From<usize> + Into<usize>;
type Stored;
fn global_table() -> &'static RwLock<Weak<Self>>;
}
impl OffsetTable for F64Table {
type Offset = F64Offset;
type Stored = OrderedFloat<f64>;
#[derive(Debug)]
pub struct OffsetTableImpl<T: RawBlockTraits>(InnerOffsetTableImpl<T>);
impl<T: RawBlockTraits> OffsetTableImpl<T> {
#[inline(always)]
fn global_table() -> &'static RwLock<Weak<Self>> {
static GLOBAL_ATOM_TABLE: RwLock<Weak<F64Table>> = RwLock::new(Weak::new());
&GLOBAL_ATOM_TABLE
pub fn new() -> Self {
Self(InnerOffsetTableImpl::Serial(SerialOffsetTable::new()))
}
}
impl OffsetTable for CodeIndexTable {
type Offset = CodeIndexOffset;
type Stored = IndexPtr;
#[inline(always)]
fn global_table() -> &'static RwLock<Weak<CodeIndexTable>> {
static GLOBAL_CODE_INDEX_TABLE: RwLock<Weak<CodeIndexTable>> = RwLock::new(Weak::new());
&GLOBAL_CODE_INDEX_TABLE
impl<T: RawBlockTraits> Default for OffsetTableImpl<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: 'static> OffsetTableImpl<T>
where
OffsetTableImpl<T>: OffsetTable<Stored = T>,
{
#[inline]
pub fn new() -> Arc<Self> {
let upgraded = Self::global_table().read().unwrap().upgrade();
// don't inline upgraded, otherwise temporary will be dropped too late in case of None
if let Some(atom_table) = upgraded {
atom_table
} else {
let mut guard = Self::global_table().write().unwrap();
// try to upgrade again in case we lost the race on the write lock
if let Some(atom_table) = guard.upgrade() {
atom_table
} else {
let table = Arc::new(Self {
block: Arcu::new(RawBlock::new(), GlobalEpochCounterPool),
update: Mutex::new(()),
});
*guard = Arc::downgrade(&table);
table
}
#[derive(Debug)]
enum InnerOffsetTableImpl<T: RawBlockTraits> {
Serial(SerialOffsetTable<T>),
#[allow(dead_code)]
Concurrent(Arc<ConcurrentOffsetTable<T>>),
}
impl<T: RawBlockTraits> InnerOffsetTableImpl<T> {
#[inline(always)]
fn build_with(&mut self, value: T) -> usize {
match self {
Self::Concurrent(concurrent_tbl) => unsafe { concurrent_tbl.build_with(value) },
Self::Serial(serial_tbl) => unsafe { serial_tbl.build_with(value) },
}
}
#[inline(always)]
fn lookup<'a>(&'a self, offset: usize) -> TablePtr<'a, T> {
match self {
Self::Concurrent(concurrent_tbl) => {
TablePtr(InnerTablePtr::Concurrent(concurrent_tbl.lookup(offset)))
}
Self::Serial(serial_tbl) => unsafe {
TablePtr(InnerTablePtr::Serial(serial_tbl.lookup(offset)))
},
}
}
#[inline(always)]
fn lookup_mut<'a>(&'a mut self, offset: usize) -> TablePtrMut<'a, T> {
match self {
Self::Concurrent(concurrent_tbl) => TablePtrMut(InnerTablePtrMut::Concurrent(
concurrent_tbl.lookup_mut(offset),
)),
Self::Serial(serial_tbl) => unsafe {
TablePtrMut(InnerTablePtrMut::Serial(serial_tbl.lookup_mut(offset)))
},
}
}
}
pub trait OffsetTable<T: RawBlockTraits> {
type Offset: Copy + Into<usize>;
fn build_with(&mut self, value: T) -> Self::Offset;
fn lookup<'a>(&'a self, offset: Self::Offset) -> TablePtr<'a, T>;
fn lookup_mut<'a>(&'a mut self, offset: Self::Offset) -> TablePtrMut<'a, T>;
}
impl OffsetTable<OrderedFloat<f64>> for OffsetTableImpl<OrderedFloat<f64>> {
type Offset = F64Offset;
fn build_with(&mut self, value: OrderedFloat<f64>) -> F64Offset {
F64Offset(self.0.build_with(value))
}
fn lookup<'a>(&'a self, offset: F64Offset) -> TablePtr<'a, OrderedFloat<f64>> {
self.0.lookup(offset.into())
}
fn lookup_mut<'a>(&'a mut self, offset: F64Offset) -> TablePtrMut<'a, OrderedFloat<f64>> {
self.0.lookup_mut(offset.into())
}
}
impl OffsetTable<IndexPtr> for OffsetTableImpl<IndexPtr> {
type Offset = CodeIndexOffset;
fn build_with(&mut self, value: IndexPtr) -> CodeIndexOffset {
CodeIndexOffset(self.0.build_with(value))
}
fn lookup<'a>(&'a self, offset: CodeIndexOffset) -> TablePtr<'a, IndexPtr> {
self.0.lookup(offset.into())
}
fn lookup_mut<'a>(&'a mut self, offset: CodeIndexOffset) -> TablePtrMut<'a, IndexPtr> {
self.0.lookup_mut(offset.into())
}
}
#[derive(Debug)]
struct SerialOffsetTable<T: RawBlockTraits> {
block: RawBlock<T>,
}
impl<T: RawBlockTraits> SerialOffsetTable<T> {
#[inline]
fn new() -> Self {
Self {
block: RawBlock::new(),
}
}
unsafe fn build_with(&mut self, value: T) -> usize {
let mut ptr;
loop {
ptr = self.block.alloc(size_of::<T>());
if ptr.is_null() {
let new_block = self.block.grow_new().unwrap();
self.block = new_block;
} else {
break;
}
}
ptr::write(ptr as *mut T, value);
ptr.addr() - self.block.base.addr()
}
#[inline]
unsafe fn lookup(&self, offset: usize) -> &T {
&*self.block.base.add(offset).cast::<T>()
}
#[inline]
unsafe fn lookup_mut(&mut self, offset: usize) -> &mut T {
&mut *self.block.base.add(offset).cast::<T>().cast_mut()
}
}
#[derive(Debug)]
pub struct ConcurrentOffsetTable<T: RawBlockTraits> {
block: Arcu<RawBlock<T>, GlobalEpochCounterPool>,
update: Mutex<()>,
}
impl<T: RawBlockTraits> ConcurrentOffsetTable<T> {
#[allow(clippy::missing_safety_doc)]
pub unsafe fn build_with(
&self,
value: <OffsetTableImpl<T> as OffsetTable>::Stored,
) -> <OffsetTableImpl<T> as OffsetTable>::Offset {
unsafe fn build_with(&self, value: T) -> usize {
let update_guard = self.update.lock();
// we don't have an index table for lookups as AtomTable does so
// just get the epoch after we take the upgrade lock
let mut block_epoch = self.block.read();
let mut ptr;
loop {
@@ -141,8 +214,7 @@ where
ptr::write(ptr as *mut T, value);
let value =
<OffsetTableImpl<T> as OffsetTable>::Offset::from(ptr.addr() - block_epoch.base.addr());
let value = ptr.addr() - block_epoch.base.addr();
// AtomTable would have to update the index table at this point
// explicit drop to ensure we don't accidentally drop it early
@@ -151,17 +223,20 @@ where
value
}
pub fn lookup(offset: <Self as OffsetTable>::Offset) -> RcuRef<RawBlock<Self>, UnsafeCell<T>> {
let table = Self::global_table()
.read()
.unwrap()
.upgrade()
.expect("We should only be looking up entries when there is a table");
#[inline]
fn lookup(&self, offset: usize) -> RcuRef<RawBlock<T>, T> {
RcuRef::try_map(self.block.read(), |raw_block| unsafe {
raw_block.base.add(offset).cast::<T>().as_ref()
})
.expect("The offset should result in a non-null pointer")
}
RcuRef::try_map(table.block.read(), |raw_block| unsafe {
#[inline]
fn lookup_mut(&self, offset: usize) -> RcuRef<RawBlock<T>, UnsafeCell<T>> {
RcuRef::try_map(self.block.read(), |raw_block| unsafe {
raw_block
.base
.add(offset.into())
.add(offset)
.cast_mut()
.cast::<UnsafeCell<T>>()
.as_ref()
@@ -170,109 +245,8 @@ where
}
}
#[derive(Debug)]
pub struct TablePtr<T>(RcuRef<RawBlock<OffsetTableImpl<T>>, UnsafeCell<T>>)
where
OffsetTableImpl<T>: RawBlockTraits;
pub type CodeIndexPtr = TablePtr<IndexPtr>;
pub type F64Ptr = TablePtr<OrderedFloat<f64>>;
impl<T> Clone for TablePtr<T>
where
OffsetTableImpl<T>: RawBlockTraits,
{
fn clone(&self) -> Self {
Self(RcuRef::clone(&self.0))
}
}
impl<T: PartialEq> PartialEq for TablePtr<T>
where
OffsetTableImpl<T>: RawBlockTraits,
{
fn eq(&self, other: &TablePtr<T>) -> bool {
RcuRef::ptr_eq(&self.0, &other.0) || self.deref() == other.deref()
}
}
impl<T: Eq> Eq for TablePtr<T> where OffsetTableImpl<T>: RawBlockTraits {}
impl<T: PartialOrd + Ord> PartialOrd for TablePtr<T>
where
OffsetTableImpl<T>: RawBlockTraits,
{
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<T: Ord> Ord for TablePtr<T>
where
OffsetTableImpl<T>: RawBlockTraits,
{
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
(**self).cmp(&**other)
}
}
impl<T: Hash> Hash for TablePtr<T>
where
OffsetTableImpl<T>: RawBlockTraits,
{
#[inline(always)]
fn hash<H: Hasher>(&self, hasher: &mut H) {
(self as &T).hash(hasher)
}
}
impl<T: fmt::Display> fmt::Display for TablePtr<T>
where
OffsetTableImpl<T>: RawBlockTraits,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self as &T)
}
}
impl<T> Deref for TablePtr<T>
where
OffsetTableImpl<T>: RawBlockTraits,
{
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe { self.0.get().as_ref().unwrap() }
}
}
impl<T> DerefMut for TablePtr<T>
where
OffsetTableImpl<T>: RawBlockTraits,
{
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.0.get().as_mut().unwrap() }
}
}
impl<T: 'static> TablePtr<T>
where
OffsetTableImpl<T>: OffsetTable<Stored = T>,
{
#[inline(always)]
pub fn from_offset(offset: <OffsetTableImpl<T> as OffsetTable>::Offset) -> Self {
Self(OffsetTableImpl::<T>::lookup(offset))
}
#[inline(always)]
pub fn as_offset(&self) -> <OffsetTableImpl<T> as OffsetTable>::Offset {
<OffsetTableImpl<T> as OffsetTable>::Offset::from(
self.0.get().addr() - RcuRef::get_root(&self.0).base.addr(),
)
}
}
pub type F64Table = OffsetTableImpl<OrderedFloat<f64>>;
pub type CodeIndexTable = OffsetTableImpl<IndexPtr>;
#[derive(Clone, Copy, Debug)]
pub struct F64Offset(usize);
@@ -284,10 +258,9 @@ impl From<usize> for F64Offset {
}
}
impl Into<usize> for F64Offset {
#[inline(always)]
fn into(self: Self) -> usize {
self.0
impl From<F64Offset> for usize {
fn from(val: F64Offset) -> Self {
val.0
}
}
@@ -301,57 +274,71 @@ impl From<usize> for CodeIndexOffset {
}
}
impl Into<usize> for CodeIndexOffset {
impl From<CodeIndexOffset> for usize {
#[inline(always)]
fn into(self: Self) -> usize {
self.0
fn from(val: CodeIndexOffset) -> Self {
val.0
}
}
impl CodeIndexOffset {
#[inline(always)]
pub fn from_ptr(ptr: CodeIndexPtr) -> Self {
ptr.as_offset()
}
#[inline(always)]
pub fn as_ptr(self) -> CodeIndexPtr {
CodeIndexPtr::from_offset(self)
}
#[inline(always)]
pub fn to_u64(self) -> u64 {
self.0 as u64
}
}
impl PartialEq for CodeIndexOffset {
#[inline(always)]
fn eq(&self, other: &CodeIndexOffset) -> bool {
self.as_ptr() == other.as_ptr()
#[derive(Debug)]
pub struct TablePtr<'a, T: RawBlockTraits>(InnerTablePtr<'a, T>);
#[derive(Debug)]
enum InnerTablePtr<'a, T: RawBlockTraits> {
Concurrent(RcuRef<RawBlock<T>, T>),
Serial(&'a T),
}
impl<T: PartialEq + RawBlockTraits> PartialEq for TablePtr<'_, T> {
fn eq(&self, other: &TablePtr<'_, T>) -> bool {
self.deref() == other.deref()
}
}
impl Eq for CodeIndexOffset {}
impl<T: Eq + RawBlockTraits> Eq for TablePtr<'_, T> {}
impl PartialOrd for CodeIndexOffset {
#[inline(always)]
impl<T: PartialOrd + Ord + RawBlockTraits> PartialOrd for TablePtr<'_, T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for CodeIndexOffset {
#[inline(always)]
impl<T: Ord + RawBlockTraits> Ord for TablePtr<'_, T> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_ptr().cmp(&other.as_ptr())
(**self).cmp(&**other)
}
}
impl Hash for CodeIndexOffset {
impl<T: Hash + RawBlockTraits> Hash for TablePtr<'_, T> {
#[inline(always)]
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.as_ptr().hash(hasher)
(self as &T).hash(hasher)
}
}
impl<T: fmt::Display + RawBlockTraits> fmt::Display for TablePtr<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self as &T)
}
}
impl<T: RawBlockTraits> Deref for TablePtr<'_, T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
match &self.0 {
InnerTablePtr::Concurrent(rcu_ref) => rcu_ref,
InnerTablePtr::Serial(ref_mut) => ref_mut,
}
}
}
@@ -361,67 +348,103 @@ impl fmt::Display for CodeIndexOffset {
}
}
impl CodeIndexPtr {
#[inline]
pub fn set(&self, val: IndexPtr) {
unsafe { *self.0.get() = val };
}
#[inline]
pub fn replace(&self, val: IndexPtr) -> IndexPtr {
unsafe { self.0.get().replace(val) }
}
}
impl F64Offset {
#[inline(always)]
pub fn from_ptr(ptr: F64Ptr) -> Self {
ptr.as_offset()
}
#[inline(always)]
pub fn as_ptr(self) -> F64Ptr {
F64Ptr::from_offset(self)
}
#[inline(always)]
pub fn to_u64(self) -> u64 {
self.0 as u64
}
}
impl PartialEq for F64Offset {
#[inline(always)]
fn eq(&self, other: &F64Offset) -> bool {
self.as_ptr() == other.as_ptr()
}
}
impl Eq for F64Offset {}
impl PartialOrd for F64Offset {
#[inline(always)]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for F64Offset {
#[inline(always)]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_ptr().cmp(&other.as_ptr())
}
}
impl Hash for F64Offset {
#[inline(always)]
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.as_ptr().hash(hasher)
}
}
impl fmt::Display for F64Offset {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "F64Offset({})", self.0)
}
}
#[derive(Debug)]
pub struct TablePtrMut<'a, T: RawBlockTraits>(InnerTablePtrMut<'a, T>);
#[derive(Debug)]
enum InnerTablePtrMut<'a, T: RawBlockTraits> {
Concurrent(RcuRef<RawBlock<T>, UnsafeCell<T>>),
Serial(&'a mut T),
}
impl<T: PartialEq + RawBlockTraits> PartialEq for TablePtrMut<'_, T> {
fn eq(&self, other: &TablePtrMut<'_, T>) -> bool {
self.deref() == other.deref()
}
}
impl<T: Eq + RawBlockTraits> Eq for TablePtrMut<'_, T> {}
impl<T: PartialOrd + Ord + RawBlockTraits> PartialOrd for TablePtrMut<'_, T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<T: Ord + RawBlockTraits> Ord for TablePtrMut<'_, T> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
(**self).cmp(&**other)
}
}
impl<T: Hash + RawBlockTraits> Hash for TablePtrMut<'_, T> {
#[inline(always)]
fn hash<H: Hasher>(&self, hasher: &mut H) {
(self as &T).hash(hasher)
}
}
impl<T: fmt::Display + RawBlockTraits> fmt::Display for TablePtrMut<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self as &T)
}
}
impl<T: RawBlockTraits> Deref for TablePtrMut<'_, T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
match &self.0 {
InnerTablePtrMut::Concurrent(rcu_ref) => unsafe { rcu_ref.get().as_ref().unwrap() },
InnerTablePtrMut::Serial(ref_mut) => ref_mut,
}
}
}
impl<T: RawBlockTraits> DerefMut for TablePtrMut<'_, T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
match &mut self.0 {
InnerTablePtrMut::Concurrent(rcu_ref) => unsafe {
&mut *rcu_ref.get().as_mut().unwrap()
},
InnerTablePtrMut::Serial(ref_mut) => ref_mut,
}
}
}
impl TablePtrMut<'_, IndexPtr> {
#[inline]
pub fn set(&mut self, val: IndexPtr) {
match &mut self.0 {
InnerTablePtrMut::Concurrent(rcu_ref) => unsafe {
*rcu_ref.get() = val;
},
InnerTablePtrMut::Serial(ref_mut) => {
**ref_mut = val;
}
}
}
#[inline]
pub fn replace(&mut self, val: IndexPtr) -> IndexPtr {
match &mut self.0 {
InnerTablePtrMut::Concurrent(rcu_ref) => unsafe { rcu_ref.get().replace(val) },
InnerTablePtrMut::Serial(ref_mut) => mem::replace(*ref_mut, val),
}
}
}

View File

@@ -2,7 +2,6 @@
use crate::arena::*;
use crate::atom_table::*;
use crate::machine::machine_indices::CodeIndex;
use crate::offset_table::*;
use crate::parser::char_reader::*;
use crate::types::HeapCellValueTag;
@@ -698,17 +697,18 @@ impl Not for Fixnum {
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Copy, Clone)]
pub enum Literal {
Atom(Atom),
CodeIndex(CodeIndex),
CodeIndexOffset(CodeIndexOffset),
Fixnum(Fixnum),
Integer(TypedArenaPtr<Integer>),
Rational(TypedArenaPtr<Rational>),
Float(F64Offset),
F64Offset(F64Offset),
}
impl From<F64Ptr> for Literal {
/*
impl From<F64Ptr<'_>> for Literal {
#[inline(always)]
fn from(ptr: F64Ptr) -> Literal {
Literal::Float(ptr.as_offset())
@@ -721,14 +721,15 @@ impl fmt::Display for Literal {
Literal::Atom(ref atom) => {
write!(f, "{}", atom.flat_index())
}
Literal::CodeIndex(i) => write!(f, "{:?}", *i.as_ptr()),
Literal::CodeIndexOffset(i) => write!(f, "{}", *i),
Literal::Fixnum(n) => write!(f, "{}", n.get_num()),
Literal::Integer(ref n) => write!(f, "{}", n),
Literal::Rational(ref n) => write!(f, "{}", n),
Literal::Float(ref n) => write!(f, "{}", *n),
Literal::FloatOffset(ref n) => write!(f, "{}", *n),
}
}
}
*/
impl Literal {
pub fn as_atom(&self, atom_tbl: &Arc<AtomTable>) -> Option<Atom> {
@@ -874,7 +875,7 @@ impl Term {
pub(crate) fn unfold_by_str_once(term: &mut Term, s: Atom) -> Option<(Term, Term)> {
if let Term::Clause(_, ref name, ref mut subterms) = term {
if let Some(Term::Literal(_, Literal::CodeIndex(_))) = subterms.last() {
if let Some(Term::Literal(_, Literal::CodeIndexOffset(_))) = subterms.last() {
subterms.pop();
}

View File

@@ -1,7 +1,7 @@
use crate::arena::*;
use crate::atom_table::*;
pub use crate::machine::machine_state::*;
use crate::offset_table::F64Ptr;
use crate::offset_table::*;
use crate::parser::ast::*;
use crate::parser::char_reader::*;
use crate::parser::dashu::Integer;
@@ -30,7 +30,7 @@ struct LayoutInfo {
more: bool,
}
#[derive(Debug, PartialEq)]
#[derive(Debug)]
pub enum Token {
Literal(Literal),
Var(String),
@@ -58,7 +58,7 @@ impl Token {
enum Number {
BigInt(TypedArenaPtr<Integer>),
Fixnum(Fixnum),
Float(F64Ptr),
Float(F64Offset),
}
impl Number {
@@ -67,7 +67,7 @@ impl Number {
match self {
Number::BigInt(ibig) => Literal::Integer(ibig),
Number::Fixnum(fixnum) => Literal::Fixnum(fixnum),
Number::Float(f) => Literal::Float(f.as_offset()),
Number::Float(f) => Literal::F64Offset(f),
}
}
}
@@ -944,8 +944,8 @@ impl<'a, R: CharRead> Lexer<'a, R> {
Ok(n) => Ok(Token::Literal(n.to_literal())),
Err(_) => {
let n = parse_float_lossy(&token_string)?;
Ok(Token::Literal(Literal::Float(
float_alloc!(n, self.machine_st.arena).as_offset(),
Ok(Token::Literal(Literal::F64Offset(
float_alloc!(n, self.machine_st.arena),
)))
}
},

View File

@@ -3,12 +3,11 @@ use dashu::Rational;
use crate::arena::*;
use crate::atom_table::*;
use crate::offset_table::OffsetTable;
use crate::parser::ast::*;
use crate::parser::char_reader::*;
use crate::parser::lexer::*;
use ordered_float::OrderedFloat;
use std::cell::Cell;
use std::mem;
use std::ops::Neg;
@@ -963,17 +962,21 @@ impl<'a, R: CharRead> Parser<'a, R> {
Token::Literal(Literal::Rational(n)) => {
self.negate_number(n, negate_rat_rc, |r, _| Literal::Rational(r))
}
Token::Literal(Literal::Float(n)) if n.as_ptr().is_infinite() => {
Token::Literal(Literal::F64Offset(n)) if self.lexer.machine_st.arena.f64_tbl.lookup(n).is_infinite() => {
return Err(ParserError::InfiniteFloat(
self.lexer.line_num,
self.lexer.col_num,
));
}
Token::Literal(Literal::Float(n)) => self.negate_number(
**n.as_ptr(),
|n, _| -n,
|n, arena| Literal::from(float_alloc!(n, arena)),
),
Token::Literal(Literal::F64Offset(n)) => {
let n = *self.lexer.machine_st.arena.f64_tbl.lookup(n);
self.negate_number(
n,
|n, _| -n,
|n, arena| Literal::F64Offset(arena.f64_tbl.build_with(n)),
)
}
Token::Literal(Literal::Fixnum(n)) => {
self.negate_number(n, |n, _| -n, |n, _| Literal::Fixnum(n))
}

View File

@@ -30,9 +30,9 @@ pub enum HeapCellValueTag {
PStrLoc = 0b010011,
// constants.
Cons = 0b0,
F64 = 0b010101,
F64Offset = 0b010101,
Fixnum = 0b011001,
CodeIndex = 0b011011,
CodeIndexOffset = 0b011011,
Atom = 0b011111,
CutPoint = 0b011101,
// trail elements.
@@ -57,9 +57,9 @@ pub enum HeapCellValueView {
PStrLoc = 0b010011,
// constants.
Cons = 0b0,
F64 = 0b010101,
F64Offset = 0b010101,
Fixnum = 0b011001,
CodeIndex = 0b011011,
CodeIndexOffset = 0b011011,
Atom = 0b011111,
CutPoint = 0b011101,
// trail elements.
@@ -261,9 +261,9 @@ pub struct HeapCellValue {
impl fmt::Debug for HeapCellValue {
fn fmt(&self, f: &mut std::fmt::Formatter) -> fmt::Result {
match self.get_tag() {
HeapCellValueTag::F64 => f
HeapCellValueTag::F64Offset => f
.debug_struct("HeapCellValue")
.field("tag", &HeapCellValueTag::F64)
.field("tag", &HeapCellValueTag::F64Offset)
.field("offset", &self.get_value())
.field("m", &self.m())
.field("f", &self.f())
@@ -289,18 +289,6 @@ impl fmt::Debug for HeapCellValue {
.field("f", &self.f())
.finish()
}
/*
HeapCellValueTag::PStr => {
let (name, _) = cell_as_atom_cell!(self).get_name_and_arity();
f.debug_struct("HeapCellValue")
.field("tag", &HeapCellValueTag::PStr)
.field("contents", &name.as_str())
.field("m", &self.m())
.field("f", &self.f())
.finish()
}
*/
tag => f
.debug_struct("HeapCellValue")
.field("tag", &tag)
@@ -317,7 +305,7 @@ impl From<Literal> for HeapCellValue {
fn from(literal: Literal) -> Self {
match literal {
Literal::Atom(name) => atom_as_cell!(name),
Literal::CodeIndex(idx) => HeapCellValue::from(idx),
Literal::CodeIndexOffset(idx) => HeapCellValue::from(idx),
Literal::Fixnum(n) => fixnum_as_cell!(n),
Literal::Integer(bigint_ptr) => {
typed_arena_ptr_as_cell!(bigint_ptr)
@@ -325,7 +313,7 @@ impl From<Literal> for HeapCellValue {
Literal::Rational(bigint_ptr) => {
typed_arena_ptr_as_cell!(bigint_ptr)
}
Literal::Float(f) => HeapCellValue::from(f.as_ptr()),
Literal::F64Offset(f) => HeapCellValue::from(f),
}
}
}
@@ -345,11 +333,11 @@ impl TryFrom<HeapCellValue> for Literal {
(HeapCellValueTag::Fixnum, n) => {
Ok(Literal::Fixnum(n))
}
(HeapCellValueTag::F64, f) => {
Ok(Literal::Float(f.as_offset()))
(HeapCellValueTag::F64Offset, f) => {
Ok(Literal::F64Offset(f))
}
(HeapCellValueTag::CodeIndex, idx) => {
Ok(Literal::CodeIndex(idx))
(HeapCellValueTag::CodeIndexOffset, idx) => {
Ok(Literal::CodeIndexOffset(idx))
}
(HeapCellValueTag::Cons, cons_ptr) => {
match_untyped_arena_ptr!(cons_ptr,
@@ -381,19 +369,19 @@ where
}
}
impl From<F64Ptr> for HeapCellValue {
impl From<F64Offset> for HeapCellValue {
#[inline]
fn from(f64_ptr: F64Ptr) -> HeapCellValue {
HeapCellValue::build_with(HeapCellValueTag::F64, f64_ptr.as_offset().to_u64())
fn from(f64_offset: F64Offset) -> HeapCellValue {
HeapCellValue::build_with(HeapCellValueTag::F64Offset, f64_offset.to_u64())
}
}
impl From<CodeIndexPtr> for HeapCellValue {
impl From<CodeIndexOffset> for HeapCellValue {
#[inline]
fn from(code_index_ptr: CodeIndexPtr) -> HeapCellValue {
fn from(code_index_offset: CodeIndexOffset) -> HeapCellValue {
HeapCellValue::build_with(
HeapCellValueTag::CodeIndex,
code_index_ptr.as_offset().to_u64(),
HeapCellValueTag::CodeIndexOffset,
code_index_offset.to_u64(),
)
}
}
@@ -472,7 +460,7 @@ impl HeapCellValue {
| HeapCellValueTag::Var
| HeapCellValueTag::StackVar
| HeapCellValueTag::AttrVar
| HeapCellValueTag::PStrLoc // | HeapCellValueTag::PStrOffset
| HeapCellValueTag::PStrLoc
)
}
@@ -496,7 +484,7 @@ impl HeapCellValue {
pub fn is_constant(self) -> bool {
match self.get_tag() {
HeapCellValueTag::Cons
| HeapCellValueTag::F64
| HeapCellValueTag::F64Offset
| HeapCellValueTag::Fixnum
| HeapCellValueTag::CutPoint => true,
HeapCellValueTag::Atom => cell_as_atom_cell!(self).get_arity() == 0,
@@ -661,38 +649,52 @@ impl HeapCellValue {
}
pub fn order_category(self, heap: &Heap) -> Option<TermOrderCategory> {
match Number::try_from(self).ok() {
Some(Number::Integer(_)) | Some(Number::Fixnum(_)) | Some(Number::Rational(_)) => {
read_heap_cell!(self,
(HeapCellValueTag::Cons, c) => {
match_untyped_arena_ptr!(c,
(ArenaHeaderTag::Integer, _n) => {
Some(TermOrderCategory::Integer)
}
(ArenaHeaderTag::Rational, _n) => {
Some(TermOrderCategory::Integer)
}
_ => {
None
}
)
}
(HeapCellValueTag::F64Offset) => {
Some(TermOrderCategory::FloatingPoint)
}
(HeapCellValueTag::Fixnum | HeapCellValueTag::CutPoint) => {
Some(TermOrderCategory::Integer)
}
Some(Number::Float(_)) => Some(TermOrderCategory::FloatingPoint),
None => match self.get_tag() {
HeapCellValueTag::Var | HeapCellValueTag::StackVar | HeapCellValueTag::AttrVar => {
Some(TermOrderCategory::Variable)
}
// HeapCellValueTag::Char => Some(TermOrderCategory::Atom),
HeapCellValueTag::Atom => Some(if cell_as_atom_cell!(self).get_arity() > 0 {
(HeapCellValueTag::Var | HeapCellValueTag::StackVar | HeapCellValueTag::AttrVar) => {
Some(TermOrderCategory::Variable)
}
(HeapCellValueTag::Atom, (_name, arity)) => {
Some(if arity > 0 {
TermOrderCategory::Compound
} else {
TermOrderCategory::Atom
}),
HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc => {
// | HeapCellValueTag::CStr => {
})
}
(HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc) => {
Some(TermOrderCategory::Compound)
}
(HeapCellValueTag::Str, s) => {
let arity = cell_as_atom_cell!(heap[s]).get_arity();
if arity == 0 {
Some(TermOrderCategory::Atom)
} else {
Some(TermOrderCategory::Compound)
}
HeapCellValueTag::Str => {
let value = heap[self.get_value() as usize];
let arity = cell_as_atom_cell!(value).get_arity();
if arity == 0 {
Some(TermOrderCategory::Atom)
} else {
Some(TermOrderCategory::Compound)
}
}
_ => None,
},
}
}
_ => {
None
}
)
}
#[inline(always)]