]> Repositorios git - scryer-prolog.git/commitdiff
use OffsetTableImpl without synchronization by default
authorMark Thom <[email protected]>
Fri, 23 May 2025 06:49:57 +0000 (23:49 -0700)
committerMark Thom <[email protected]>
Tue, 8 Jul 2025 05:39:47 +0000 (22:39 -0700)
28 files changed:
build/instructions_template.rs
src/arena.rs
src/arithmetic.rs
src/codegen.rs
src/forms.rs
src/heap_print.rs
src/machine/arithmetic_ops.rs
src/machine/compile.rs
src/machine/disjuncts.rs
src/machine/dispatch.rs
src/machine/heap.rs
src/machine/lib_machine/mod.rs
src/machine/load_state.rs
src/machine/loader.rs
src/machine/machine_indices.rs
src/machine/machine_state.rs
src/machine/machine_state_impl.rs
src/machine/mock_wam.rs
src/machine/mod.rs
src/machine/preprocessor.rs
src/machine/system_calls.rs
src/machine/unify.rs
src/macros.rs
src/offset_table.rs
src/parser/ast.rs
src/parser/lexer.rs
src/parser/parser.rs
src/types.rs

index baa596268c8adf76e3c30304b30db9a021506921..dc2ed9f7710cb1e4d9f5d3ffc4729ba688aaf876 100644 (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! {
index a6ccb921be1892e7feaa3e8c0fbee8ebb57928c4..2be3a9f91bde3ed1794e92de5c756c50f84c0b94 100644 (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
 
index 2f0df28de6ec6cac6756338f46af6f713a947860..a4aad3f853cf6dbd0041bf1541fde45f7138db7b 100644 (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))
index 4145865328ef4ad884d52dbd2c3cd7cfc7fe040a..afde0ab7618bd104f86a03e7e65ff3ddc6c77b4b 100644 (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(_),
             ) => {
index 0779d5b8537dba017ef09f8ce0c07c9423c41c16..1418b5701047ba416803e9ea5b286868af2fcadb 100644 (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),
         }
     }
index c23344bfc8a3c9ceb0513cf21c4927c63a0fc350..d45e45a9e180e2eee0b457aecfc906c57a024323 100644 (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,
index d1667795cf2310ee716daa638704ad9cba3cd90b..8e4c0552f336deddd2580868043d357e5027e834 100644 (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) => {
index 1b2f6bffb980cf77ea389d504754ac3bc98462d1..0ce7b5b88ece126ebd1d53114f15d16e85c801e4 100644 (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,
                     );
                 }
index 2187e7b88bc59ff6b5eb3778819af51d36b476fa..4ecac7bca2415e06f42b5f3992f1f6b3b0442f8c 100644 (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(),
index 20dfd8eecefa4a21319ddd60c6a8ae5dad4a2202..20d60c942b17aa472be38b30a0d59a382bfd2726 100644 (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!(),
                         };
index dc4d2ce0b0f986b6fa54893a74645cc89b9417b6..fdf24047a12c226f743095e1042175d765201b0e 100644 (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,
index 7e87dc00674c4c3b507c20c0977ccc70df165847..dbaac20722ebda7b9cdd5da0acbc60b9bd1a65f5 100644 (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);
 
index 0a712c1a7b56b541645bab3b2796b240d4c8bb81..123c7be51204735ac7ede405420494d8b074146d 100644 (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));
+
+                    let src_code_index_ptr = *code_idx_tbl.lookup(src_code_index.into());
 
-                    set_code_index(
-                        &mut payload.retraction_info,
+                    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)
         }
index c18eceda1b4c71c6c51447f82398a0676491f802..cfec0bf6b3246e26187a3596d1702612834c3196 100644 (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
index 8dc5291f0d6dfd93a37d8a2c9dbc166806dfac02..66caba46295cae54f269fb4a218943db48f9a2f0 100644 (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 CodeIndex {
-    #[inline]
-    pub(crate) fn new(ptr: IndexPtr, arena: &mut Arena) -> Self {
-        unsafe { CodeIndex(arena.code_index_tbl.build_with(ptr)) }
-    }
-
+impl Into<CodeIndexOffset> for CodeIndex {
     #[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,
-        }
+    fn into(self) -> CodeIndexOffset {
+        self.0
     }
+}
 
+impl Into<CodeIndexOffset> for &'_ CodeIndex {
     #[inline(always)]
-    pub(crate) fn get(&self) -> IndexPtr {
-        *self.as_ptr().deref()
+    fn into(self) -> CodeIndexOffset {
+        self.0
     }
+}
 
-    #[inline(always)]
-    pub(crate) fn set(&mut self, value: IndexPtr) {
-        self.as_ptr().set(value);
+impl CodeIndex {
+    #[inline]
+    pub(crate) fn new(ptr: IndexPtr, code_index_tbl: &mut CodeIndexTable) -> Self {
+        CodeIndex(code_index_tbl.build_with(ptr))
     }
 
     #[inline(always)]
-    pub(crate) fn get_tag(self) -> IndexPtrTag {
-        self.get().tag()
+    pub(crate) fn default(code_index_tbl: &mut CodeIndexTable) -> Self {
+        CodeIndex::new(IndexPtr::undefined(), code_index_tbl)
     }
 
     #[inline(always)]
-    pub(crate) fn replace(&mut self, value: IndexPtr) -> IndexPtr {
-        self.as_ptr().replace(value)
+    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 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)
     }
 }
 
index e323648316e051b110c15687cfd5a2b4defff714..fac5d7b6aa293e2a4d144341c023769231e05207 100644 (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;
index b72b18d2bafdf19cf2c315e9fb046eb70bdde47d..385d9a4e65cddf0526d98a072cce6b4d1fa57e84 100644 (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)
index a372e0af977921401a9054e0389aab0c40f0beb8..b7201b716a5f7f2a3991ced14903a83b94da3c4f 100644 (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,
index 4c9873732a104f5899039a237ccbd683bfe529bb..fb336248643a880c484cd4083e1e56b9d5771475 100644 (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;
+
+                        let target_code_index = target_code_dir.entry(key).or_insert_with(|| {
+                            CodeIndex::new(IndexPtr::undefined(), code_index_tbl)
+                        });
 
-                        target_code_index.set(src_code_index.get());
+                        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)
         });
index 9ee332ed1d4db656e8093764fc11caf5dfdeb731..3a0434021b0186035c2243f6d56c2d5559f67882 100644 (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();
index dc07cb7867841e1121ae71cecdc1683477fc046f..94728dcef3704bc6ddc042fdcb8de11d72515771 100644 (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()))
             }
index fdc996a0e41e8c96a0138d6669aba0117add58e8..6d3bc3ada96d92bbf8f4847f3be32ae001730f44 100644 (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);
                     }
index 29e3369f8afebe46e2b956367a609aeeb8203fd8..e301832bcdee6baabcf0fb2bba01fc339d09f319 100644 (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)]
index 7b47b96ffff00d57a19fdc31681a15978224ed74..a384cb84962e30d853f6a33dad36813dea1a721c 100644 (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;
+#[derive(Debug)]
+pub struct OffsetTableImpl<T: RawBlockTraits>(InnerOffsetTableImpl<T>);
 
-    fn global_table() -> &'static RwLock<Weak<Self>>;
+impl<T: RawBlockTraits> OffsetTableImpl<T> {
+    #[inline(always)]
+    pub fn new() -> Self {
+        Self(InnerOffsetTableImpl::Serial(SerialOffsetTable::new()))
+    }
 }
 
-impl OffsetTable for F64Table {
-    type Offset = F64Offset;
-    type Stored = OrderedFloat<f64>;
+impl<T: RawBlockTraits> Default for OffsetTableImpl<T> {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[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 global_table() -> &'static RwLock<Weak<Self>> {
-        static GLOBAL_ATOM_TABLE: RwLock<Weak<F64Table>> = RwLock::new(Weak::new());
-        &GLOBAL_ATOM_TABLE
+    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)))
+            },
+        }
     }
 }
 
-impl OffsetTable for CodeIndexTable {
+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;
-    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
+    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: 'static> OffsetTableImpl<T>
-where
-    OffsetTableImpl<T>: OffsetTable<Stored = T>,
-{
+impl<T: RawBlockTraits> SerialOffsetTable<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
+    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 {
-                let table = Arc::new(Self {
-                    block: Arcu::new(RawBlock::new(), GlobalEpochCounterPool),
-                    update: Mutex::new(()),
-                });
-                *guard = Arc::downgrade(&table);
-                table
+                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,127 +274,177 @@ 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 fmt::Display for CodeIndexOffset {
+impl<T: fmt::Display + RawBlockTraits> fmt::Display for TablePtr<'_, T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "CodeIndexOffset({})", self.0)
+        write!(f, "{}", self as &T)
     }
 }
 
-impl CodeIndexPtr {
+impl<T: RawBlockTraits> Deref for TablePtr<'_, T> {
+    type Target = T;
+
     #[inline]
-    pub fn set(&self, val: IndexPtr) {
-        unsafe { *self.0.get() = val };
+    fn deref(&self) -> &Self::Target {
+        match &self.0 {
+            InnerTablePtr::Concurrent(rcu_ref) => rcu_ref,
+            InnerTablePtr::Serial(ref_mut) => ref_mut,
+        }
     }
+}
 
-    #[inline]
-    pub fn replace(&self, val: IndexPtr) -> IndexPtr {
-        unsafe { self.0.get().replace(val) }
+impl fmt::Display for CodeIndexOffset {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "CodeIndexOffset({})", self.0)
     }
 }
 
 impl F64Offset {
     #[inline(always)]
-    pub fn from_ptr(ptr: F64Ptr) -> Self {
-        ptr.as_offset()
+    pub fn to_u64(self) -> u64 {
+        self.0 as u64
     }
+}
 
-    #[inline(always)]
-    pub fn as_ptr(self) -> F64Ptr {
-        F64Ptr::from_offset(self)
+impl fmt::Display for F64Offset {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "F64Offset({})", self.0)
     }
+}
 
-    #[inline(always)]
-    pub fn to_u64(self) -> u64 {
-        self.0 as u64
-    }
+#[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 PartialEq for F64Offset {
-    #[inline(always)]
-    fn eq(&self, other: &F64Offset) -> bool {
-        self.as_ptr() == other.as_ptr()
+impl<T: PartialEq + RawBlockTraits> PartialEq for TablePtrMut<'_, T> {
+    fn eq(&self, other: &TablePtrMut<'_, T>) -> bool {
+        self.deref() == other.deref()
     }
 }
 
-impl Eq for F64Offset {}
+impl<T: Eq + RawBlockTraits> Eq for TablePtrMut<'_, T> {}
 
-impl PartialOrd for F64Offset {
-    #[inline(always)]
+impl<T: PartialOrd + Ord + RawBlockTraits> PartialOrd for TablePtrMut<'_, T> {
     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
         Some(self.cmp(other))
     }
 }
 
-impl Ord for F64Offset {
-    #[inline(always)]
+impl<T: Ord + RawBlockTraits> Ord for TablePtrMut<'_, T> {
     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
-        self.as_ptr().cmp(&other.as_ptr())
+        (**self).cmp(&**other)
     }
 }
 
-impl Hash for F64Offset {
+impl<T: Hash + RawBlockTraits> Hash for TablePtrMut<'_, T> {
     #[inline(always)]
     fn hash<H: Hasher>(&self, hasher: &mut H) {
-        self.as_ptr().hash(hasher)
+        (self as &T).hash(hasher)
     }
 }
 
-impl fmt::Display for F64Offset {
+impl<T: fmt::Display + RawBlockTraits> fmt::Display for TablePtrMut<'_, T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "F64Offset({})", self.0)
+        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),
+        }
     }
 }
index d67d97ced34af6ef22dd147d9978f927348a9ff4..4fc10e054039838e2093ea5515f3c39a5740105c 100644 (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();
         }
 
index a1b8cb4a4e63410e21bd6dd07987558afece918e..6584dd32b9c353e87b79bd2b3014635df569b1f8 100644 (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),
                     )))
                 }
             },
index 10702109ca31d45adb739bdb180c682ceef3327f..b989738d17bd5b50151577e56c6b8af815922892 100644 (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))
             }
index b47659309c2879b108709392122629c368693d1f..60b3b13235055fff46c6f5cbd1f6a4444dc1b734 100644 (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)]