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! {
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) => {{
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))
}};
}
#[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 {}
#[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!() }
);
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
#[derive(Debug)]
pub(crate) struct ArithmeticEvaluator<'a> {
marker: &'a mut DebrayAllocator,
+ f64_tbl: &'a F64Table,
interm: Vec<ArithmeticTerm>,
interm_c: usize,
}
}
}
-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)),
}
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,
}
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();
}
}
-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,
}
)
}
- (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))
use crate::indexing::*;
use crate::instructions::*;
use crate::iterators::*;
+use crate::offset_table::F64Table;
use crate::parser::ast::*;
use crate::targets::*;
use crate::types::*;
}
#[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,
}
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);
}
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) {}
}
}
-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(),
}
}
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();
}
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);
}
},
InlinedClauseType::IsFloat(..) => match terms[0] {
- Term::Literal(_, Literal::Float(_)) => {
+ Term::Literal(_, Literal::F64Offset(_)) => {
instr!("$succeed")
}
Term::Var(ref vr, ref name) => {
}
},
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(_)) => {
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)
}
Term::Literal(
_,
c @ Literal::Integer(_)
- | c @ Literal::Float(_)
+ | c @ Literal::F64Offset(_)
| c @ Literal::Rational(_)
| c @ Literal::Fixnum(_),
) => {
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;
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),
}
}
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::*;
#[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
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>,
}
}
- 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,
HCPrinter {
outputter: output,
iter: stackful_preorder_iter(heap, stack, term_loc),
+ arena,
op_dir,
state_stack: vec![],
toplevel_spec: None,
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 {
|| 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),
}
}
- 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);
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,
});
}
}
- (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);
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
+ &wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
3,
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
+ &wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
5,
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
+ &wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
0,
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,
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
+ &wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
0,
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
+ &wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
0,
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,
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,
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
+ &wam.machine_st.arena,
&wam.op_dir,
PrinterOutputter::new(),
2,
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,
&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;
(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) => {
}
}
-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
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 {
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)?;
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 {
);
}
+ 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(),
);
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(
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();
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)
}
}
}
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
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 => {
)
};
- 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,
);
}
}
}
};
- 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,
)
}
}
};
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,
);
}
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(),
}
(HeapCellValueTag::PStrLoc |
HeapCellValueTag::Lis) => {
- // HeapCellValueTag::CStr) => {
l
}
(HeapCellValueTag::Fixnum |
HeapCellValueTag::CutPoint |
- // HeapCellValueTag::Char |
- HeapCellValueTag::F64) => {
+ HeapCellValueTag::F64Offset) => {
c
}
(HeapCellValueTag::Atom, (_name, arity)) => {
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);
.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);
.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;
}
.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;
}
.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;
}
.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;
}
.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;
}
.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;
}
.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;
}
.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;
}
}
}
}
- &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();
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();
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();
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!(),
};
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!(),
};
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!(),
};
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!(),
};
use crate::atom_table::*;
-use crate::forms::*;
use crate::functor_macro::*;
+use crate::machine::{ArenaHeaderTag, Fixnum, Integer};
use crate::types::*;
use std::alloc;
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)
}
}
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()
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,
},
}
}
- (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())),
}
}
(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 == "[]" {
.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);
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>>(
}
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 {
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(
.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(
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(
.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),
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),
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));
+ }
}
_ => {}
}
.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));
}
}
}
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,
);
.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,
);
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 => {
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 => {
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
.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)
}
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
.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)
}
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);
}
}
}
}
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) => {
* 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(),
);
}
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) => {
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;
}
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)
.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 {
.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;
.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
use crate::parser::ast::*;
-use crate::arena::*;
use crate::atom_table::*;
use crate::forms::*;
use crate::machine::loader::*;
use std::cmp::Ordering;
use std::collections::BTreeSet;
-use std::ops::Deref;
use crate::types::*;
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")]
impl From<CodeIndex> for HeapCellValue {
#[inline(always)]
fn from(idx: CodeIndex) -> HeapCellValue {
- HeapCellValue::from(idx.as_ptr())
+ HeapCellValue::from(idx.0)
}
}
}
}
-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)
}
}
let mut printer = HCPrinter::new(
&mut self.heap,
&mut self.stack,
+ &self.arena,
op_dir,
PrinterOutputter::new(),
0,
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;
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);
}
}
}
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();
}
}
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();
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();
}
)
}
- /*
- (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();
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();
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),
_ => {
(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!()
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);
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)) => {
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)
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!(
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)
}
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()))
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)
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,
#[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));
}
_ => {
}
}
/// 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.
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();
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();
}
}
}
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!();
key,
CodeIndex::new(
IndexPtr::index(p + impls_offset),
- &mut self.machine_st.arena,
+ &mut self.machine_st.arena.code_index_tbl,
),
);
}
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;
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)
}
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)
}
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)
});
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)));
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)) => {
Term::Clause(
cell,
name,
- vec![Term::Literal(Cell::default(), Literal::CodeIndex(idx))],
+ vec![Term::Literal(
+ Cell::default(),
+ Literal::CodeIndexOffset(idx.into()),
+ )],
),
)
}
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();
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();
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;
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()),
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) {
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 {
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;
}
};
- 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);
}
}
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| {
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;
}
}
#[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();
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 {
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();
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(),
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)
}
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);
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);
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();
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))
}
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,
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);
} 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();
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 {
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,
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) {
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();
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()),
_ => {
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
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)
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();
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(),
_ => {
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();
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)
}
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)
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)
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);
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(),
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(),
_ => {
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(),
_ => {
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();
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();
},
};
- 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 =
#[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();
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,
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();
#[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()))
}
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()) => {}
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) => {}
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) => {}
}
}
- 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;
}
_ => {
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);
}
};
}
-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)
}};
}
#[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
}};
#[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)]
#[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)]
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};
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
}
}
-impl RawBlockTraits for CodeIndexTable {
+impl RawBlockTraits for IndexPtr {
#[inline]
fn init_size() -> usize {
CODE_INDEX_TABLE_INIT_SIZE
}
}
-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 {
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
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()
}
}
-#[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);
}
}
-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
}
}
}
}
-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),
+ }
}
}
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;
}
}
-#[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())
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> {
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();
}
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;
more: bool,
}
-#[derive(Debug, PartialEq)]
+#[derive(Debug)]
pub enum Token {
Literal(Literal),
Var(String),
enum Number {
BigInt(TypedArenaPtr<Integer>),
Fixnum(Fixnum),
- Float(F64Ptr),
+ Float(F64Offset),
}
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),
}
}
}
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),
)))
}
},
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;
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))
}
PStrLoc = 0b010011,
// constants.
Cons = 0b0,
- F64 = 0b010101,
+ F64Offset = 0b010101,
Fixnum = 0b011001,
- CodeIndex = 0b011011,
+ CodeIndexOffset = 0b011011,
Atom = 0b011111,
CutPoint = 0b011101,
// trail elements.
PStrLoc = 0b010011,
// constants.
Cons = 0b0,
- F64 = 0b010101,
+ F64Offset = 0b010101,
Fixnum = 0b011001,
- CodeIndex = 0b011011,
+ CodeIndexOffset = 0b011011,
Atom = 0b011111,
CutPoint = 0b011101,
// trail elements.
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())
.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)
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)
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),
}
}
}
(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,
}
}
-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(),
)
}
}
| HeapCellValueTag::Var
| HeapCellValueTag::StackVar
| HeapCellValueTag::AttrVar
- | HeapCellValueTag::PStrLoc // | HeapCellValueTag::PStrOffset
+ | HeapCellValueTag::PStrLoc
)
}
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,
}
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)]