use OffsetTableImpl without synchronization by default
This commit is contained in:
@@ -2698,7 +2698,7 @@ pub fn generate_instructions_rs() -> TokenStream {
|
||||
|
||||
if ident == "Named" {
|
||||
clause_type_from_name_and_arity_arms.push(quote! {
|
||||
(name, arity) => ClauseType::Named(arity, name, CodeIndex::default(arena))
|
||||
(name, arity) => ClauseType::Named(arity, name, CodeIndex::default(&mut arena.code_index_tbl))
|
||||
});
|
||||
|
||||
clause_type_to_instr_arms.push(quote! {
|
||||
|
||||
26
src/arena.rs
26
src/arena.rs
@@ -21,7 +21,6 @@ use std::ops::{Deref, DerefMut};
|
||||
use std::ptr;
|
||||
use std::ptr::addr_of_mut;
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::Arc;
|
||||
|
||||
macro_rules! arena_alloc {
|
||||
($e:expr, $arena:expr) => {{
|
||||
@@ -32,8 +31,7 @@ macro_rules! arena_alloc {
|
||||
|
||||
macro_rules! float_alloc {
|
||||
($e:expr, $arena:expr) => {{
|
||||
let result = $e;
|
||||
unsafe { $arena.f64_tbl.build_with(OrderedFloat(result)).as_ptr() }
|
||||
$arena.f64_tbl.build_with(OrderedFloat($e))
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -458,8 +456,8 @@ impl Drop for UntypedArenaSlab {
|
||||
#[derive(Debug)]
|
||||
pub struct Arena {
|
||||
base: Option<UntypedArenaSlab>,
|
||||
pub f64_tbl: Arc<F64Table>,
|
||||
pub code_index_tbl: Arc<CodeIndexTable>,
|
||||
pub f64_tbl: F64Table,
|
||||
pub code_index_tbl: CodeIndexTable,
|
||||
}
|
||||
|
||||
unsafe impl Send for Arena {}
|
||||
@@ -584,23 +582,27 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn float_ptr_cast() {
|
||||
let wam = MockWAM::new();
|
||||
let mut wam = MockWAM::new();
|
||||
|
||||
let f = 0f64;
|
||||
let fp = float_alloc!(f, wam.machine_st.arena);
|
||||
let mut cell = HeapCellValue::from(fp.clone());
|
||||
let mut cell = HeapCellValue::from(fp);
|
||||
|
||||
assert_eq!(cell.get_tag(), HeapCellValueTag::F64);
|
||||
assert_eq!(cell.get_tag(), HeapCellValueTag::F64Offset);
|
||||
assert!(!cell.get_mark_bit());
|
||||
assert_eq!(fp.deref(), &OrderedFloat(f));
|
||||
assert_eq!(
|
||||
wam.machine_st.arena.f64_tbl.lookup(fp).deref(),
|
||||
&OrderedFloat(f)
|
||||
);
|
||||
|
||||
cell.set_mark_bit(true);
|
||||
|
||||
assert!(cell.get_mark_bit());
|
||||
|
||||
read_heap_cell!(cell,
|
||||
(HeapCellValueTag::F64, ptr) => {
|
||||
assert_eq!(OrderedFloat(*ptr), OrderedFloat(f))
|
||||
(HeapCellValueTag::F64Offset, offset) => {
|
||||
let fp = wam.machine_st.arena.f64_tbl.lookup(offset.into());
|
||||
assert_eq!(*fp, OrderedFloat(0f64))
|
||||
}
|
||||
_ => { unreachable!() }
|
||||
);
|
||||
@@ -825,7 +827,7 @@ mod tests {
|
||||
let float_ptr = float_alloc!(float, wam.machine_st.arena);
|
||||
let cell = HeapCellValue::from(float_ptr);
|
||||
|
||||
assert_eq!(cell.get_tag(), HeapCellValueTag::F64);
|
||||
assert_eq!(cell.get_tag(), HeapCellValueTag::F64Offset);
|
||||
|
||||
// char
|
||||
|
||||
|
||||
@@ -138,6 +138,7 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ArithmeticEvaluator<'a> {
|
||||
marker: &'a mut DebrayAllocator,
|
||||
f64_tbl: &'a F64Table,
|
||||
interm: Vec<ArithmeticTerm>,
|
||||
interm_c: usize,
|
||||
}
|
||||
@@ -156,11 +157,18 @@ impl<'a> ArithmeticTermIter<'a> for &'a Term {
|
||||
}
|
||||
}
|
||||
|
||||
fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: &Literal) -> Result<(), ArithmeticError> {
|
||||
fn push_literal(
|
||||
f64_tbl: &F64Table,
|
||||
interm: &mut Vec<ArithmeticTerm>,
|
||||
c: &Literal,
|
||||
) -> Result<(), ArithmeticError> {
|
||||
match c {
|
||||
Literal::Fixnum(n) => interm.push(ArithmeticTerm::Number(Number::Fixnum(*n))),
|
||||
Literal::Integer(n) => interm.push(ArithmeticTerm::Number(Number::Integer(*n))),
|
||||
Literal::Float(n) => interm.push(ArithmeticTerm::Number(Number::Float(*n.as_ptr()))),
|
||||
&Literal::F64Offset(offset) => {
|
||||
let n = *f64_tbl.lookup(offset);
|
||||
interm.push(ArithmeticTerm::Number(Number::Float(n)));
|
||||
}
|
||||
Literal::Rational(n) => interm.push(ArithmeticTerm::Number(Number::Rational(*n))),
|
||||
Literal::Atom(name) if name == &atom!("e") => interm.push(ArithmeticTerm::Number(
|
||||
Number::Float(OrderedFloat(std::f64::consts::E)),
|
||||
@@ -178,9 +186,14 @@ fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: &Literal) -> Result<(), Ari
|
||||
}
|
||||
|
||||
impl<'a> ArithmeticEvaluator<'a> {
|
||||
pub(crate) fn new(marker: &'a mut DebrayAllocator, target_int: usize) -> Self {
|
||||
pub(crate) fn new(
|
||||
marker: &'a mut DebrayAllocator,
|
||||
f64_tbl: &'a F64Table,
|
||||
target_int: usize,
|
||||
) -> Self {
|
||||
ArithmeticEvaluator {
|
||||
marker,
|
||||
f64_tbl,
|
||||
interm: Vec::new(),
|
||||
interm_c: target_int,
|
||||
}
|
||||
@@ -318,7 +331,7 @@ impl<'a> ArithmeticEvaluator<'a> {
|
||||
|
||||
for term_ref in src.iter()? {
|
||||
match term_ref? {
|
||||
ArithTermRef::Literal(c) => push_literal(&mut self.interm, &c)?,
|
||||
ArithTermRef::Literal(c) => push_literal(self.f64_tbl, &mut self.interm, &c)?,
|
||||
ArithTermRef::Var(lvl, cell, name) => {
|
||||
let var_num = name.to_var_num().unwrap();
|
||||
|
||||
@@ -652,11 +665,11 @@ impl Ord for Number {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<HeapCellValue> for Number {
|
||||
impl TryFrom<(HeapCellValue, &'_ F64Table)> for Number {
|
||||
type Error = ();
|
||||
|
||||
#[inline]
|
||||
fn try_from(value: HeapCellValue) -> Result<Number, Self::Error> {
|
||||
fn try_from((value, f64_tbl): (HeapCellValue, &F64Table)) -> Result<Number, Self::Error> {
|
||||
read_heap_cell!(value,
|
||||
(HeapCellValueTag::Cons, c) => {
|
||||
match_untyped_arena_ptr!(c,
|
||||
@@ -671,8 +684,9 @@ impl TryFrom<HeapCellValue> for Number {
|
||||
}
|
||||
)
|
||||
}
|
||||
(HeapCellValueTag::F64, n) => {
|
||||
Ok(Number::Float(*n))
|
||||
(HeapCellValueTag::F64Offset, offset) => {
|
||||
let n = *f64_tbl.lookup(offset.into());
|
||||
Ok(Number::Float(n))
|
||||
}
|
||||
(HeapCellValueTag::Fixnum | HeapCellValueTag::CutPoint, n) => {
|
||||
Ok(Number::Fixnum(n))
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::forms::*;
|
||||
use crate::indexing::*;
|
||||
use crate::instructions::*;
|
||||
use crate::iterators::*;
|
||||
use crate::offset_table::F64Table;
|
||||
use crate::parser::ast::*;
|
||||
use crate::targets::*;
|
||||
use crate::types::*;
|
||||
@@ -269,9 +270,10 @@ impl CodeGenSettings {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct CodeGenerator {
|
||||
pub(crate) struct CodeGenerator<'f64_tbl> {
|
||||
marker: DebrayAllocator,
|
||||
settings: CodeGenSettings,
|
||||
f64_tbl: &'f64_tbl F64Table,
|
||||
pub(crate) skeleton: PredicateSkeleton,
|
||||
}
|
||||
|
||||
@@ -323,7 +325,7 @@ trait AddToFreeList<'a, Target: CompilationTarget<'a>> {
|
||||
fn add_subterm_to_free_list(&mut self, term: &Term);
|
||||
}
|
||||
|
||||
impl<'a> AddToFreeList<'a, FactInstruction> for CodeGenerator {
|
||||
impl<'a> AddToFreeList<'a, FactInstruction> for CodeGenerator<'_> {
|
||||
fn add_term_to_free_list(&mut self, r: RegType) {
|
||||
self.marker.add_reg_to_free_list(r);
|
||||
}
|
||||
@@ -331,7 +333,7 @@ impl<'a> AddToFreeList<'a, FactInstruction> for CodeGenerator {
|
||||
fn add_subterm_to_free_list(&mut self, _term: &Term) {}
|
||||
}
|
||||
|
||||
impl<'a> AddToFreeList<'a, QueryInstruction> for CodeGenerator {
|
||||
impl<'a> AddToFreeList<'a, QueryInstruction> for CodeGenerator<'_> {
|
||||
#[inline(always)]
|
||||
fn add_term_to_free_list(&mut self, _r: RegType) {}
|
||||
|
||||
@@ -353,11 +355,12 @@ fn structure_cell(term: &Term) -> Option<&Cell<RegType>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl CodeGenerator {
|
||||
pub(crate) fn new(settings: CodeGenSettings) -> Self {
|
||||
impl<'f64_tbl> CodeGenerator<'f64_tbl> {
|
||||
pub(crate) fn new(f64_tbl: &'f64_tbl F64Table, settings: CodeGenSettings) -> Self {
|
||||
CodeGenerator {
|
||||
marker: DebrayAllocator::new(),
|
||||
settings,
|
||||
f64_tbl,
|
||||
skeleton: PredicateSkeleton::new(),
|
||||
}
|
||||
}
|
||||
@@ -427,7 +430,7 @@ impl CodeGenerator {
|
||||
where
|
||||
Target: crate::targets::CompilationTarget<'a>,
|
||||
Iter: Iterator<Item = TermRef<'a>>,
|
||||
CodeGenerator: AddToFreeList<'a, Target>,
|
||||
CodeGenerator<'f64_tbl>: AddToFreeList<'a, Target>,
|
||||
{
|
||||
let mut target = CodeDeque::new();
|
||||
|
||||
@@ -443,7 +446,7 @@ impl CodeGenerator {
|
||||
}
|
||||
TermRef::Clause(lvl, cell, name, terms) => {
|
||||
let terms_range =
|
||||
if let Some(subterm @ Term::Literal(_, Literal::CodeIndex(_))) =
|
||||
if let Some(subterm @ Term::Literal(_, Literal::CodeIndexOffset(_))) =
|
||||
terms.last()
|
||||
{
|
||||
self.subterm_to_instr::<Target>(subterm, context, &mut target);
|
||||
@@ -666,7 +669,7 @@ impl CodeGenerator {
|
||||
}
|
||||
},
|
||||
InlinedClauseType::IsFloat(..) => match terms[0] {
|
||||
Term::Literal(_, Literal::Float(_)) => {
|
||||
Term::Literal(_, Literal::F64Offset(_)) => {
|
||||
instr!("$succeed")
|
||||
}
|
||||
Term::Var(ref vr, ref name) => {
|
||||
@@ -687,7 +690,7 @@ impl CodeGenerator {
|
||||
}
|
||||
},
|
||||
InlinedClauseType::IsNumber(..) => match terms[0] {
|
||||
Term::Literal(_, Literal::Float(_))
|
||||
Term::Literal(_, Literal::F64Offset(_))
|
||||
| Term::Literal(_, Literal::Rational(_))
|
||||
| Term::Literal(_, Literal::Integer(_))
|
||||
| Term::Literal(_, Literal::Fixnum(_)) => {
|
||||
@@ -791,7 +794,7 @@ impl CodeGenerator {
|
||||
term_loc: GenContext,
|
||||
arg: usize,
|
||||
) -> Result<ArithCont, ArithmeticError> {
|
||||
let mut evaluator = ArithmeticEvaluator::new(&mut self.marker, target_int);
|
||||
let mut evaluator = ArithmeticEvaluator::new(&mut self.marker, self.f64_tbl, target_int);
|
||||
evaluator.compile_is(term, term_loc, arg)
|
||||
}
|
||||
|
||||
@@ -861,7 +864,7 @@ impl CodeGenerator {
|
||||
Term::Literal(
|
||||
_,
|
||||
c @ Literal::Integer(_)
|
||||
| c @ Literal::Float(_)
|
||||
| c @ Literal::F64Offset(_)
|
||||
| c @ Literal::Rational(_)
|
||||
| c @ Literal::Fixnum(_),
|
||||
) => {
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::machine::disjuncts::VarData;
|
||||
use crate::machine::loader::PredicateQueue;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::offset_table::OffsetTable;
|
||||
use crate::parser::ast::*;
|
||||
use crate::parser::dashu::{Integer, Rational};
|
||||
use crate::parser::parser::CompositeOpDesc;
|
||||
@@ -742,7 +743,7 @@ impl ArenaFrom<Number> for HeapCellValue {
|
||||
match value {
|
||||
Number::Fixnum(n) => fixnum_as_cell!(n),
|
||||
Number::Integer(n) => typed_arena_ptr_as_cell!(n),
|
||||
Number::Float(OrderedFloat(n)) => HeapCellValue::from(float_alloc!(n, arena)),
|
||||
Number::Float(n) => HeapCellValue::from(arena.f64_tbl.build_with(n)),
|
||||
Number::Rational(n) => typed_arena_ptr_as_cell!(n),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ use crate::parser::dashu::{ibig, Integer, Rational};
|
||||
use crate::forms::*;
|
||||
use crate::heap_iter::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::partial_string::*;
|
||||
use crate::machine::stack::*;
|
||||
use crate::machine::streams::*;
|
||||
@@ -389,17 +388,20 @@ fn is_numbered_var(name: Atom, arity: usize) -> bool {
|
||||
#[inline]
|
||||
fn negated_op_needs_bracketing(
|
||||
iter: &StackfulPreOrderHeapIter<ListElider>,
|
||||
f64_tbl: &F64Table,
|
||||
op_dir: &OpDir,
|
||||
op: &Option<DirectedOp>,
|
||||
) -> bool {
|
||||
if let Some(ref op) = op {
|
||||
op.is_negative_sign()
|
||||
&& iter.leftmost_leaf_has_property(op_dir, |addr| match Number::try_from(addr) {
|
||||
&& iter.leftmost_leaf_has_property(op_dir, |addr| {
|
||||
match Number::try_from((addr, f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => n.get_num() > 0,
|
||||
Ok(Number::Float(OrderedFloat(f))) => f > 0f64,
|
||||
Ok(Number::Integer(n)) => n.is_positive(),
|
||||
Ok(Number::Rational(n)) => n.is_positive(),
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
false
|
||||
@@ -473,6 +475,7 @@ pub fn fmt_float(mut fl: f64) -> String {
|
||||
pub struct HCPrinter<'a, Outputter> {
|
||||
outputter: Outputter,
|
||||
iter: StackfulPreOrderHeapIter<'a, ListElider>,
|
||||
arena: &'a Arena,
|
||||
op_dir: &'a OpDir,
|
||||
state_stack: Vec<TokenOrRedirect>,
|
||||
toplevel_spec: Option<DirectedOp>,
|
||||
@@ -530,19 +533,39 @@ pub(crate) fn numbervar(offset: &Integer, addr: HeapCellValue) -> Option<String>
|
||||
}
|
||||
}
|
||||
|
||||
match Number::try_from(addr) {
|
||||
Ok(Number::Fixnum(n)) if n.get_num() >= 0 => {
|
||||
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
|
||||
}
|
||||
)
|
||||
}
|
||||
(HeapCellValueTag::Fixnum, n) => {
|
||||
if n.get_num() >= 0 {
|
||||
Some(numbervar(offset + Integer::from(n.get_num())))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
Ok(Number::Integer(n)) if !n.is_negative() => Some(numbervar(Integer::from(offset + &*n))),
|
||||
_ => None,
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
pub fn new(
|
||||
heap: &'a mut Heap,
|
||||
stack: &'a mut Stack,
|
||||
arena: &'a Arena,
|
||||
op_dir: &'a OpDir,
|
||||
output: Outputter,
|
||||
term_loc: usize,
|
||||
@@ -550,6 +573,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
HCPrinter {
|
||||
outputter: output,
|
||||
iter: stackful_preorder_iter(heap, stack, term_loc),
|
||||
arena,
|
||||
op_dir,
|
||||
state_stack: vec![],
|
||||
toplevel_spec: None,
|
||||
@@ -1280,12 +1304,14 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
let at_cdr = self.outputter.ends_with("|");
|
||||
|
||||
if self.double_quotes && !self.ignore_ops && !is_cyclic {
|
||||
if end_cell.is_string_terminator(self.iter.heap) {
|
||||
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 {
|
||||
self.at_cdr(",");
|
||||
@@ -1426,7 +1452,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|| if let Some(ref op) = op {
|
||||
if self.numbervars && arity == 1 && name == atom!("$VAR") {
|
||||
!self.iter.immediate_leaf_has_property(|addr| {
|
||||
match Number::try_from(addr) {
|
||||
match Number::try_from((addr, &self.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(n)) => (*n).sign() == Sign::Positive,
|
||||
Ok(Number::Fixnum(n)) => n.get_num() >= 0,
|
||||
Ok(Number::Float(f)) => f >= OrderedFloat(0f64),
|
||||
@@ -1511,28 +1537,29 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_index_ptr(&mut self, idx: CodeIndex, max_depth: usize) {
|
||||
fn print_index_ptr(&mut self, idx: CodeIndexOffset, max_depth: usize) {
|
||||
if self.format_struct(max_depth, 1, atom!("$index_ptr")) {
|
||||
let atom = self.state_stack.pop().unwrap();
|
||||
|
||||
self.state_stack.pop();
|
||||
self.state_stack.pop();
|
||||
|
||||
let idx_ptr = idx.as_ptr();
|
||||
let idx_ptr = self.arena.code_index_tbl.lookup(idx);
|
||||
|
||||
let offset = if idx_ptr.is_undefined() || idx_ptr.is_dynamic_undefined() {
|
||||
TokenOrRedirect::Atom(atom!("undefined"))
|
||||
} else {
|
||||
let idx_ptr_p = idx_ptr.p() as i64;
|
||||
|
||||
if let Ok(n) = Fixnum::build_with_checked(idx_ptr_p) {
|
||||
TokenOrRedirect::NumberFocus(
|
||||
max_depth,
|
||||
NumberFocus::Unfocused(Number::Fixnum(
|
||||
/* FIXME this is not safe */
|
||||
unsafe { Fixnum::build_with_unchecked(idx_ptr_p) },
|
||||
)),
|
||||
NumberFocus::Unfocused(Number::Fixnum(n)),
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
TokenOrRedirect::Atom(atom!("out_of_bounds_idx_ptr"))
|
||||
}
|
||||
};
|
||||
|
||||
self.state_stack.push(offset);
|
||||
@@ -1612,7 +1639,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
is_functor_redirect: bool,
|
||||
mut max_depth: usize,
|
||||
) {
|
||||
let negated_operand = negated_op_needs_bracketing(&self.iter, self.op_dir, &op);
|
||||
let negated_operand =
|
||||
negated_op_needs_bracketing(&self.iter, &self.arena.f64_tbl, self.op_dir, &op);
|
||||
|
||||
let addr = match self.check_for_seen(&mut max_depth) {
|
||||
Some(addr) => addr,
|
||||
@@ -1714,14 +1742,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
});
|
||||
}
|
||||
}
|
||||
(HeapCellValueTag::CodeIndex, idx) => {
|
||||
(HeapCellValueTag::CodeIndexOffset, idx) => {
|
||||
self.print_index_ptr(idx, self.max_depth);
|
||||
}
|
||||
(HeapCellValueTag::Fixnum | HeapCellValueTag::CutPoint, n) => {
|
||||
self.print_number(max_depth, NumberFocus::Unfocused(Number::Fixnum(n)), &op);
|
||||
}
|
||||
(HeapCellValueTag::F64, f) => {
|
||||
self.print_number(max_depth, NumberFocus::Unfocused(Number::Float(*f)), &op);
|
||||
(HeapCellValueTag::F64Offset, offset) => {
|
||||
let f = *self.arena.f64_tbl.lookup(offset.into());
|
||||
self.print_number(max_depth, NumberFocus::Unfocused(Number::Float(f)), &op);
|
||||
}
|
||||
(HeapCellValueTag::PStrLoc) => {
|
||||
self.print_list_like(max_depth);
|
||||
@@ -1885,6 +1914,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.machine_st.arena,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
3,
|
||||
@@ -1917,6 +1947,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.machine_st.arena,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
5,
|
||||
@@ -1944,6 +1975,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.machine_st.arena,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
0,
|
||||
@@ -1956,6 +1988,7 @@ mod tests {
|
||||
let mut printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.machine_st.arena,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
0,
|
||||
@@ -1999,6 +2032,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.machine_st.arena,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
0,
|
||||
@@ -2017,6 +2051,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.machine_st.arena,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
0,
|
||||
@@ -2033,6 +2068,7 @@ mod tests {
|
||||
let mut printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.machine_st.arena,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
0,
|
||||
@@ -2069,6 +2105,7 @@ mod tests {
|
||||
let mut printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.machine_st.arena,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
0,
|
||||
@@ -2094,6 +2131,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.machine_st.arena,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
2,
|
||||
@@ -2123,6 +2161,7 @@ mod tests {
|
||||
let mut printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.machine_st.arena,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
2,
|
||||
|
||||
@@ -1124,7 +1124,7 @@ impl MachineState {
|
||||
&ArithmeticTerm::Reg(r) => {
|
||||
let value = self.store(self.deref(self[r]));
|
||||
|
||||
match Number::try_from(value) {
|
||||
match Number::try_from((value, &self.arena.f64_tbl)) {
|
||||
Ok(n) => Ok(n),
|
||||
Err(_) => {
|
||||
self.heap[0] = value;
|
||||
@@ -1388,7 +1388,8 @@ impl MachineState {
|
||||
(HeapCellValueTag::Fixnum, n) => {
|
||||
self.interms.push(Number::Fixnum(n));
|
||||
}
|
||||
(HeapCellValueTag::F64, fl) => {
|
||||
(HeapCellValueTag::F64Offset, offset) => {
|
||||
let fl = self.arena.f64_tbl.lookup(offset);
|
||||
self.interms.push(Number::Float(*fl));
|
||||
}
|
||||
(HeapCellValueTag::Cons, ptr) => {
|
||||
|
||||
@@ -700,31 +700,25 @@ fn remove_non_leading_clause(
|
||||
}
|
||||
}
|
||||
|
||||
fn finalize_retract(
|
||||
fn finalize_retract<'a, LS: LoadState<'a>>(
|
||||
payload: &mut <LS as LoadState<'a>>::LoaderFieldType,
|
||||
key: PredicateKey,
|
||||
compilation_target: CompilationTarget,
|
||||
skeleton: &mut PredicateSkeleton,
|
||||
code_index: CodeIndex,
|
||||
target_pos: usize,
|
||||
index_ptr_opt: Option<IndexPtr>,
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) -> usize {
|
||||
let clause_clause_loc = delete_from_skeleton(
|
||||
compilation_target,
|
||||
key,
|
||||
skeleton,
|
||||
target_pos,
|
||||
retraction_info,
|
||||
&mut payload.retraction_info,
|
||||
);
|
||||
|
||||
if let Some(index_ptr) = index_ptr_opt {
|
||||
set_code_index(
|
||||
retraction_info,
|
||||
&compilation_target,
|
||||
key,
|
||||
code_index,
|
||||
index_ptr,
|
||||
);
|
||||
set_code_index::<LS>(payload, &compilation_target, key, code_index, index_ptr);
|
||||
}
|
||||
|
||||
clause_clause_loc
|
||||
@@ -1239,7 +1233,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
let mut preprocessor = Preprocessor::new(settings);
|
||||
let clause = preprocessor.try_term_to_tl(self, term)?;
|
||||
|
||||
let mut cg = CodeGenerator::new(settings);
|
||||
let f64_tbl = &LS::machine_st(&mut self.payload).arena.f64_tbl;
|
||||
|
||||
let mut cg = CodeGenerator::new(f64_tbl, settings);
|
||||
let clause_code = cg.compile_predicate(vec![clause])?;
|
||||
|
||||
Ok(StandaloneCompileResult {
|
||||
@@ -1254,7 +1250,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
mut predicates: PredicateQueue,
|
||||
settings: CodeGenSettings,
|
||||
) -> Result<CodeIndex, SessionError> {
|
||||
let code_index = self.get_or_insert_code_index(key, predicates.compilation_target);
|
||||
let code_idx = self.get_or_insert_code_index(key, predicates.compilation_target);
|
||||
|
||||
LS::err_on_builtin_overwrite(self, key)?;
|
||||
|
||||
@@ -1268,7 +1264,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
clauses.push(preprocessor.try_term_to_tl(self, term)?);
|
||||
}
|
||||
|
||||
let mut cg = CodeGenerator::new(settings);
|
||||
let f64_tbl = &LS::machine_st(&mut self.payload).arena.f64_tbl;
|
||||
|
||||
let mut cg = CodeGenerator::new(f64_tbl, settings);
|
||||
let mut code = cg.compile_predicate(clauses)?;
|
||||
|
||||
if settings.is_extensible {
|
||||
@@ -1327,9 +1325,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
);
|
||||
}
|
||||
|
||||
let index_ptr = LS::machine_st(&mut self.payload)
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup(code_idx.into());
|
||||
|
||||
print_overwrite_warning(
|
||||
&predicates.compilation_target,
|
||||
code_index.get(),
|
||||
*index_ptr,
|
||||
key,
|
||||
settings.is_dynamic(),
|
||||
);
|
||||
@@ -1340,16 +1343,16 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
IndexPtr::index(code_ptr)
|
||||
};
|
||||
|
||||
set_code_index(
|
||||
&mut self.payload.retraction_info,
|
||||
set_code_index::<LS>(
|
||||
&mut self.payload,
|
||||
&predicates.compilation_target,
|
||||
key,
|
||||
code_index,
|
||||
code_idx,
|
||||
index_ptr,
|
||||
);
|
||||
|
||||
self.wam_prelude.code.extend(code);
|
||||
Ok(code_index)
|
||||
Ok(code_idx)
|
||||
}
|
||||
|
||||
fn extend_local_predicate_skeleton(
|
||||
@@ -1551,19 +1554,19 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
self.push_back_to_local_predicate_skeleton(&compilation_target, &key, code_len);
|
||||
|
||||
let code_index = self.get_or_insert_code_index(key, compilation_target);
|
||||
let code_idx = self.get_or_insert_code_index(key, compilation_target);
|
||||
|
||||
if let Some(new_code_ptr) = result {
|
||||
set_code_index(
|
||||
&mut self.payload.retraction_info,
|
||||
set_code_index::<LS>(
|
||||
&mut self.payload,
|
||||
&compilation_target,
|
||||
key,
|
||||
code_index,
|
||||
code_idx,
|
||||
new_code_ptr,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(code_index)
|
||||
Ok(code_idx)
|
||||
}
|
||||
AppendOrPrepend::Prepend => {
|
||||
let clause_index_info = standalone_skeleton.clauses.pop_back().unwrap();
|
||||
@@ -1593,17 +1596,17 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
self.push_front_to_local_predicate_skeleton(&compilation_target, &key, code_len);
|
||||
|
||||
let code_index = self.get_or_insert_code_index(key, compilation_target);
|
||||
let code_idx = self.get_or_insert_code_index(key, compilation_target);
|
||||
|
||||
set_code_index(
|
||||
&mut self.payload.retraction_info,
|
||||
set_code_index::<LS>(
|
||||
&mut self.payload,
|
||||
&compilation_target,
|
||||
key,
|
||||
code_index,
|
||||
code_idx,
|
||||
new_code_ptr,
|
||||
);
|
||||
|
||||
Ok(code_index)
|
||||
Ok(code_idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1651,7 +1654,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
pub(super) fn retract_clause(&mut self, key: PredicateKey, target_pos: usize) -> usize {
|
||||
let payload_compilation_target = self.payload.compilation_target;
|
||||
let code_index = self.get_or_insert_code_index(key, payload_compilation_target);
|
||||
let code_idx_offset = self.get_or_insert_code_index(key, payload_compilation_target);
|
||||
|
||||
let skeleton = self
|
||||
.wam_prelude
|
||||
@@ -1729,14 +1732,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
None
|
||||
};
|
||||
|
||||
return finalize_retract(
|
||||
return finalize_retract::<LS>(
|
||||
&mut self.payload,
|
||||
key,
|
||||
payload_compilation_target,
|
||||
skeleton,
|
||||
code_index,
|
||||
code_idx_offset,
|
||||
target_pos,
|
||||
index_ptr_opt,
|
||||
&mut self.payload.retraction_info,
|
||||
);
|
||||
}
|
||||
None => {
|
||||
@@ -1758,14 +1761,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
)
|
||||
};
|
||||
|
||||
return finalize_retract(
|
||||
return finalize_retract::<LS>(
|
||||
&mut self.payload,
|
||||
key,
|
||||
payload_compilation_target,
|
||||
skeleton,
|
||||
code_index,
|
||||
code_idx_offset,
|
||||
target_pos,
|
||||
index_ptr_opt,
|
||||
&mut self.payload.retraction_info,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1988,14 +1991,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
};
|
||||
|
||||
finalize_retract(
|
||||
finalize_retract::<LS>(
|
||||
&mut self.payload,
|
||||
key,
|
||||
payload_compilation_target,
|
||||
skeleton,
|
||||
code_index,
|
||||
code_idx_offset,
|
||||
target_pos,
|
||||
index_ptr_opt,
|
||||
&mut self.payload.retraction_info,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2222,18 +2225,23 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
};
|
||||
|
||||
let predicates = self.payload.predicates.take();
|
||||
let code_index = self.compile(key, predicates, settings)?;
|
||||
let offset = self.compile(key, predicates, settings)?;
|
||||
|
||||
if let Some(filename) = self.listing_src_file_name() {
|
||||
if let Some(ref mut module) = self.wam_prelude.indices.modules.get_mut(&filename) {
|
||||
let index_ptr = code_index.get();
|
||||
let code_index = *module.code_dir.entry(key).or_insert(code_index);
|
||||
let code_idx = LS::machine_st(&mut self.payload)
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup_mut(offset.into());
|
||||
|
||||
set_code_index(
|
||||
&mut self.payload.retraction_info,
|
||||
let index_ptr = *code_idx;
|
||||
let offset = *module.code_dir.entry(key).or_insert(offset);
|
||||
|
||||
set_code_index::<LS>(
|
||||
&mut self.payload,
|
||||
&CompilationTarget::Module(filename),
|
||||
key,
|
||||
code_index,
|
||||
offset,
|
||||
index_ptr,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -579,7 +579,7 @@ impl VariableClassifier {
|
||||
mut terms,
|
||||
) if terms.len() == 3 => {
|
||||
if let Some(last_arg) = terms.last() {
|
||||
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
|
||||
if let Term::Literal(_, Literal::CodeIndexOffset(_)) = last_arg {
|
||||
terms.pop();
|
||||
state_stack.push(TraversalState::Term(Term::Clause(
|
||||
Cell::default(),
|
||||
|
||||
@@ -232,13 +232,11 @@ impl MachineState {
|
||||
}
|
||||
(HeapCellValueTag::PStrLoc |
|
||||
HeapCellValueTag::Lis) => {
|
||||
// HeapCellValueTag::CStr) => {
|
||||
l
|
||||
}
|
||||
(HeapCellValueTag::Fixnum |
|
||||
HeapCellValueTag::CutPoint |
|
||||
// HeapCellValueTag::Char |
|
||||
HeapCellValueTag::F64) => {
|
||||
HeapCellValueTag::F64Offset) => {
|
||||
c
|
||||
}
|
||||
(HeapCellValueTag::Atom, (_name, arity)) => {
|
||||
@@ -548,19 +546,33 @@ impl Machine {
|
||||
let p = self.machine_st.p;
|
||||
|
||||
// Find the boundaries of the current predicate
|
||||
self.indices.code_dir.sort_by(|_, a, _, b| a.cmp(b));
|
||||
self.indices.code_dir.sort_by(|_, a, _, b| {
|
||||
let a = *self.machine_st.arena.code_index_tbl.lookup((*a).into());
|
||||
let b = *self.machine_st.arena.code_index_tbl.lookup((*b).into());
|
||||
|
||||
a.cmp(&b)
|
||||
});
|
||||
|
||||
let predicate_idx = self
|
||||
.indices
|
||||
.code_dir
|
||||
.binary_search_by_key(&p, |_, x| x.get().p() as usize)
|
||||
.binary_search_by_key(&p, |_, x| -> usize {
|
||||
self.machine_st.arena.code_index_tbl.lookup((*x).into()).p()
|
||||
as usize
|
||||
})
|
||||
.unwrap_or_else(|x| x - 1);
|
||||
|
||||
let current_pred_start = self
|
||||
.indices
|
||||
.code_dir
|
||||
.get_index(predicate_idx)
|
||||
.map(|x| x.1.as_ptr().p() as usize)
|
||||
.map(|idx| {
|
||||
self.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup((*idx.1).into())
|
||||
.p() as usize
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
debug_assert!(current_pred_start <= p);
|
||||
@@ -569,7 +581,13 @@ impl Machine {
|
||||
.indices
|
||||
.code_dir
|
||||
.get_index(predicate_idx + 1)
|
||||
.map(|x| x.1.as_ptr().p() as usize)
|
||||
.map(|idx| {
|
||||
self.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup((*idx.1).into())
|
||||
.p() as usize
|
||||
})
|
||||
.unwrap_or(self.code.len());
|
||||
|
||||
debug_assert!(current_pred_end >= p);
|
||||
@@ -2343,7 +2361,7 @@ impl Machine {
|
||||
.store(self.machine_st.deref(self.machine_st[r]));
|
||||
|
||||
read_heap_cell!(d,
|
||||
(HeapCellValueTag::Fixnum | HeapCellValueTag::F64 |
|
||||
(HeapCellValueTag::Fixnum | HeapCellValueTag::F64Offset |
|
||||
HeapCellValueTag::Cons) => {
|
||||
self.machine_st.p += 1;
|
||||
}
|
||||
@@ -2375,7 +2393,7 @@ impl Machine {
|
||||
.store(self.machine_st.deref(self.machine_st[r]));
|
||||
|
||||
read_heap_cell!(d,
|
||||
(HeapCellValueTag::Fixnum | HeapCellValueTag::F64 |
|
||||
(HeapCellValueTag::Fixnum | HeapCellValueTag::F64Offset |
|
||||
HeapCellValueTag::Cons) => {
|
||||
self.machine_st.p = self.machine_st.cp;
|
||||
}
|
||||
@@ -2472,7 +2490,7 @@ impl Machine {
|
||||
.machine_st
|
||||
.store(self.machine_st.deref(self.machine_st[r]));
|
||||
|
||||
match Number::try_from(d) {
|
||||
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(_) | Number::Integer(_)) => {
|
||||
self.machine_st.p += 1;
|
||||
}
|
||||
@@ -2493,7 +2511,7 @@ impl Machine {
|
||||
.machine_st
|
||||
.store(self.machine_st.deref(self.machine_st[r]));
|
||||
|
||||
match Number::try_from(d) {
|
||||
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(_) | Number::Integer(_)) => {
|
||||
self.machine_st.p = self.machine_st.cp;
|
||||
}
|
||||
@@ -2514,7 +2532,7 @@ impl Machine {
|
||||
.machine_st
|
||||
.store(self.machine_st.deref(self.machine_st[r]));
|
||||
|
||||
match Number::try_from(d) {
|
||||
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(_) => {
|
||||
self.machine_st.p += 1;
|
||||
}
|
||||
@@ -2528,7 +2546,7 @@ impl Machine {
|
||||
.machine_st
|
||||
.store(self.machine_st.deref(self.machine_st[r]));
|
||||
|
||||
match Number::try_from(d) {
|
||||
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(_) => {
|
||||
self.machine_st.p = self.machine_st.cp;
|
||||
}
|
||||
@@ -2590,7 +2608,7 @@ impl Machine {
|
||||
.machine_st
|
||||
.store(self.machine_st.deref(self.machine_st[r]));
|
||||
|
||||
match Number::try_from(d) {
|
||||
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Float(_)) => {
|
||||
self.machine_st.p += 1;
|
||||
}
|
||||
@@ -2604,7 +2622,7 @@ impl Machine {
|
||||
.machine_st
|
||||
.store(self.machine_st.deref(self.machine_st[r]));
|
||||
|
||||
match Number::try_from(d) {
|
||||
match Number::try_from((d, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Float(_)) => {
|
||||
self.machine_st.p = self.machine_st.cp;
|
||||
}
|
||||
@@ -2677,10 +2695,10 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
}
|
||||
&Instruction::CallNamed(arity, name, ref idx) => {
|
||||
let idx = idx.get();
|
||||
&Instruction::CallNamed(arity, name, idx) => {
|
||||
let idx = self.machine_st.arena.code_index_tbl.lookup(idx.into());
|
||||
|
||||
try_or_throw!(self.machine_st, self.try_call(name, arity, idx));
|
||||
try_or_throw!(self.machine_st, self.try_call(name, arity, *idx));
|
||||
|
||||
if self.machine_st.fail {
|
||||
self.machine_st.backtrack();
|
||||
@@ -2688,10 +2706,10 @@ impl Machine {
|
||||
increment_call_count!(self.machine_st);
|
||||
}
|
||||
}
|
||||
&Instruction::ExecuteNamed(arity, name, ref idx) => {
|
||||
let idx = idx.get();
|
||||
&Instruction::ExecuteNamed(arity, name, idx) => {
|
||||
let idx = self.machine_st.arena.code_index_tbl.lookup(idx.into());
|
||||
|
||||
try_or_throw!(self.machine_st, self.try_execute(name, arity, idx));
|
||||
try_or_throw!(self.machine_st, self.try_execute(name, arity, *idx));
|
||||
|
||||
if self.machine_st.fail {
|
||||
self.machine_st.backtrack();
|
||||
@@ -2699,19 +2717,19 @@ impl Machine {
|
||||
increment_call_count!(self.machine_st);
|
||||
}
|
||||
}
|
||||
&Instruction::DefaultCallNamed(arity, name, ref idx) => {
|
||||
let idx = idx.get();
|
||||
&Instruction::DefaultCallNamed(arity, name, idx) => {
|
||||
let idx = self.machine_st.arena.code_index_tbl.lookup(idx.into());
|
||||
|
||||
try_or_throw!(self.machine_st, self.try_call(name, arity, idx));
|
||||
try_or_throw!(self.machine_st, self.try_call(name, arity, *idx));
|
||||
|
||||
if self.machine_st.fail {
|
||||
self.machine_st.backtrack();
|
||||
}
|
||||
}
|
||||
&Instruction::DefaultExecuteNamed(arity, name, ref idx) => {
|
||||
let idx = idx.get();
|
||||
&Instruction::DefaultExecuteNamed(arity, name, idx) => {
|
||||
let idx = self.machine_st.arena.code_index_tbl.lookup(idx.into());
|
||||
|
||||
try_or_throw!(self.machine_st, self.try_execute(name, arity, idx));
|
||||
try_or_throw!(self.machine_st, self.try_execute(name, arity, *idx));
|
||||
|
||||
if self.machine_st.fail {
|
||||
self.machine_st.backtrack();
|
||||
@@ -5251,7 +5269,7 @@ impl Machine {
|
||||
let l = self.machine_st.registers[3];
|
||||
let l = self.machine_st.store(self.machine_st.deref(l));
|
||||
|
||||
let l = match Number::try_from(l) {
|
||||
let l = match Number::try_from((l, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(l)) => l.get_num() as usize,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@@ -5259,7 +5277,7 @@ impl Machine {
|
||||
let p = self.machine_st.registers[4];
|
||||
let p = self.machine_st.store(self.machine_st.deref(p));
|
||||
|
||||
let p = match Number::try_from(p) {
|
||||
let p = match Number::try_from((p, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(p)) => p.get_num() as usize,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@@ -5297,7 +5315,7 @@ impl Machine {
|
||||
let l = self.machine_st.registers[3];
|
||||
let l = self.machine_st.store(self.machine_st.deref(l));
|
||||
|
||||
let l = match Number::try_from(l) {
|
||||
let l = match Number::try_from((l, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(l)) => l.get_num() as usize,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@@ -5305,7 +5323,7 @@ impl Machine {
|
||||
let p = self.machine_st.registers[4];
|
||||
let p = self.machine_st.store(self.machine_st.deref(p));
|
||||
|
||||
let p = match Number::try_from(p) {
|
||||
let p = match Number::try_from((p, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(p)) => p.get_num() as usize,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::atom_table::*;
|
||||
use crate::forms::*;
|
||||
use crate::functor_macro::*;
|
||||
use crate::machine::{ArenaHeaderTag, Fixnum, Integer};
|
||||
use crate::types::*;
|
||||
|
||||
use std::alloc;
|
||||
@@ -717,7 +717,7 @@ impl Heap {
|
||||
pub(crate) fn slice_to_str(&self, slice_loc: usize, slice_len: usize) -> &str {
|
||||
unsafe {
|
||||
let slice = std::slice::from_raw_parts(self.inner.ptr.add(slice_loc), slice_len);
|
||||
std::str::from_utf8_unchecked(&slice)
|
||||
std::str::from_utf8_unchecked(slice)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -824,7 +824,7 @@ impl Heap {
|
||||
let s = unsafe {
|
||||
let char_ptr = self.inner.ptr.add(byte_idx);
|
||||
let slice = std::slice::from_raw_parts(char_ptr, size_of::<char>());
|
||||
std::str::from_utf8_unchecked(&slice)
|
||||
std::str::from_utf8_unchecked(slice)
|
||||
};
|
||||
|
||||
s.chars().next().unwrap()
|
||||
@@ -1158,14 +1158,24 @@ pub fn sized_iter_to_heap_list<SrcT: Into<HeapCellValue>>(
|
||||
|
||||
pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<usize> {
|
||||
let extract_integer = |s: usize| -> Option<usize> {
|
||||
match Number::try_from(heap[s]) {
|
||||
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
|
||||
Ok(Number::Integer(n)) => {
|
||||
let value: usize = (&*n).try_into().unwrap();
|
||||
Some(value)
|
||||
read_heap_cell!(heap[s],
|
||||
(HeapCellValueTag::Cons, c) => {
|
||||
match_untyped_arena_ptr!(c,
|
||||
(ArenaHeaderTag::Integer, n) => {
|
||||
(&*n).try_into().ok()
|
||||
}
|
||||
_ => None,
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
)
|
||||
}
|
||||
(HeapCellValueTag::Fixnum, n) => {
|
||||
usize::try_from(n.get_num()).ok()
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
)
|
||||
};
|
||||
|
||||
read_heap_cell!(addr,
|
||||
|
||||
@@ -277,14 +277,15 @@ impl Term {
|
||||
},
|
||||
}
|
||||
}
|
||||
(HeapCellValueTag::F64, f) => {
|
||||
term_stack.push(Term::Float((*f).into()));
|
||||
(HeapCellValueTag::F64Offset, offset) => {
|
||||
let f = *machine.machine_st.arena.f64_tbl.lookup(offset);
|
||||
term_stack.push(Term::Float(f.into()));
|
||||
}
|
||||
(HeapCellValueTag::Fixnum, n) => {
|
||||
term_stack.push(Term::Integer(n.into()));
|
||||
}
|
||||
(HeapCellValueTag::Cons, ptr) => {
|
||||
if let Ok(n) = Number::try_from(addr) {
|
||||
if let Ok(n) = Number::try_from((addr, &machine.machine_st.arena.f64_tbl)) {
|
||||
match n {
|
||||
Number::Integer(i) => term_stack.push(Term::Integer((*i).clone())),
|
||||
Number::Rational(r) => term_stack.push(Term::Rational((*r).clone())),
|
||||
@@ -312,31 +313,6 @@ impl Term {
|
||||
}
|
||||
}
|
||||
(HeapCellValueTag::Atom, (name, arity)) => {
|
||||
//let h = iter.focus().value() as usize;
|
||||
//let mut arity = arity;
|
||||
|
||||
// Not sure why/if this is needed.
|
||||
// Might find out with better testing later.
|
||||
/*
|
||||
if iter.heap.len() > h + arity + 1 {
|
||||
let value = iter.heap[h + arity + 1];
|
||||
|
||||
if let Some(idx) = get_structure_index(value) {
|
||||
// in the second condition, arity == 0,
|
||||
// meaning idx cannot pertain to this atom
|
||||
// if it is the direct subterm of a larger
|
||||
// structure.
|
||||
if arity > 0 || !iter.direct_subterm_of_str(h) {
|
||||
term_stack.push(
|
||||
Term::Literal(Cell::default(), Literal::CodeIndex(idx))
|
||||
);
|
||||
|
||||
arity += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if arity == 0 {
|
||||
let atom_name = name.as_str().to_string();
|
||||
if atom_name == "[]" {
|
||||
@@ -621,9 +597,15 @@ impl Machine {
|
||||
.indices
|
||||
.code_dir
|
||||
.get(&(atom!("call"), 1))
|
||||
.expect("couldn't get code index")
|
||||
.local()
|
||||
.unwrap();
|
||||
.cloned()
|
||||
.map(|offset| {
|
||||
self.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup(offset.into())
|
||||
.p() as usize
|
||||
})
|
||||
.expect("couldn't get code index");
|
||||
|
||||
self.machine_st.execute_at_index(1, call_index_p);
|
||||
|
||||
|
||||
@@ -15,35 +15,40 @@ use std::mem;
|
||||
|
||||
pub(super) type ModuleOpExports = Vec<(OpDecl, Option<OpDesc>)>;
|
||||
|
||||
pub(super) fn set_code_index(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
pub(super) fn set_code_index<'a, LS: LoadState<'a>>(
|
||||
payload: &mut <LS as LoadState<'a>>::LoaderFieldType,
|
||||
compilation_target: &CompilationTarget,
|
||||
key: PredicateKey,
|
||||
mut code_index: CodeIndex,
|
||||
code_idx: CodeIndex,
|
||||
code_ptr: IndexPtr,
|
||||
) {
|
||||
let mut code_idx_ptr = LS::machine_st(payload)
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup_mut(code_idx.into());
|
||||
|
||||
let record = match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
if IndexPtrTag::Undefined == code_index.get().tag() {
|
||||
code_index.set(code_ptr);
|
||||
if IndexPtrTag::Undefined == code_idx_ptr.tag() {
|
||||
code_idx_ptr.set(code_ptr);
|
||||
RetractionRecord::AddedUserPredicate(key)
|
||||
} else {
|
||||
let replaced = code_index.replace(code_ptr);
|
||||
let replaced = code_idx_ptr.replace(code_ptr);
|
||||
RetractionRecord::ReplacedUserPredicate(key, replaced)
|
||||
}
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if IndexPtrTag::Undefined == code_index.get().tag() {
|
||||
code_index.set(code_ptr);
|
||||
if IndexPtrTag::Undefined == code_idx_ptr.tag() {
|
||||
code_idx_ptr.set(code_ptr);
|
||||
RetractionRecord::AddedModulePredicate(*module_name, key)
|
||||
} else {
|
||||
let replaced = code_index.replace(code_ptr);
|
||||
let replaced = code_idx_ptr.replace(code_ptr);
|
||||
RetractionRecord::ReplacedModulePredicate(*module_name, key, replaced)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
retraction_info.push_record(record);
|
||||
payload.retraction_info.push_record(record);
|
||||
}
|
||||
|
||||
fn add_op_decl_as_module_export<'a, LS: LoadState<'a>>(
|
||||
@@ -133,21 +138,28 @@ pub(super) fn import_module_exports<'a, LS: LoadState<'a>>(
|
||||
}
|
||||
|
||||
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
|
||||
let arena = &mut LS::machine_st(payload).arena;
|
||||
let code_idx_tbl = &mut LS::machine_st(payload).arena.code_index_tbl;
|
||||
|
||||
let target_code_index = *code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::default(arena));
|
||||
.or_insert_with(|| CodeIndex::default(code_idx_tbl));
|
||||
|
||||
set_code_index(
|
||||
&mut payload.retraction_info,
|
||||
let src_code_index_ptr = *code_idx_tbl.lookup(src_code_index.into());
|
||||
|
||||
set_code_index::<LS>(
|
||||
payload,
|
||||
compilation_target,
|
||||
key,
|
||||
target_code_index,
|
||||
src_code_index.get(),
|
||||
src_code_index_ptr,
|
||||
);
|
||||
|
||||
if src_code_index.as_ptr().is_dynamic_undefined() {
|
||||
if LS::machine_st(payload)
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup(src_code_index.into())
|
||||
.is_dynamic_undefined()
|
||||
{
|
||||
code_dir.insert(key, src_code_index);
|
||||
}
|
||||
} else {
|
||||
@@ -189,19 +201,20 @@ fn import_module_exports_into_module<'a, LS: LoadState<'a>>(
|
||||
meta_predicates.insert(key, meta_specs.clone());
|
||||
}
|
||||
|
||||
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
|
||||
let arena = &mut LS::machine_st(payload).arena;
|
||||
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
|
||||
let code_index_tbl = &mut LS::machine_st(payload).arena.code_index_tbl;
|
||||
|
||||
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
|
||||
let target_code_index = *code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::default(arena));
|
||||
.or_insert_with(|| CodeIndex::default(code_index_tbl));
|
||||
|
||||
set_code_index(
|
||||
&mut payload.retraction_info,
|
||||
set_code_index::<LS>(
|
||||
payload,
|
||||
compilation_target,
|
||||
key,
|
||||
target_code_index,
|
||||
src_code_index.get(),
|
||||
src_code_ptr,
|
||||
);
|
||||
} else {
|
||||
return Err(SessionError::ModuleDoesNotContainExport(
|
||||
@@ -242,21 +255,21 @@ fn import_qualified_module_exports<'a, LS: LoadState<'a>>(
|
||||
.insert(key, meta_specs.clone());
|
||||
}
|
||||
|
||||
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
|
||||
let arena = &mut LS::machine_st(payload).arena;
|
||||
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
|
||||
let code_index_tbl = &mut LS::machine_st(payload).arena.code_index_tbl;
|
||||
|
||||
let target_code_index = *wam_prelude
|
||||
.indices
|
||||
.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
|
||||
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
|
||||
let target_code_index =
|
||||
*wam_prelude.indices.code_dir.entry(key).or_insert_with(|| {
|
||||
CodeIndex::new(IndexPtr::undefined(), code_index_tbl)
|
||||
});
|
||||
|
||||
set_code_index(
|
||||
&mut payload.retraction_info,
|
||||
set_code_index::<LS>(
|
||||
payload,
|
||||
compilation_target,
|
||||
key,
|
||||
target_code_index,
|
||||
src_code_index.get(),
|
||||
src_code_ptr,
|
||||
);
|
||||
} else {
|
||||
return Err(SessionError::ModuleDoesNotContainExport(
|
||||
@@ -303,19 +316,20 @@ fn import_qualified_module_exports_into_module<'a, LS: LoadState<'a>>(
|
||||
meta_predicates.insert(key, meta_specs.clone());
|
||||
}
|
||||
|
||||
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
|
||||
let arena = &mut LS::machine_st(payload).arena;
|
||||
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
|
||||
let code_index_tbl = &mut LS::machine_st(payload).arena.code_index_tbl;
|
||||
|
||||
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
|
||||
let target_code_index = *code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), code_index_tbl));
|
||||
|
||||
set_code_index(
|
||||
&mut payload.retraction_info,
|
||||
set_code_index::<LS>(
|
||||
payload,
|
||||
&payload_compilation_target,
|
||||
key,
|
||||
target_code_index,
|
||||
src_code_index.get(),
|
||||
src_code_ptr,
|
||||
);
|
||||
} else {
|
||||
return Err(SessionError::ModuleDoesNotContainExport(
|
||||
@@ -468,11 +482,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
.indices
|
||||
.get_predicate_skeleton(local_compilation_target, key)
|
||||
{
|
||||
let old_index_ptr = code_index.replace(if global_skeleton.core.is_dynamic {
|
||||
let old_index_ptr = code_index.replace(
|
||||
&mut LS::machine_st(&mut self.payload).arena.code_index_tbl,
|
||||
if global_skeleton.core.is_dynamic {
|
||||
IndexPtr::dynamic_undefined()
|
||||
} else {
|
||||
IndexPtr::undefined()
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
self.payload.retraction_info.push_record(
|
||||
RetractionRecord::ReplacedModulePredicate(module_name, *key, old_index_ptr),
|
||||
@@ -486,8 +503,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !code_index.as_ptr().is_undefined() && !code_index.as_ptr().is_dynamic_undefined() {
|
||||
let old_index_ptr = code_index.replace(IndexPtr::undefined());
|
||||
let code_index_tbl = &mut LS::machine_st(&mut self.payload).arena.code_index_tbl;
|
||||
let code_ptr = code_index_tbl.lookup((*code_index).into());
|
||||
|
||||
if !code_ptr.is_undefined() && !code_ptr.is_dynamic_undefined() {
|
||||
let old_index_ptr = code_index.replace(code_index_tbl, IndexPtr::undefined());
|
||||
|
||||
self.payload.retraction_info.push_record(
|
||||
RetractionRecord::ReplacedModulePredicate(module_name, *key, old_index_ptr),
|
||||
@@ -517,26 +537,35 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
None => return,
|
||||
};
|
||||
|
||||
fn remove_module_exports(
|
||||
fn remove_module_exports<'b, LS: LoadState<'b>>(
|
||||
payload: &mut <LS as LoadState<'b>>::LoaderFieldType,
|
||||
removed_module: &Module,
|
||||
code_dir: &mut CodeDir,
|
||||
op_dir: &mut OpDir,
|
||||
retraction_info: &mut RetractionInfo,
|
||||
predicate_retractor: impl Fn(PredicateKey, IndexPtr) -> RetractionRecord,
|
||||
op_retractor: impl Fn(OpDecl, OpDesc) -> RetractionRecord,
|
||||
) {
|
||||
for export in removed_module.module_decl.exports.iter() {
|
||||
match export {
|
||||
ModuleExport::PredicateKey(ref key) => {
|
||||
match (removed_module.code_dir.get(key), code_dir.get_mut(key)) {
|
||||
(Some(module_code_index), Some(target_code_index))
|
||||
if module_code_index.get() == target_code_index.get() =>
|
||||
{
|
||||
let old_index_ptr =
|
||||
target_code_index.replace(IndexPtr::undefined());
|
||||
retraction_info
|
||||
match (
|
||||
removed_module.code_dir.get(key).cloned(),
|
||||
code_dir.get_mut(key).cloned(),
|
||||
) {
|
||||
(Some(module_code_idx), Some(target_code_idx)) => {
|
||||
let code_index_tbl =
|
||||
&mut LS::machine_st(payload).arena.code_index_tbl;
|
||||
let module_code_ptr = code_index_tbl.lookup(module_code_idx.into());
|
||||
let target_code_ptr = code_index_tbl.lookup(target_code_idx.into());
|
||||
|
||||
if module_code_ptr == target_code_ptr {
|
||||
let old_index_ptr = target_code_idx
|
||||
.replace(code_index_tbl, IndexPtr::undefined());
|
||||
payload
|
||||
.retraction_info
|
||||
.push_record(predicate_retractor(*key, old_index_ptr));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -545,7 +574,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
.swap_remove(&(op_decl.name, op_decl.op_desc.get_spec().fixity()));
|
||||
|
||||
if let Some(op_desc) = op_dir_value_opt {
|
||||
retraction_info.push_record(op_retractor(*op_decl, op_desc));
|
||||
payload
|
||||
.retraction_info
|
||||
.push_record(op_retractor(*op_decl, op_desc));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -554,11 +585,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
match self.payload.compilation_target {
|
||||
CompilationTarget::User => {
|
||||
remove_module_exports(
|
||||
remove_module_exports::<LS>(
|
||||
&mut self.payload,
|
||||
&removed_module,
|
||||
&mut self.wam_prelude.indices.code_dir,
|
||||
&mut self.wam_prelude.indices.op_dir,
|
||||
&mut self.payload.retraction_info,
|
||||
RetractionRecord::ReplacedUserPredicate,
|
||||
RetractionRecord::ReplacedUserOp,
|
||||
);
|
||||
@@ -578,11 +609,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
.modules
|
||||
.get_mut(&target_module_name)
|
||||
{
|
||||
remove_module_exports(
|
||||
remove_module_exports::<LS>(
|
||||
&mut self.payload,
|
||||
&removed_module,
|
||||
&mut module.code_dir,
|
||||
&mut module.op_dir,
|
||||
&mut self.payload.retraction_info,
|
||||
predicate_retractor,
|
||||
op_retractor,
|
||||
);
|
||||
@@ -608,7 +639,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
Some(ref mut module) => *module.code_dir.entry(key).or_insert_with(|| {
|
||||
CodeIndex::new(
|
||||
IndexPtr::undefined(),
|
||||
&mut LS::machine_st(&mut self.payload).arena,
|
||||
&mut LS::machine_st(&mut self.payload).arena.code_index_tbl,
|
||||
)
|
||||
}),
|
||||
None => {
|
||||
@@ -618,7 +649,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
Some(ref mut module) => *module.code_dir.entry(key).or_insert_with(|| {
|
||||
CodeIndex::new(
|
||||
IndexPtr::undefined(),
|
||||
&mut LS::machine_st(&mut self.payload).arena,
|
||||
&mut LS::machine_st(&mut self.payload).arena.code_index_tbl,
|
||||
)
|
||||
}),
|
||||
None => {
|
||||
@@ -634,7 +665,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
key: PredicateKey,
|
||||
compilation_target: CompilationTarget,
|
||||
) -> CodeIndex {
|
||||
let arena = &mut LS::machine_st(&mut self.payload).arena;
|
||||
let code_index_tbl = &mut LS::machine_st(&mut self.payload).arena.code_index_tbl;
|
||||
|
||||
match compilation_target {
|
||||
CompilationTarget::User => *self
|
||||
@@ -642,7 +673,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
.indices
|
||||
.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena)),
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), code_index_tbl)),
|
||||
CompilationTarget::Module(module_name) => {
|
||||
self.get_or_insert_local_code_index(module_name, key)
|
||||
}
|
||||
@@ -654,7 +685,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
module_name: Atom,
|
||||
key: PredicateKey,
|
||||
) -> CodeIndex {
|
||||
let arena = &mut LS::machine_st(&mut self.payload).arena;
|
||||
let code_index_tbl = &mut LS::machine_st(&mut self.payload).arena.code_index_tbl;
|
||||
|
||||
if module_name == atom!("user") {
|
||||
return *self
|
||||
@@ -662,7 +693,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
.indices
|
||||
.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), code_index_tbl));
|
||||
} else {
|
||||
self.get_or_insert_local_code_index(module_name, key)
|
||||
}
|
||||
|
||||
@@ -720,7 +720,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
self.wam_prelude.indices.modules.get_mut(&module_name)
|
||||
{
|
||||
if let Some(code_idx) = module.code_dir.get_mut(&key) {
|
||||
code_idx.set(old_code_idx)
|
||||
let code_index_tbl =
|
||||
&mut LS::machine_st(&mut self.payload).arena.code_index_tbl;
|
||||
code_idx.set(code_index_tbl, old_code_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -741,7 +743,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
RetractionRecord::ReplacedUserPredicate(key, old_code_idx) => {
|
||||
if let Some(code_idx) = self.wam_prelude.indices.code_dir.get_mut(&key) {
|
||||
code_idx.set(old_code_idx)
|
||||
let code_index_tbl =
|
||||
&mut LS::machine_st(&mut self.payload).arena.code_index_tbl;
|
||||
code_idx.set(code_index_tbl, old_code_idx)
|
||||
}
|
||||
}
|
||||
RetractionRecord::AddedIndex(index_key, clause_loc) => {
|
||||
@@ -1217,14 +1221,18 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
* but to multifile and discontiguous predicates as well.
|
||||
*/
|
||||
|
||||
let code_index = self.get_or_insert_code_index(key, compilation_target);
|
||||
let offset = self.get_or_insert_code_index(key, compilation_target);
|
||||
let code_idx_ptr = LS::machine_st(&mut self.payload)
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup_mut(offset.into());
|
||||
|
||||
if code_index.as_ptr().is_undefined() {
|
||||
set_code_index(
|
||||
&mut self.payload.retraction_info,
|
||||
if code_idx_ptr.is_undefined() {
|
||||
set_code_index::<LS>(
|
||||
&mut self.payload,
|
||||
&compilation_target,
|
||||
key,
|
||||
code_index,
|
||||
offset,
|
||||
IndexPtr::dynamic_undefined(),
|
||||
);
|
||||
}
|
||||
@@ -1395,7 +1403,7 @@ impl MachineState {
|
||||
Err(cons_term) => term_stack.push(cons_term),
|
||||
}
|
||||
}
|
||||
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | HeapCellValueTag::F64) => {
|
||||
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | HeapCellValueTag::F64Offset) => {
|
||||
term_stack.push(Term::Literal(Cell::default(), Literal::try_from(addr).unwrap()));
|
||||
}
|
||||
(HeapCellValueTag::StackVar, h) => {
|
||||
@@ -1410,7 +1418,7 @@ impl MachineState {
|
||||
let value = iter.heap[h.saturating_sub(1)];
|
||||
|
||||
if let Some(idx) = get_structure_index(value) {
|
||||
term_stack.push(Term::Literal(Cell::default(), Literal::CodeIndex(idx)));
|
||||
term_stack.push(Term::Literal(Cell::default(), Literal::CodeIndexOffset(idx.into())));
|
||||
arity += 1;
|
||||
}
|
||||
|
||||
@@ -1588,7 +1596,7 @@ impl Machine {
|
||||
let predicate_name = cell_as_atom!(self.deref_register(2));
|
||||
|
||||
let arity = self.deref_register(3);
|
||||
let arity = match Number::try_from(arity) {
|
||||
let arity = match Number::try_from((arity, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(n)) if *n >= Integer::ZERO && *n <= Integer::from(MAX_ARITY) => {
|
||||
let value: usize = (&*n).try_into().unwrap();
|
||||
Ok(value)
|
||||
@@ -1999,7 +2007,15 @@ impl Machine {
|
||||
.wam_prelude
|
||||
.indices
|
||||
.get_predicate_code_index(name, arity, module_name)
|
||||
.map(|code_idx| code_idx.get_tag())
|
||||
.map(|offset| {
|
||||
loader
|
||||
.payload
|
||||
.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup(offset.into())
|
||||
.tag()
|
||||
})
|
||||
.unwrap_or(IndexPtrTag::DynamicUndefined);
|
||||
|
||||
if idx_tag == IndexPtrTag::Index {
|
||||
@@ -2142,9 +2158,15 @@ impl Machine {
|
||||
.indices
|
||||
.remove_predicate_skeleton(&compilation_target, &key);
|
||||
|
||||
let mut code_index = loader.get_or_insert_code_index(key, compilation_target);
|
||||
let offset = loader.get_or_insert_code_index(key, compilation_target);
|
||||
let mut code_idx = loader
|
||||
.payload
|
||||
.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup_mut(offset.into());
|
||||
|
||||
code_index.set(IndexPtr::undefined());
|
||||
code_idx.set(IndexPtr::undefined());
|
||||
|
||||
loader.payload.compilation_target = clause_clause_compilation_target;
|
||||
|
||||
@@ -2174,7 +2196,7 @@ impl Machine {
|
||||
.machine_st
|
||||
.store(self.machine_st.deref(self.machine_st[temp_v!(3)]));
|
||||
|
||||
let target_pos = match Number::try_from(target_pos) {
|
||||
let target_pos = match Number::try_from((target_pos, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(n)) => {
|
||||
let value: usize = (&*n).try_into().unwrap();
|
||||
value
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use crate::parser::ast::*;
|
||||
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::loader::*;
|
||||
@@ -19,7 +18,6 @@ use scryer_modular_bitfield::{bitfield, BitfieldSpecifier};
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::BTreeSet;
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::types::*;
|
||||
|
||||
@@ -127,9 +125,18 @@ impl IndexPtr {
|
||||
pub(crate) fn is_dynamic_undefined(&self) -> bool {
|
||||
matches!(self.tag(), IndexPtrTag::DynamicUndefined)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn local(&self) -> Option<usize> {
|
||||
match self.tag() {
|
||||
IndexPtrTag::Index => Some(self.p() as usize),
|
||||
IndexPtrTag::DynamicIndex => Some(self.p() as usize),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Ord, Hash, PartialOrd, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy)] // , Ord, Hash, PartialOrd, Eq, PartialEq)]
|
||||
pub struct CodeIndex(CodeIndexOffset);
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
@@ -141,7 +148,7 @@ const_assert!(std::mem::align_of::<CodeIndex>() == 8);
|
||||
impl From<CodeIndex> for HeapCellValue {
|
||||
#[inline(always)]
|
||||
fn from(idx: CodeIndex) -> HeapCellValue {
|
||||
HeapCellValue::from(idx.as_ptr())
|
||||
HeapCellValue::from(idx.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,48 +159,39 @@ impl From<CodeIndexOffset> for CodeIndex {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<CodeIndexOffset> for CodeIndex {
|
||||
#[inline(always)]
|
||||
fn into(self) -> CodeIndexOffset {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<CodeIndexOffset> for &'_ CodeIndex {
|
||||
#[inline(always)]
|
||||
fn into(self) -> CodeIndexOffset {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl CodeIndex {
|
||||
#[inline]
|
||||
pub(crate) fn new(ptr: IndexPtr, arena: &mut Arena) -> Self {
|
||||
unsafe { CodeIndex(arena.code_index_tbl.build_with(ptr)) }
|
||||
pub(crate) fn new(ptr: IndexPtr, code_index_tbl: &mut CodeIndexTable) -> Self {
|
||||
CodeIndex(code_index_tbl.build_with(ptr))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn default(arena: &mut Arena) -> Self {
|
||||
CodeIndex::new(IndexPtr::undefined(), arena)
|
||||
}
|
||||
|
||||
pub(crate) fn local(&self) -> Option<usize> {
|
||||
match self.0.as_ptr().tag() {
|
||||
IndexPtrTag::Index => Some(self.get().p() as usize),
|
||||
IndexPtrTag::DynamicIndex => Some(self.get().p() as usize),
|
||||
_ => None,
|
||||
}
|
||||
pub(crate) fn default(code_index_tbl: &mut CodeIndexTable) -> Self {
|
||||
CodeIndex::new(IndexPtr::undefined(), code_index_tbl)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn get(&self) -> IndexPtr {
|
||||
*self.as_ptr().deref()
|
||||
pub(crate) fn set(&self, code_index_tbl: &mut CodeIndexTable, value: IndexPtr) {
|
||||
code_index_tbl.lookup_mut(self.0).set(value);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn set(&mut self, value: IndexPtr) {
|
||||
self.as_ptr().set(value);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn get_tag(self) -> IndexPtrTag {
|
||||
self.get().tag()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn replace(&mut self, value: IndexPtr) -> IndexPtr {
|
||||
self.as_ptr().replace(value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_ptr(&self) -> CodeIndexPtr {
|
||||
self.0.as_ptr()
|
||||
pub(crate) fn replace(&self, code_index_tbl: &mut CodeIndexTable, value: IndexPtr) -> IndexPtr {
|
||||
code_index_tbl.lookup_mut(self.0).replace(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -952,6 +952,7 @@ impl MachineState {
|
||||
let mut printer = HCPrinter::new(
|
||||
&mut self.heap,
|
||||
&mut self.stack,
|
||||
&self.arena,
|
||||
op_dir,
|
||||
PrinterOutputter::new(),
|
||||
0,
|
||||
@@ -962,7 +963,7 @@ impl MachineState {
|
||||
printer.quoted = quoted;
|
||||
printer.double_quotes = double_quotes;
|
||||
|
||||
match Number::try_from(max_depth) {
|
||||
match Number::try_from((max_depth, &self.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => {
|
||||
if let Ok(n) = usize::try_from(n.get_num()) {
|
||||
printer.max_depth = n;
|
||||
|
||||
@@ -288,7 +288,7 @@ impl MachineState {
|
||||
unifier.unify_big_rational(n1, value);
|
||||
}
|
||||
|
||||
pub fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
|
||||
pub fn unify_f64(&mut self, f1: F64Offset, value: HeapCellValue) {
|
||||
let mut unifier = DefaultUnifier::from(self);
|
||||
unifier.unify_f64(f1, value);
|
||||
}
|
||||
@@ -409,8 +409,11 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
Some(TermOrderCategory::FloatingPoint) => {
|
||||
let v1 = cell_as_f64_ptr!(v1);
|
||||
let v2 = cell_as_f64_ptr!(v2);
|
||||
let v1 = cell_as_f64_offset!(v1);
|
||||
let v2 = cell_as_f64_offset!(v2);
|
||||
|
||||
let v1 = self.arena.f64_tbl.lookup(v1);
|
||||
let v2 = self.arena.f64_tbl.lookup(v2);
|
||||
|
||||
if v1 != v2 {
|
||||
self.pdl.clear();
|
||||
@@ -418,8 +421,8 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
Some(TermOrderCategory::Integer) => {
|
||||
let v1 = Number::try_from(v1).unwrap();
|
||||
let v2 = Number::try_from(v2).unwrap();
|
||||
let v1 = Number::try_from((v1, &self.arena.f64_tbl)).unwrap();
|
||||
let v2 = Number::try_from((v2, &self.arena.f64_tbl)).unwrap();
|
||||
|
||||
if v1 != v2 {
|
||||
self.pdl.clear();
|
||||
@@ -436,22 +439,6 @@ impl MachineState {
|
||||
return Some(n1.cmp(&n2));
|
||||
}
|
||||
}
|
||||
/*
|
||||
(HeapCellValueTag::Char, c2) => {
|
||||
if let Some(c1) = n1.as_char() {
|
||||
if c1 != c2 {
|
||||
self.pdl.clear();
|
||||
return Some(c1.cmp(&c2));
|
||||
}
|
||||
} else {
|
||||
self.pdl.clear();
|
||||
return Some(
|
||||
n1.as_str().chars().next().cmp(&Some(c2))
|
||||
.then(Ordering::Greater)
|
||||
);
|
||||
}
|
||||
}
|
||||
*/
|
||||
(HeapCellValueTag::Str, s) => {
|
||||
let n2 = cell_as_atom_cell!(self.heap[s])
|
||||
.get_name();
|
||||
@@ -466,52 +453,6 @@ impl MachineState {
|
||||
}
|
||||
)
|
||||
}
|
||||
/*
|
||||
(HeapCellValueTag::Char, c1) => {
|
||||
read_heap_cell!(v2,
|
||||
(HeapCellValueTag::Atom, (n2, _a2)) => {
|
||||
if let Some(c2) = n2.as_char() {
|
||||
if c1 != c2 {
|
||||
self.pdl.clear();
|
||||
return Some(c1.cmp(&c2));
|
||||
}
|
||||
} else {
|
||||
self.pdl.clear();
|
||||
return Some(
|
||||
Some(c1).cmp(&n2.as_str().chars().next())
|
||||
.then(Ordering::Less)
|
||||
);
|
||||
}
|
||||
}
|
||||
(HeapCellValueTag::Char, c2) => {
|
||||
if c1 != c2 {
|
||||
self.pdl.clear();
|
||||
return Some(c1.cmp(&c2));
|
||||
}
|
||||
}
|
||||
(HeapCellValueTag::Str, s) => {
|
||||
let n2 = cell_as_atom_cell!(self.heap[s])
|
||||
.get_name();
|
||||
|
||||
if let Some(c2) = n2.as_char() {
|
||||
if c1 != c2 {
|
||||
self.pdl.clear();
|
||||
return Some(c1.cmp(&c2));
|
||||
}
|
||||
} else {
|
||||
self.pdl.clear();
|
||||
return Some(
|
||||
Some(c1).cmp(&n2.as_str().chars().next())
|
||||
.then(Ordering::Less)
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
)
|
||||
}
|
||||
*/
|
||||
(HeapCellValueTag::Str, s) => {
|
||||
let n1 = cell_as_atom_cell!(self.heap[s])
|
||||
.get_name();
|
||||
@@ -523,22 +464,6 @@ impl MachineState {
|
||||
return Some(n1.cmp(&n2));
|
||||
}
|
||||
}
|
||||
/*
|
||||
(HeapCellValueTag::Char, c2) => {
|
||||
if let Some(c1) = n1.as_char() {
|
||||
if c1 != c2 {
|
||||
self.pdl.clear();
|
||||
return Some(c1.cmp(&c2));
|
||||
}
|
||||
} else {
|
||||
self.pdl.clear();
|
||||
return Some(
|
||||
n1.as_str().chars().next().cmp(&Some(c2))
|
||||
.then(Ordering::Greater)
|
||||
);
|
||||
}
|
||||
}
|
||||
*/
|
||||
(HeapCellValueTag::Str, s) => {
|
||||
let n2 = cell_as_atom_cell!(self.heap[s])
|
||||
.get_name();
|
||||
@@ -865,7 +790,7 @@ impl MachineState {
|
||||
return Err(self.error_form(err, stub_gen()));
|
||||
}
|
||||
_ => {
|
||||
let n = match Number::try_from(n) {
|
||||
let n = match Number::try_from((n, &self.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => Number::Fixnum(n),
|
||||
Ok(Number::Integer(n)) => Number::Integer(n),
|
||||
_ => {
|
||||
@@ -917,46 +842,18 @@ impl MachineState {
|
||||
(HeapCellValueTag::PStrLoc, pstr_loc) => {
|
||||
if n == 1 || n == 2 {
|
||||
let a3 = self.registers[3];
|
||||
// let (h, offset) = pstr_loc_and_offset(&self.heap, pstr_loc);
|
||||
let mut char_iter = self.heap.char_iter(pstr_loc);
|
||||
|
||||
// let pstr = cell_as_string!(self.heap[h]);
|
||||
// let offset = offset.get_num() as usize;
|
||||
|
||||
if let Some(c) = char_iter.next() { // pstr.as_str_from(offset).chars().next() {
|
||||
if let Some(c) = char_iter.next() {
|
||||
if n == 1 {
|
||||
self.unify_char(c, a3);
|
||||
} else {
|
||||
// let offset = (offset + c.len_utf8()) as i64;
|
||||
// let h_len = self.heap.len();
|
||||
// let pstr_atom: Atom = pstr.into();
|
||||
if char_iter.next().is_some() {
|
||||
unify_fn!(*self, pstr_loc_as_cell!(pstr_loc + c.len_utf8()), a3);
|
||||
} else {
|
||||
let tail_idx = Heap::pstr_tail_idx(pstr_loc + c.len_utf8());
|
||||
unify_fn!(*self, self.heap[tail_idx], a3);
|
||||
}
|
||||
|
||||
/*
|
||||
if pstr_atom.len() > offset as usize {
|
||||
self.heap.push(pstr_offset_as_cell!(h));
|
||||
self.heap.push(fixnum_as_cell!(Fixnum::build_with_unchecked(offset as i64)));
|
||||
|
||||
unify_fn!(*self, pstr_loc_as_cell!(h_len), a3);
|
||||
} else {
|
||||
match self.heap[h].get_tag() {
|
||||
HeapCellValueTag::CStr => {
|
||||
self.unify_atom(atom!("[]"), self.store(self.deref(a3)));
|
||||
}
|
||||
HeapCellValueTag::PStr => {
|
||||
unify_fn!(*self, self.heap[h+1], a3);
|
||||
}
|
||||
_ => {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
@@ -965,34 +862,6 @@ impl MachineState {
|
||||
self.fail = true;
|
||||
}
|
||||
}
|
||||
/*
|
||||
(HeapCellValueTag::CStr, cstr_atom) => {
|
||||
let cstr = PartialString::from(cstr_atom);
|
||||
|
||||
if let Some(c) = cstr.as_str_from(0).chars().next() {
|
||||
if n == 1 {
|
||||
self.unify_char(c, self.store(self.deref(self.registers[3])));
|
||||
} else if n == 2 {
|
||||
let offset = c.len_utf8();
|
||||
let h_len = self.heap.len();
|
||||
|
||||
if cstr_atom.len() > offset{
|
||||
self.heap.push(atom_as_cstr_cell!(cstr_atom));
|
||||
self.heap.push(pstr_offset_as_cell!(h_len));
|
||||
self.heap.push(fixnum_as_cell!(Fixnum::build_with_unchecked(offset as i64)));
|
||||
|
||||
unify_fn!(*self, pstr_loc_as_cell!(h_len+1), self.registers[3]);
|
||||
} else {
|
||||
self.unify_atom(atom!("[]"), self.store(self.deref(self.registers[3])));
|
||||
}
|
||||
} else {
|
||||
self.fail = true;
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
*/
|
||||
_ => {
|
||||
// 8.5.2.3 d)
|
||||
let err = self.type_error(ValidType::Compound, term);
|
||||
@@ -1077,7 +946,7 @@ impl MachineState {
|
||||
|
||||
read_heap_cell!(a1,
|
||||
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | // | HeapCellValueTag::Char
|
||||
HeapCellValueTag::F64) => {
|
||||
HeapCellValueTag::F64Offset) => {
|
||||
self.try_functor_unify_components(a1, 0);
|
||||
}
|
||||
(HeapCellValueTag::Atom, (_name, arity)) => {
|
||||
@@ -1103,17 +972,17 @@ impl MachineState {
|
||||
return Err(self.error_form(err, stub_gen()));
|
||||
}
|
||||
|
||||
let mut type_error = |arity| {
|
||||
let err = self.type_error(ValidType::Integer, arity);
|
||||
Err(self.error_form(err, stub_gen()))
|
||||
let type_error = |machine_st: &mut Self, arity| {
|
||||
let err = machine_st.type_error(ValidType::Integer, arity);
|
||||
Err(machine_st.error_form(err, stub_gen()))
|
||||
};
|
||||
|
||||
let arity = match Number::try_from(arity) {
|
||||
let arity = match Number::try_from((arity, &self.arena.f64_tbl)) {
|
||||
Ok(Number::Float(_)) => {
|
||||
return type_error(arity);
|
||||
return type_error(self, arity);
|
||||
}
|
||||
Ok(Number::Rational(n)) if !n.denominator().is_one() => {
|
||||
return type_error(arity);
|
||||
return type_error(self, arity);
|
||||
}
|
||||
Ok(n) if n > MAX_ARITY => {
|
||||
// 8.5.1.3 f)
|
||||
@@ -1135,13 +1004,13 @@ impl MachineState {
|
||||
value
|
||||
},
|
||||
Err(_) => {
|
||||
return type_error(arity);
|
||||
return type_error(self, arity);
|
||||
}
|
||||
};
|
||||
|
||||
read_heap_cell!(store_name,
|
||||
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | // HeapCellValueTag::Char |
|
||||
HeapCellValueTag::F64) if arity == 0 => {
|
||||
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | HeapCellValueTag::F64Offset)
|
||||
if arity == 0 => {
|
||||
self.bind(a1.as_var().unwrap(), deref_name);
|
||||
}
|
||||
(HeapCellValueTag::Atom, (name, atom_arity)) => {
|
||||
@@ -1173,22 +1042,8 @@ impl MachineState {
|
||||
return Err(self.error_form(err, stub_gen()));
|
||||
}
|
||||
}
|
||||
/*
|
||||
(HeapCellValueTag::Char, c) => {
|
||||
let c = AtomTable::build_with(&self.atom_tbl, &c.to_string());
|
||||
|
||||
resource_error_call_result!(
|
||||
self,
|
||||
self.try_functor_fabricate_struct(
|
||||
c,
|
||||
arity as usize,
|
||||
a1.as_var().unwrap(),
|
||||
)
|
||||
);
|
||||
}
|
||||
*/
|
||||
(HeapCellValueTag::Cons | HeapCellValueTag::Fixnum |
|
||||
HeapCellValueTag::F64) if arity != 0 => {
|
||||
HeapCellValueTag::F64Offset) if arity != 0 => {
|
||||
let err = self.type_error(ValidType::Atom, store_name);
|
||||
return Err(self.error_form(err, stub_gen())); // 8.5.1.3 e)
|
||||
}
|
||||
@@ -1243,12 +1098,6 @@ impl MachineState {
|
||||
Err(self.error_form(err, stub_gen()))
|
||||
}
|
||||
}
|
||||
/*
|
||||
(HeapCellValueTag::CStr, cstr_atom) => {
|
||||
let cstr = cstr_atom.as_str();
|
||||
Ok(cstr.chars().map(|c| char_as_cell!(c)).collect())
|
||||
}
|
||||
*/
|
||||
_ => {
|
||||
let err = self.type_error(ValidType::List, value);
|
||||
Err(self.error_form(err, stub_gen()))
|
||||
@@ -1372,7 +1221,7 @@ impl MachineState {
|
||||
for addr in addrs {
|
||||
let addr = self.store(self.deref(addr));
|
||||
|
||||
match Number::try_from(addr) {
|
||||
match Number::try_from((addr, &self.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => {
|
||||
if let Ok(b) = u8::try_from(n.get_num()) {
|
||||
bytes.push(b)
|
||||
|
||||
@@ -56,6 +56,7 @@ impl MockWAM {
|
||||
let mut printer = HCPrinter::new(
|
||||
&mut self.machine_st.heap,
|
||||
&mut self.machine_st.stack,
|
||||
&mut self.machine_st.arena,
|
||||
&self.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
term_write_result.heap_loc,
|
||||
|
||||
@@ -208,8 +208,8 @@ pub(crate) fn import_builtin_impls(code_dir: &CodeDir, builtins: &mut Module) {
|
||||
#[inline]
|
||||
pub(crate) fn get_structure_index(value: HeapCellValue) -> Option<CodeIndex> {
|
||||
read_heap_cell!(value,
|
||||
(HeapCellValueTag::CodeIndex, ip) => {
|
||||
return Some(ip);
|
||||
(HeapCellValueTag::CodeIndexOffset, offset) => {
|
||||
return Some(CodeIndex::from(offset));
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
@@ -242,7 +242,7 @@ impl Machine {
|
||||
}
|
||||
|
||||
/// Runs the predicate `key` in `module_name` until completion.
|
||||
/// Siltently ignores failure, thrown errors and choice points.
|
||||
/// Silently ignores failure, thrown errors and choice points.
|
||||
///
|
||||
/// Consider using [`Machine::run_query`] if you wish to handle
|
||||
/// predicates that may fail, leave a choice point or throw.
|
||||
@@ -252,8 +252,10 @@ impl Machine {
|
||||
key: PredicateKey,
|
||||
) -> std::process::ExitCode {
|
||||
if let Some(module) = self.indices.modules.get(&module_name) {
|
||||
if let Some(code_index) = module.code_dir.get(&key) {
|
||||
let p = code_index.local().unwrap();
|
||||
if let Some(code_idx) = module.code_dir.get(&key) {
|
||||
let index_ptr = self.machine_st.arena.code_index_tbl.lookup(code_idx.into());
|
||||
let p = index_ptr.local().unwrap();
|
||||
|
||||
// Leave a halting choice point to backtrack to in case the predicate fails or throws.
|
||||
self.allocate_stub_choice_point();
|
||||
|
||||
@@ -324,8 +326,9 @@ impl Machine {
|
||||
self.load_file(path_buf.to_str().unwrap(), stream);
|
||||
|
||||
if let Some(module) = self.indices.modules.get(&atom!("$atts")) {
|
||||
if let Some(code_index) = module.code_dir.get(&(atom!("driver"), 2)) {
|
||||
self.machine_st.attr_var_init.verify_attrs_loc = code_index.local().unwrap();
|
||||
if let Some(code_idx) = module.code_dir.get(&(atom!("driver"), 2)) {
|
||||
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(code_idx.into());
|
||||
self.machine_st.attr_var_init.verify_attrs_loc = index_ptr.local().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,13 +342,16 @@ impl Machine {
|
||||
for arity in 1..66 {
|
||||
let key = (atom!("call"), arity);
|
||||
|
||||
match loader.code_dir.get(&key) {
|
||||
match loader.code_dir.get(&key).cloned() {
|
||||
Some(src_code_index) => {
|
||||
let target_code_index = target_code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
|
||||
let code_index_tbl = &mut arena.code_index_tbl;
|
||||
|
||||
target_code_index.set(src_code_index.get());
|
||||
let target_code_index = target_code_dir.entry(key).or_insert_with(|| {
|
||||
CodeIndex::new(IndexPtr::undefined(), code_index_tbl)
|
||||
});
|
||||
|
||||
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
|
||||
target_code_index.set(code_index_tbl, src_code_ptr);
|
||||
}
|
||||
None => {
|
||||
unreachable!();
|
||||
@@ -454,7 +460,7 @@ impl Machine {
|
||||
key,
|
||||
CodeIndex::new(
|
||||
IndexPtr::index(p + impls_offset),
|
||||
&mut self.machine_st.arena,
|
||||
&mut self.machine_st.arena.code_index_tbl,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -535,37 +541,8 @@ impl Machine {
|
||||
|
||||
if cell.is_var() {
|
||||
offset += 1;
|
||||
/*
|
||||
} else if lit.get_tag() == HeapCellValueTag::CStr {
|
||||
read_heap_cell!(cell,
|
||||
(HeapCellValueTag::CStr) => {
|
||||
if cell == lit {
|
||||
offset += 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
(HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc) => {
|
||||
offset += 1;
|
||||
}
|
||||
(HeapCellValueTag::Str, s) => {
|
||||
let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
|
||||
.get_name_and_arity();
|
||||
|
||||
if name == atom!(".") && arity == 2 {
|
||||
offset += 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return false;
|
||||
}
|
||||
);
|
||||
*/
|
||||
} else {
|
||||
unify!(self.machine_st, cell, lit);
|
||||
// self.machine_st.write_literal_to_var(cell, lit);
|
||||
|
||||
if self.machine_st.fail {
|
||||
self.machine_st.fail = false;
|
||||
@@ -1068,13 +1045,15 @@ impl Machine {
|
||||
|
||||
if module_name == atom!("user") {
|
||||
if let Some(idx) = self.indices.code_dir.get(&(name, arity)).cloned() {
|
||||
self.try_call(name, arity, idx.get())
|
||||
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
|
||||
self.try_call(name, arity, index_ptr)
|
||||
} else {
|
||||
Err(self.machine_st.throw_undefined_error(name, arity))
|
||||
}
|
||||
} else if let Some(module) = self.indices.modules.get(&module_name) {
|
||||
if let Some(idx) = module.code_dir.get(&(name, arity)).cloned() {
|
||||
self.try_call(name, arity, idx.get())
|
||||
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
|
||||
self.try_call(name, arity, index_ptr)
|
||||
} else {
|
||||
self.undefined_procedure(name, arity)
|
||||
}
|
||||
@@ -1098,13 +1077,15 @@ impl Machine {
|
||||
|
||||
if module_name == atom!("user") {
|
||||
if let Some(idx) = self.indices.code_dir.get(&(name, arity)).cloned() {
|
||||
self.try_execute(name, arity, idx.get())
|
||||
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
|
||||
self.try_execute(name, arity, index_ptr)
|
||||
} else {
|
||||
self.undefined_procedure(name, arity)
|
||||
}
|
||||
} else if let Some(module) = self.indices.modules.get(&module_name) {
|
||||
if let Some(idx) = module.code_dir.get(&(name, arity)).cloned() {
|
||||
self.try_execute(name, arity, idx.get())
|
||||
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
|
||||
self.try_execute(name, arity, index_ptr)
|
||||
} else {
|
||||
self.undefined_procedure(name, arity)
|
||||
}
|
||||
@@ -1146,12 +1127,24 @@ impl Machine {
|
||||
let r_c_w_h = self
|
||||
.indices
|
||||
.get_predicate_code_index(r_c_w_h_atom, 0, iso_ext)
|
||||
.and_then(|item| item.local())
|
||||
.and_then(|code_idx| {
|
||||
self.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup(code_idx.into())
|
||||
.local()
|
||||
})
|
||||
.unwrap();
|
||||
let r_c_wo_h = self
|
||||
.indices
|
||||
.get_predicate_code_index(r_c_wo_h_atom, 1, iso_ext)
|
||||
.and_then(|item| item.local())
|
||||
.and_then(|code_idx| {
|
||||
self.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup(code_idx.into())
|
||||
.local()
|
||||
})
|
||||
.unwrap();
|
||||
(r_c_w_h, r_c_wo_h)
|
||||
});
|
||||
|
||||
@@ -424,7 +424,7 @@ fn build_meta_predicate_clause<'a, LS: LoadState<'a>>(
|
||||
|
||||
let term = match term {
|
||||
Term::Clause(cell, name, mut terms) => {
|
||||
if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() {
|
||||
if let Some(Term::Literal(_, Literal::CodeIndexOffset(_))) = terms.last() {
|
||||
arg_terms
|
||||
.push(process_term(module_name, Term::Clause(cell, name, terms)));
|
||||
|
||||
@@ -433,7 +433,10 @@ fn build_meta_predicate_clause<'a, LS: LoadState<'a>>(
|
||||
|
||||
let idx = loader.get_or_insert_qualified_code_index(module_name, key);
|
||||
|
||||
terms.push(Term::Literal(Cell::default(), Literal::CodeIndex(idx)));
|
||||
terms.push(Term::Literal(
|
||||
Cell::default(),
|
||||
Literal::CodeIndexOffset(idx.into()),
|
||||
));
|
||||
process_term(module_name, Term::Clause(cell, name, terms))
|
||||
}
|
||||
Term::Literal(cell, Literal::Atom(name)) => {
|
||||
@@ -444,7 +447,10 @@ fn build_meta_predicate_clause<'a, LS: LoadState<'a>>(
|
||||
Term::Clause(
|
||||
cell,
|
||||
name,
|
||||
vec![Term::Literal(Cell::default(), Literal::CodeIndex(idx))],
|
||||
vec![Term::Literal(
|
||||
Cell::default(),
|
||||
Literal::CodeIndexOffset(idx.into()),
|
||||
)],
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -469,7 +475,7 @@ pub(super) fn clause_to_query_term<'a, LS: LoadState<'a>>(
|
||||
mut terms: Vec<Term>,
|
||||
call_policy: CallPolicy,
|
||||
) -> QueryTerm {
|
||||
if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() {
|
||||
if let Some(Term::Literal(_, Literal::CodeIndexOffset(_))) = terms.last() {
|
||||
// supplementary code vector indices are unnecessary for
|
||||
// root-level clauses.
|
||||
terms.pop();
|
||||
@@ -504,7 +510,7 @@ pub(super) fn qualified_clause_to_query_term<'a, LS: LoadState<'a>>(
|
||||
mut terms: Vec<Term>,
|
||||
call_policy: CallPolicy,
|
||||
) -> QueryTerm {
|
||||
if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() {
|
||||
if let Some(Term::Literal(_, Literal::CodeIndexOffset(_))) = terms.last() {
|
||||
// supplementary code vector indices are unnecessary for
|
||||
// root-level clauses.
|
||||
terms.pop();
|
||||
|
||||
@@ -25,6 +25,7 @@ use crate::machine::partial_string::*;
|
||||
use crate::machine::stack::*;
|
||||
use crate::machine::streams::*;
|
||||
use crate::machine::{get_structure_index, Machine, VERIFY_ATTR_INTERRUPT_LOC};
|
||||
use crate::offset_table::*;
|
||||
use crate::parser::ast::*;
|
||||
use crate::parser::char_reader::*;
|
||||
use crate::parser::dashu::Integer;
|
||||
@@ -821,7 +822,7 @@ impl MachineState {
|
||||
let mut max_old = -1i64;
|
||||
|
||||
if !max_steps.is_var() {
|
||||
let max_steps = Number::try_from(max_steps);
|
||||
let max_steps = Number::try_from((max_steps, &self.arena.f64_tbl));
|
||||
|
||||
let max_steps_n = match max_steps {
|
||||
Ok(Number::Fixnum(n)) => Some(n.get_num()),
|
||||
@@ -1132,7 +1133,7 @@ impl MachineState {
|
||||
for addr in addrs {
|
||||
let addr = self.store(self.deref(addr));
|
||||
|
||||
match Number::try_from(addr) {
|
||||
match Number::try_from((addr, &self.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => {
|
||||
if let Ok(n) = u32::try_from(n.get_num()) {
|
||||
if let Some(c) = std::char::from_u32(n) {
|
||||
@@ -1241,7 +1242,13 @@ impl Machine {
|
||||
let mut bp = self
|
||||
.indices
|
||||
.get_predicate_code_index(atom!("$clause"), 2, module_name)
|
||||
.and_then(|idx| idx.local())
|
||||
.and_then(|idx| {
|
||||
self.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup(idx.into())
|
||||
.local()
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
macro_rules! extract_ptr {
|
||||
@@ -1431,7 +1438,7 @@ impl Machine {
|
||||
self.machine_st.error_form(err, stub)
|
||||
})?;
|
||||
|
||||
let index_cell = if index_cell_opt.is_some() {
|
||||
let index_cell_opt = if index_cell_opt.is_some() {
|
||||
index_cell_opt
|
||||
} else {
|
||||
let is_internal_call = name == atom!("$call") && goal_arity > 0;
|
||||
@@ -1469,11 +1476,13 @@ impl Machine {
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(code_index) = index_cell {
|
||||
if !code_index.as_ptr().is_undefined() {
|
||||
if let Some(code_idx) = index_cell_opt {
|
||||
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(code_idx.into());
|
||||
|
||||
if !index_ptr.is_undefined() {
|
||||
load_registers(&mut self.machine_st, goal, goal_arity);
|
||||
self.machine_st.neck_cut();
|
||||
return call_at_index(self, name, arity, code_index.get());
|
||||
return call_at_index(self, name, arity, index_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1653,7 +1662,7 @@ impl Machine {
|
||||
|
||||
let idx = CodeIndex::new(
|
||||
IndexPtr::index(helper_clause_loc),
|
||||
&mut self.machine_st.arena,
|
||||
&mut self.machine_st.arena.code_index_tbl,
|
||||
);
|
||||
|
||||
writer.write_with(|section| {
|
||||
@@ -1694,7 +1703,7 @@ impl Machine {
|
||||
|
||||
let idx_cell = self.machine_st.heap[s.saturating_sub(1)];
|
||||
|
||||
if HeapCellValueTag::CodeIndex == idx_cell.get_tag() {
|
||||
if HeapCellValueTag::CodeIndexOffset == idx_cell.get_tag() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1846,7 +1855,7 @@ impl Machine {
|
||||
#[inline(always)]
|
||||
pub(crate) fn bind_from_register(&mut self) {
|
||||
let reg = self.deref_register(2);
|
||||
let n = match Number::try_from(reg) {
|
||||
let n = match Number::try_from((reg, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
|
||||
Ok(Number::Integer(n)) => {
|
||||
let value: usize = (&*n).try_into().unwrap();
|
||||
@@ -2608,7 +2617,7 @@ impl Machine {
|
||||
|
||||
let addr = match addr {
|
||||
addr if addr.is_var() => addr,
|
||||
addr => match Number::try_from(addr) {
|
||||
addr => match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(n)) => {
|
||||
let result: Result<u8, _> = (&*n).try_into();
|
||||
if let Ok(value) = result {
|
||||
@@ -2797,7 +2806,7 @@ impl Machine {
|
||||
a2
|
||||
}
|
||||
_ => {
|
||||
match Number::try_from(a2) {
|
||||
match Number::try_from((a2, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(n)) => {
|
||||
let n: u32 = (&*n).try_into().unwrap();
|
||||
|
||||
@@ -2864,7 +2873,7 @@ impl Machine {
|
||||
let n = self.deref_register(1);
|
||||
let chs = self.deref_register(2);
|
||||
|
||||
let string = match Number::try_from(n) {
|
||||
let string = match Number::try_from((n, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Float(OrderedFloat(n))) => fmt_float(n),
|
||||
Ok(Number::Fixnum(n)) => n.get_num().to_string(),
|
||||
Ok(Number::Integer(n)) => n.to_string(),
|
||||
@@ -2892,7 +2901,7 @@ impl Machine {
|
||||
let n = self.deref_register(1);
|
||||
let chs = self.machine_st.registers[2];
|
||||
|
||||
let string = match Number::try_from(n) {
|
||||
let string = match Number::try_from((n, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Float(OrderedFloat(n))) => {
|
||||
format!("{0:<20?}", n)
|
||||
}
|
||||
@@ -2979,13 +2988,8 @@ impl Machine {
|
||||
debug_assert_eq!(arity, 0);
|
||||
name.as_char().unwrap()
|
||||
}
|
||||
/*
|
||||
(HeapCellValueTag::Char, c) => {
|
||||
c
|
||||
}
|
||||
*/
|
||||
_ => {
|
||||
match Number::try_from(a2) {
|
||||
match Number::try_from((a2, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(n)) => {
|
||||
let n: u32 = (&*n).try_into().unwrap();
|
||||
let n = std::char::from_u32(n);
|
||||
@@ -3223,7 +3227,7 @@ impl Machine {
|
||||
let err = self.machine_st.instantiation_error();
|
||||
Err(self.machine_st.error_form(err, stub_gen()))
|
||||
} else {
|
||||
match Number::try_from(addr) {
|
||||
match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(n)) => {
|
||||
let n: u32 = (&*n).try_into().unwrap();
|
||||
let n = char::try_from(n);
|
||||
@@ -3370,7 +3374,7 @@ impl Machine {
|
||||
let err = self.machine_st.instantiation_error();
|
||||
return Err(self.machine_st.error_form(err, stub_gen()));
|
||||
} else {
|
||||
match Number::try_from(addr) {
|
||||
match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(n)) => {
|
||||
let n: u8 = (&*n).try_into().unwrap();
|
||||
|
||||
@@ -3449,7 +3453,7 @@ impl Machine {
|
||||
let addr = if addr.is_var() {
|
||||
addr
|
||||
} else {
|
||||
match Number::try_from(addr) {
|
||||
match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(ref n)) if (**n).num_eq(&1_i64) => {
|
||||
fixnum_as_cell!(Fixnum::build_with(-1))
|
||||
}
|
||||
@@ -3603,7 +3607,7 @@ impl Machine {
|
||||
3,
|
||||
)?;
|
||||
|
||||
let num = match Number::try_from(self.deref_register(2)) {
|
||||
let num = match Number::try_from((self.deref_register(2), &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
|
||||
Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
|
||||
Ok(u) => u,
|
||||
@@ -3704,7 +3708,7 @@ impl Machine {
|
||||
let addr = if addr.is_var() {
|
||||
addr
|
||||
} else {
|
||||
match Number::try_from(addr) {
|
||||
match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(n)) => {
|
||||
let n: u32 = (&*n).try_into().unwrap();
|
||||
let n = std::char::from_u32(n);
|
||||
@@ -4040,7 +4044,7 @@ impl Machine {
|
||||
} else {
|
||||
arity_match = |arity_1, arity_2| arity_1 == arity_2;
|
||||
|
||||
let arity = match Number::try_from(arity) {
|
||||
let arity = match Number::try_from((arity, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => Some(n.get_num() as usize),
|
||||
Ok(Number::Integer(n)) => {
|
||||
let value: usize = (&*n).try_into().unwrap();
|
||||
@@ -4299,7 +4303,10 @@ impl Machine {
|
||||
pub(crate) fn random_integer(&mut self) {
|
||||
let a1 = self.deref_register(1);
|
||||
let a2 = self.deref_register(2);
|
||||
let value = match (Number::try_from(a1), Number::try_from(a2)) {
|
||||
let value = match (
|
||||
Number::try_from((a1, &self.machine_st.arena.f64_tbl)),
|
||||
Number::try_from((a2, &self.machine_st.arena.f64_tbl)),
|
||||
) {
|
||||
(Ok(Number::Fixnum(lower)), Ok(Number::Fixnum(upper))) => {
|
||||
let (lower, upper) = (lower.get_num(), upper.get_num());
|
||||
if lower >= upper {
|
||||
@@ -4390,7 +4397,7 @@ impl Machine {
|
||||
let stub_gen = || functor_stub(atom!("length"), 2);
|
||||
let len = self.deref_register(2);
|
||||
|
||||
let n = match Number::try_from(len) {
|
||||
let n = match Number::try_from((len, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => n.get_num() as usize,
|
||||
Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
|
||||
Ok(n) => n,
|
||||
@@ -4581,7 +4588,8 @@ impl Machine {
|
||||
let tls_cert = self.deref_register(4);
|
||||
let content_length_limit = self.deref_register(5);
|
||||
const CONTENT_LENGTH_LIMIT_DEFAULT: u64 = 32768;
|
||||
let content_length_limit = match Number::try_from(content_length_limit) {
|
||||
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
|
||||
@@ -4864,7 +4872,8 @@ impl Machine {
|
||||
pub(crate) fn http_answer(&mut self) -> CallResult {
|
||||
let culprit = self.deref_register(1);
|
||||
let status_code = self.deref_register(2);
|
||||
let status_code: u16 = match Number::try_from(status_code) {
|
||||
let status_code: u16 = match Number::try_from((status_code, &self.machine_st.arena.f64_tbl))
|
||||
{
|
||||
Ok(Number::Fixnum(n)) => n.get_num() as u16,
|
||||
Ok(Number::Integer(n)) => {
|
||||
let n: Result<u16, _> = (&*n).try_into();
|
||||
@@ -4994,7 +5003,7 @@ impl Machine {
|
||||
if let Some(function_name) = self.machine_st.value_to_str_like(function_name) {
|
||||
let stub_gen = || functor_stub(atom!("foreign_call"), 3);
|
||||
fn map_arg(machine_st: &mut MachineState, source: HeapCellValue) -> crate::ffi::Value {
|
||||
match Number::try_from(source) {
|
||||
match Number::try_from((source, &machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => Value::Int(n.get_num()),
|
||||
Ok(Number::Float(n)) => Value::Float(n.into_inner()),
|
||||
_ => {
|
||||
@@ -5297,7 +5306,7 @@ impl Machine {
|
||||
let priority = self.deref_register(1);
|
||||
let specifier = cell_as_atom_cell!(self.deref_register(2)).get_name();
|
||||
|
||||
let priority = match Number::try_from(priority) {
|
||||
let priority = match Number::try_from((priority, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(n)) => {
|
||||
let n: u16 = (&*n).try_into().unwrap();
|
||||
n
|
||||
@@ -5465,7 +5474,7 @@ impl Machine {
|
||||
pub(crate) fn get_attr_var_queue_beyond(&mut self) {
|
||||
let addr = self.deref_register(1);
|
||||
|
||||
let b = match Number::try_from(addr) {
|
||||
let b = match Number::try_from((addr, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Integer(n)) => {
|
||||
let value: usize = (&*n).try_into().unwrap();
|
||||
Some(value)
|
||||
@@ -5892,7 +5901,7 @@ impl Machine {
|
||||
pub(crate) fn halt(&mut self) -> std::process::ExitCode {
|
||||
let code = self.deref_register(1);
|
||||
|
||||
let code = match Number::try_from(code) {
|
||||
let code = match Number::try_from((code, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => u8::try_from(n.get_num()).unwrap(),
|
||||
Ok(Number::Integer(n)) => {
|
||||
let n: u8 = (&*n).try_into().unwrap();
|
||||
@@ -5929,7 +5938,7 @@ impl Machine {
|
||||
let a1 = self.deref_register(1);
|
||||
let a2 = self.deref_register(2);
|
||||
|
||||
let n = match Number::try_from(a2) {
|
||||
let n = match Number::try_from((a2, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(bp)) => Integer::from(bp.get_num() as usize),
|
||||
Ok(Number::Integer(n)) => (*n).clone(),
|
||||
_ => {
|
||||
@@ -5974,7 +5983,7 @@ impl Machine {
|
||||
let name = cell_as_atom!(self.deref_register(2));
|
||||
let a3 = self.deref_register(3);
|
||||
|
||||
let arity = match Number::try_from(a3) {
|
||||
let arity = match Number::try_from((a3, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => n.get_num() as usize,
|
||||
Ok(Number::Integer(n)) => {
|
||||
let result = (&*n).try_into();
|
||||
@@ -5992,7 +6001,14 @@ impl Machine {
|
||||
|
||||
self.indices
|
||||
.get_predicate_code_index(name, arity, module_name)
|
||||
.map(|index| index.local().is_some())
|
||||
.map(|idx| {
|
||||
self.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup(idx.into())
|
||||
.local()
|
||||
.is_some()
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
@@ -6014,7 +6030,10 @@ impl Machine {
|
||||
arity,
|
||||
module_name,
|
||||
)
|
||||
.map(|index| index.get())
|
||||
.map(|idx| *self.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup(idx.into()))
|
||||
.unwrap_or(IndexPtr::dynamic_undefined());
|
||||
|
||||
!matches!(index.tag(), IndexPtrTag::DynamicUndefined | IndexPtrTag::Undefined)
|
||||
@@ -6031,7 +6050,10 @@ impl Machine {
|
||||
0,
|
||||
module_name,
|
||||
)
|
||||
.map(|index| index.get())
|
||||
.map(|idx| *self.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup(idx.into()))
|
||||
.unwrap_or(IndexPtr::dynamic_undefined());
|
||||
|
||||
!matches!(index.tag(), IndexPtrTag::DynamicUndefined)
|
||||
@@ -6667,7 +6689,7 @@ impl Machine {
|
||||
pub(crate) fn set_seed(&mut self) {
|
||||
let seed = self.deref_register(1);
|
||||
|
||||
match Number::try_from(seed) {
|
||||
match Number::try_from((seed, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => {
|
||||
let n: u64 = Integer::from(n).try_into().unwrap();
|
||||
let rng: StdRng = SeedableRng::seed_from_u64(n);
|
||||
@@ -6695,7 +6717,7 @@ impl Machine {
|
||||
pub(crate) fn sleep(&mut self) {
|
||||
let time = self.deref_register(1);
|
||||
|
||||
let time = match Number::try_from(time) {
|
||||
let time = match Number::try_from((time, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Float(n)) => n.into_inner(),
|
||||
Ok(Number::Fixnum(n)) => n.get_num() as f64,
|
||||
Ok(Number::Integer(n)) => n.to_f64().value(),
|
||||
@@ -6730,7 +6752,7 @@ impl Machine {
|
||||
name
|
||||
}
|
||||
_ => {
|
||||
AtomTable::build_with(&self.machine_st.atom_tbl, &match Number::try_from(port) {
|
||||
AtomTable::build_with(&self.machine_st.atom_tbl, &match Number::try_from((port, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => n.get_num().to_string(),
|
||||
Ok(Number::Integer(n)) => n.to_string(),
|
||||
_ => {
|
||||
@@ -6829,7 +6851,7 @@ impl Machine {
|
||||
let port = if port.is_var() {
|
||||
String::from("0")
|
||||
} else {
|
||||
match Number::try_from(port) {
|
||||
match Number::try_from((port, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => n.get_num().to_string(),
|
||||
Ok(Number::Integer(n)) => n.to_string(),
|
||||
_ => {
|
||||
@@ -7107,7 +7129,7 @@ impl Machine {
|
||||
|
||||
let position = self.deref_register(2);
|
||||
|
||||
let position = match Number::try_from(position) {
|
||||
let position = match Number::try_from((position, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => n.get_num() as u64,
|
||||
Ok(Number::Integer(n)) => {
|
||||
let n: Result<u64, _> = (&*n).try_into();
|
||||
@@ -7426,7 +7448,7 @@ impl Machine {
|
||||
let name = cell_as_atom!(self.deref_register(2));
|
||||
let arity = self.deref_register(3);
|
||||
|
||||
let arity = match Number::try_from(arity) {
|
||||
let arity = match Number::try_from((arity, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => n.get_num() as usize,
|
||||
Ok(Number::Integer(n)) => {
|
||||
let value: usize = (&*n).try_into().unwrap();
|
||||
@@ -7454,22 +7476,23 @@ impl Machine {
|
||||
},
|
||||
};
|
||||
|
||||
let first_idx = match first_idx {
|
||||
Some(idx) if idx.local().is_some() => {
|
||||
if let Some(idx) = idx.local() {
|
||||
let first_idx = first_idx.and_then(|first_idx| {
|
||||
self.machine_st
|
||||
.arena
|
||||
.code_index_tbl
|
||||
.lookup(first_idx.into())
|
||||
.local()
|
||||
});
|
||||
|
||||
let first_idx = if let Some(idx) = first_idx {
|
||||
idx
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let stub = functor_stub(name, arity);
|
||||
let err = self
|
||||
.machine_st
|
||||
.existence_error(ExistenceError::Procedure(name, arity));
|
||||
|
||||
return Err(self.machine_st.error_form(err, stub));
|
||||
}
|
||||
};
|
||||
|
||||
let listing =
|
||||
@@ -7484,7 +7507,7 @@ impl Machine {
|
||||
#[inline(always)]
|
||||
pub(crate) fn inlined_instructions(&mut self) {
|
||||
let index_ptr = self.deref_register(1);
|
||||
let index_ptr = match Number::try_from(index_ptr) {
|
||||
let index_ptr = match Number::try_from((index_ptr, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => n.get_num() as usize,
|
||||
Ok(Number::Integer(n)) => {
|
||||
let value: usize = (&*n).try_into().unwrap();
|
||||
@@ -7843,7 +7866,7 @@ impl Machine {
|
||||
|
||||
let length = self.deref_register(6);
|
||||
|
||||
let length = match Number::try_from(length) {
|
||||
let length = match Number::try_from((length, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
|
||||
Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
|
||||
Ok(u) => u,
|
||||
@@ -7909,7 +7932,7 @@ impl Machine {
|
||||
|
||||
let iterations = self.deref_register(3);
|
||||
|
||||
let iterations = match Number::try_from(iterations) {
|
||||
let iterations = match Number::try_from((iterations, &self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Fixnum(n)) => u64::try_from(n.get_num()).unwrap(),
|
||||
Ok(Number::Integer(n)) => {
|
||||
let n: Result<u64, _> = (&*n).try_into();
|
||||
@@ -8555,7 +8578,10 @@ impl Machine {
|
||||
#[inline(always)]
|
||||
pub(crate) fn pop_count(&mut self) {
|
||||
let number = self.deref_register(1);
|
||||
let pop_count = integer_as_cell!(match Number::try_from(number) {
|
||||
let pop_count = integer_as_cell!(match Number::try_from((
|
||||
number,
|
||||
&self.machine_st.arena.f64_tbl
|
||||
)) {
|
||||
Ok(Number::Fixnum(n)) => {
|
||||
Number::Fixnum(Fixnum::build_with(n.get_num().count_ones()))
|
||||
}
|
||||
|
||||
@@ -216,7 +216,9 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
|
||||
return;
|
||||
}
|
||||
|
||||
match Number::try_from(value) {
|
||||
let machine_st = self.deref();
|
||||
|
||||
match Number::try_from((value, &machine_st.arena.f64_tbl)) {
|
||||
Ok(n2) => match n2 {
|
||||
Number::Fixnum(n2) if n1.get_num() == n2.get_num() => {}
|
||||
Number::Integer(n2) if (*n2).num_eq(&n1.get_num()) => {}
|
||||
@@ -237,7 +239,9 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
|
||||
return;
|
||||
}
|
||||
|
||||
match Number::try_from(value) {
|
||||
let machine_st = self.deref();
|
||||
|
||||
match Number::try_from((value, &machine_st.arena.f64_tbl)) {
|
||||
Ok(n2) => match n2 {
|
||||
Number::Fixnum(n2) if (*n1).num_eq(&n2.get_num()) => {}
|
||||
Number::Integer(n2) if (*n1).num_eq(&*n2) => {}
|
||||
@@ -258,7 +262,9 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
|
||||
return;
|
||||
}
|
||||
|
||||
match Number::try_from(value) {
|
||||
let machine_st = self.deref_mut();
|
||||
|
||||
match Number::try_from((value, &machine_st.arena.f64_tbl)) {
|
||||
Ok(n2) => match n2 {
|
||||
Number::Fixnum(n2) if (*n1).num_eq(&Integer::from(n2.get_num())) => {}
|
||||
Number::Integer(n2) if (*n1).num_eq(&*n2) => {}
|
||||
@@ -273,14 +279,19 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
|
||||
}
|
||||
}
|
||||
|
||||
fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
|
||||
fn unify_f64(&mut self, f1: F64Offset, value: HeapCellValue) {
|
||||
if let Some(r) = value.as_var() {
|
||||
Self::bind(self, r, HeapCellValue::from(f1));
|
||||
return;
|
||||
}
|
||||
|
||||
read_heap_cell!(value,
|
||||
(HeapCellValueTag::F64, f2) => {
|
||||
(HeapCellValueTag::F64Offset, f2) => {
|
||||
let machine_st = self.deref_mut();
|
||||
|
||||
let f1 = machine_st.arena.f64_tbl.lookup(f1);
|
||||
let f2 = machine_st.arena.f64_tbl.lookup(f2.into());
|
||||
|
||||
self.fail = **f1 != **f2;
|
||||
}
|
||||
_ => {
|
||||
@@ -414,17 +425,12 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
|
||||
tabu_list.insert((d1, d2));
|
||||
}
|
||||
}
|
||||
(HeapCellValueTag::F64, f1) => {
|
||||
(HeapCellValueTag::F64Offset, f1) => {
|
||||
Self::unify_f64(self, f1, d2);
|
||||
}
|
||||
(HeapCellValueTag::Fixnum, n1) => {
|
||||
Self::unify_fixnum(self, n1, d2);
|
||||
}
|
||||
/*
|
||||
(HeapCellValueTag::Char, c1) => {
|
||||
Self::unify_char(self, c1, d2);
|
||||
}
|
||||
*/
|
||||
(HeapCellValueTag::Cons, ptr_1) => {
|
||||
Self::unify_constant(self, ptr_1, d2);
|
||||
}
|
||||
|
||||
@@ -53,17 +53,17 @@ macro_rules! cell_as_atom_cell {
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! cell_as_f64_ptr {
|
||||
macro_rules! cell_as_f64_offset {
|
||||
($cell:expr) => {{
|
||||
let offset = $cell.get_value() as usize;
|
||||
F64Ptr::from_offset(F64Offset::from(offset))
|
||||
F64Offset::from(offset)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! cell_as_code_index {
|
||||
macro_rules! cell_as_code_index_offset {
|
||||
($cell:expr) => {{
|
||||
let offset = $cell.get_value() as usize;
|
||||
CodeIndex::from(CodeIndexOffset::from(offset))
|
||||
CodeIndexOffset::from(offset)
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -266,13 +266,13 @@ macro_rules! read_heap_cell_pat_body {
|
||||
#[allow(unused_braces)]
|
||||
$code
|
||||
}};
|
||||
($cell:ident, F64, $n:ident, $code:expr) => {{
|
||||
let $n = cell_as_f64_ptr!($cell);
|
||||
($cell:ident, F64Offset, $n:ident, $code:expr) => {{
|
||||
let $n = cell_as_f64_offset!($cell);
|
||||
#[allow(unused_braces)]
|
||||
$code
|
||||
}};
|
||||
($cell:ident, CodeIndex, $n:ident, $code:expr) => {{
|
||||
let $n = cell_as_code_index!($cell);
|
||||
($cell:ident, CodeIndexOffset, $n:ident, $code:expr) => {{
|
||||
let $n = cell_as_code_index_offset!($cell);
|
||||
#[allow(unused_braces)]
|
||||
$code
|
||||
}};
|
||||
@@ -281,26 +281,6 @@ macro_rules! read_heap_cell_pat_body {
|
||||
#[allow(unused_braces)]
|
||||
$code
|
||||
}};
|
||||
($cell:ident, PStr, $atom:ident, $code:expr) => {{
|
||||
let $atom = cell_as_atom!($cell);
|
||||
#[allow(unused_braces)]
|
||||
$code
|
||||
}};
|
||||
($cell:ident, CStr, $atom:ident, $code:expr) => {{
|
||||
let $atom = cell_as_atom!($cell);
|
||||
#[allow(unused_braces)]
|
||||
$code
|
||||
}};
|
||||
($cell:ident, CStr | PStr, $atom:ident, $code:expr) => {{
|
||||
let $atom = cell_as_atom!($cell);
|
||||
#[allow(unused_braces)]
|
||||
$code
|
||||
}};
|
||||
($cell:ident, PStr | CStr, $atom:ident, $code:expr) => {{
|
||||
let $atom = cell_as_atom!($cell);
|
||||
#[allow(unused_braces)]
|
||||
$code
|
||||
}};
|
||||
($cell:ident, Fixnum, $value:ident, $code:expr) => {{
|
||||
let $value = Fixnum::from_bytes($cell.into_bytes());
|
||||
#[allow(unused_braces)]
|
||||
@@ -321,11 +301,6 @@ macro_rules! read_heap_cell_pat_body {
|
||||
#[allow(unused_braces)]
|
||||
$code
|
||||
}};
|
||||
($cell:ident, Char, $value:ident, $code:expr) => {{
|
||||
let $value = unsafe { char::from_u32_unchecked($cell.get_value() as u32) };
|
||||
#[allow(unused_braces)]
|
||||
$code
|
||||
}};
|
||||
($cell:ident, $($tags:tt)|+, $value:ident, $code:expr) => {{
|
||||
let $value = $cell.get_value() as usize;
|
||||
#[allow(unused_braces)]
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use std::cell::UnsafeCell;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::RwLock;
|
||||
use std::sync::Weak;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{fmt, mem, ptr};
|
||||
|
||||
@@ -23,19 +21,7 @@ const F64_TABLE_ALIGN: usize = 8;
|
||||
const CODE_INDEX_TABLE_INIT_SIZE: usize = 1 << 16;
|
||||
const CODE_INDEX_TABLE_ALIGN: usize = 8;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OffsetTableImpl<T>
|
||||
where
|
||||
OffsetTableImpl<T>: RawBlockTraits,
|
||||
{
|
||||
block: Arcu<RawBlock<OffsetTableImpl<T>>, GlobalEpochCounterPool>,
|
||||
update: Mutex<()>,
|
||||
}
|
||||
|
||||
pub type F64Table = OffsetTableImpl<OrderedFloat<f64>>;
|
||||
pub type CodeIndexTable = OffsetTableImpl<IndexPtr>;
|
||||
|
||||
impl RawBlockTraits for F64Table {
|
||||
impl RawBlockTraits for OrderedFloat<f64> {
|
||||
#[inline]
|
||||
fn init_size() -> usize {
|
||||
F64_TABLE_INIT_SIZE
|
||||
@@ -47,7 +33,7 @@ impl RawBlockTraits for F64Table {
|
||||
}
|
||||
}
|
||||
|
||||
impl RawBlockTraits for CodeIndexTable {
|
||||
impl RawBlockTraits for IndexPtr {
|
||||
#[inline]
|
||||
fn init_size() -> usize {
|
||||
CODE_INDEX_TABLE_INIT_SIZE
|
||||
@@ -59,72 +45,159 @@ impl RawBlockTraits for CodeIndexTable {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait OffsetTable: RawBlockTraits {
|
||||
type Offset: Copy + From<usize> + Into<usize>;
|
||||
type Stored;
|
||||
#[derive(Debug)]
|
||||
pub struct OffsetTableImpl<T: RawBlockTraits>(InnerOffsetTableImpl<T>);
|
||||
|
||||
fn global_table() -> &'static RwLock<Weak<Self>>;
|
||||
impl<T: RawBlockTraits> OffsetTableImpl<T> {
|
||||
#[inline(always)]
|
||||
pub fn new() -> Self {
|
||||
Self(InnerOffsetTableImpl::Serial(SerialOffsetTable::new()))
|
||||
}
|
||||
}
|
||||
|
||||
impl OffsetTable for F64Table {
|
||||
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 lookup<'a>(&'a self, offset: usize) -> TablePtr<'a, T> {
|
||||
match self {
|
||||
Self::Concurrent(concurrent_tbl) => {
|
||||
TablePtr(InnerTablePtr::Concurrent(concurrent_tbl.lookup(offset)))
|
||||
}
|
||||
Self::Serial(serial_tbl) => unsafe {
|
||||
TablePtr(InnerTablePtr::Serial(serial_tbl.lookup(offset)))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn lookup_mut<'a>(&'a mut self, offset: usize) -> TablePtrMut<'a, T> {
|
||||
match self {
|
||||
Self::Concurrent(concurrent_tbl) => TablePtrMut(InnerTablePtrMut::Concurrent(
|
||||
concurrent_tbl.lookup_mut(offset),
|
||||
)),
|
||||
Self::Serial(serial_tbl) => unsafe {
|
||||
TablePtrMut(InnerTablePtrMut::Serial(serial_tbl.lookup_mut(offset)))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait OffsetTable<T: RawBlockTraits> {
|
||||
type Offset: Copy + Into<usize>;
|
||||
|
||||
fn build_with(&mut self, value: T) -> Self::Offset;
|
||||
fn lookup<'a>(&'a self, offset: Self::Offset) -> TablePtr<'a, T>;
|
||||
fn lookup_mut<'a>(&'a mut self, offset: Self::Offset) -> TablePtrMut<'a, T>;
|
||||
}
|
||||
|
||||
impl OffsetTable<OrderedFloat<f64>> for OffsetTableImpl<OrderedFloat<f64>> {
|
||||
type Offset = F64Offset;
|
||||
type Stored = OrderedFloat<f64>;
|
||||
|
||||
#[inline(always)]
|
||||
fn global_table() -> &'static RwLock<Weak<Self>> {
|
||||
static GLOBAL_ATOM_TABLE: RwLock<Weak<F64Table>> = RwLock::new(Weak::new());
|
||||
&GLOBAL_ATOM_TABLE
|
||||
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 for CodeIndexTable {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static> OffsetTableImpl<T>
|
||||
where
|
||||
OffsetTableImpl<T>: OffsetTable<Stored = T>,
|
||||
{
|
||||
#[derive(Debug)]
|
||||
struct SerialOffsetTable<T: RawBlockTraits> {
|
||||
block: RawBlock<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
|
||||
} else {
|
||||
let table = Arc::new(Self {
|
||||
block: Arcu::new(RawBlock::new(), GlobalEpochCounterPool),
|
||||
update: Mutex::new(()),
|
||||
});
|
||||
*guard = Arc::downgrade(&table);
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ptr::write(ptr as *mut T, value);
|
||||
ptr.addr() - self.block.base.addr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn lookup(&self, offset: usize) -> &T {
|
||||
&*self.block.base.add(offset).cast::<T>()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn lookup_mut(&mut self, offset: usize) -> &mut T {
|
||||
&mut *self.block.base.add(offset).cast::<T>().cast_mut()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConcurrentOffsetTable<T: RawBlockTraits> {
|
||||
block: Arcu<RawBlock<T>, GlobalEpochCounterPool>,
|
||||
update: Mutex<()>,
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> ConcurrentOffsetTable<T> {
|
||||
#[allow(clippy::missing_safety_doc)]
|
||||
pub unsafe fn build_with(
|
||||
&self,
|
||||
value: <OffsetTableImpl<T> as OffsetTable>::Stored,
|
||||
) -> <OffsetTableImpl<T> as OffsetTable>::Offset {
|
||||
unsafe fn build_with(&self, value: T) -> usize {
|
||||
let update_guard = self.update.lock();
|
||||
|
||||
// we don't have an index table for lookups as AtomTable does so
|
||||
// just get the epoch after we take the upgrade lock
|
||||
let mut block_epoch = self.block.read();
|
||||
|
||||
let mut ptr;
|
||||
|
||||
loop {
|
||||
@@ -141,8 +214,7 @@ where
|
||||
|
||||
ptr::write(ptr as *mut T, value);
|
||||
|
||||
let value =
|
||||
<OffsetTableImpl<T> as OffsetTable>::Offset::from(ptr.addr() - block_epoch.base.addr());
|
||||
let value = ptr.addr() - block_epoch.base.addr();
|
||||
|
||||
// AtomTable would have to update the index table at this point
|
||||
// explicit drop to ensure we don't accidentally drop it early
|
||||
@@ -151,17 +223,20 @@ where
|
||||
value
|
||||
}
|
||||
|
||||
pub fn lookup(offset: <Self as OffsetTable>::Offset) -> RcuRef<RawBlock<Self>, UnsafeCell<T>> {
|
||||
let table = Self::global_table()
|
||||
.read()
|
||||
.unwrap()
|
||||
.upgrade()
|
||||
.expect("We should only be looking up entries when there is a table");
|
||||
#[inline]
|
||||
fn lookup(&self, offset: usize) -> RcuRef<RawBlock<T>, T> {
|
||||
RcuRef::try_map(self.block.read(), |raw_block| unsafe {
|
||||
raw_block.base.add(offset).cast::<T>().as_ref()
|
||||
})
|
||||
.expect("The offset should result in a non-null pointer")
|
||||
}
|
||||
|
||||
RcuRef::try_map(table.block.read(), |raw_block| unsafe {
|
||||
#[inline]
|
||||
fn lookup_mut(&self, offset: usize) -> RcuRef<RawBlock<T>, UnsafeCell<T>> {
|
||||
RcuRef::try_map(self.block.read(), |raw_block| unsafe {
|
||||
raw_block
|
||||
.base
|
||||
.add(offset.into())
|
||||
.add(offset)
|
||||
.cast_mut()
|
||||
.cast::<UnsafeCell<T>>()
|
||||
.as_ref()
|
||||
@@ -170,109 +245,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TablePtr<T>(RcuRef<RawBlock<OffsetTableImpl<T>>, UnsafeCell<T>>)
|
||||
where
|
||||
OffsetTableImpl<T>: RawBlockTraits;
|
||||
|
||||
pub type CodeIndexPtr = TablePtr<IndexPtr>;
|
||||
pub type F64Ptr = TablePtr<OrderedFloat<f64>>;
|
||||
|
||||
impl<T> Clone for TablePtr<T>
|
||||
where
|
||||
OffsetTableImpl<T>: RawBlockTraits,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self(RcuRef::clone(&self.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PartialEq> PartialEq for TablePtr<T>
|
||||
where
|
||||
OffsetTableImpl<T>: RawBlockTraits,
|
||||
{
|
||||
fn eq(&self, other: &TablePtr<T>) -> bool {
|
||||
RcuRef::ptr_eq(&self.0, &other.0) || self.deref() == other.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Eq> Eq for TablePtr<T> where OffsetTableImpl<T>: RawBlockTraits {}
|
||||
|
||||
impl<T: PartialOrd + Ord> PartialOrd for TablePtr<T>
|
||||
where
|
||||
OffsetTableImpl<T>: RawBlockTraits,
|
||||
{
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Ord> Ord for TablePtr<T>
|
||||
where
|
||||
OffsetTableImpl<T>: RawBlockTraits,
|
||||
{
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
(**self).cmp(&**other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Hash> Hash for TablePtr<T>
|
||||
where
|
||||
OffsetTableImpl<T>: RawBlockTraits,
|
||||
{
|
||||
#[inline(always)]
|
||||
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||
(self as &T).hash(hasher)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display> fmt::Display for TablePtr<T>
|
||||
where
|
||||
OffsetTableImpl<T>: RawBlockTraits,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self as &T)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for TablePtr<T>
|
||||
where
|
||||
OffsetTableImpl<T>: RawBlockTraits,
|
||||
{
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { self.0.get().as_ref().unwrap() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for TablePtr<T>
|
||||
where
|
||||
OffsetTableImpl<T>: RawBlockTraits,
|
||||
{
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
unsafe { &mut *self.0.get().as_mut().unwrap() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static> TablePtr<T>
|
||||
where
|
||||
OffsetTableImpl<T>: OffsetTable<Stored = T>,
|
||||
{
|
||||
#[inline(always)]
|
||||
pub fn from_offset(offset: <OffsetTableImpl<T> as OffsetTable>::Offset) -> Self {
|
||||
Self(OffsetTableImpl::<T>::lookup(offset))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_offset(&self) -> <OffsetTableImpl<T> as OffsetTable>::Offset {
|
||||
<OffsetTableImpl<T> as OffsetTable>::Offset::from(
|
||||
self.0.get().addr() - RcuRef::get_root(&self.0).base.addr(),
|
||||
)
|
||||
}
|
||||
}
|
||||
pub type F64Table = OffsetTableImpl<OrderedFloat<f64>>;
|
||||
pub type CodeIndexTable = OffsetTableImpl<IndexPtr>;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct F64Offset(usize);
|
||||
@@ -284,10 +258,9 @@ impl From<usize> for F64Offset {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<usize> for F64Offset {
|
||||
#[inline(always)]
|
||||
fn into(self: Self) -> usize {
|
||||
self.0
|
||||
impl From<F64Offset> for usize {
|
||||
fn from(val: F64Offset) -> Self {
|
||||
val.0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,57 +274,71 @@ impl From<usize> for CodeIndexOffset {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<usize> for CodeIndexOffset {
|
||||
impl From<CodeIndexOffset> for usize {
|
||||
#[inline(always)]
|
||||
fn into(self: Self) -> usize {
|
||||
self.0
|
||||
fn from(val: CodeIndexOffset) -> Self {
|
||||
val.0
|
||||
}
|
||||
}
|
||||
|
||||
impl CodeIndexOffset {
|
||||
#[inline(always)]
|
||||
pub fn from_ptr(ptr: CodeIndexPtr) -> Self {
|
||||
ptr.as_offset()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_ptr(self) -> CodeIndexPtr {
|
||||
CodeIndexPtr::from_offset(self)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_u64(self) -> u64 {
|
||||
self.0 as u64
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for CodeIndexOffset {
|
||||
#[inline(always)]
|
||||
fn eq(&self, other: &CodeIndexOffset) -> bool {
|
||||
self.as_ptr() == other.as_ptr()
|
||||
#[derive(Debug)]
|
||||
pub struct TablePtr<'a, T: RawBlockTraits>(InnerTablePtr<'a, T>);
|
||||
|
||||
#[derive(Debug)]
|
||||
enum InnerTablePtr<'a, T: RawBlockTraits> {
|
||||
Concurrent(RcuRef<RawBlock<T>, T>),
|
||||
Serial(&'a T),
|
||||
}
|
||||
|
||||
impl<T: PartialEq + RawBlockTraits> PartialEq for TablePtr<'_, T> {
|
||||
fn eq(&self, other: &TablePtr<'_, T>) -> bool {
|
||||
self.deref() == other.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for CodeIndexOffset {}
|
||||
impl<T: Eq + RawBlockTraits> Eq for TablePtr<'_, T> {}
|
||||
|
||||
impl PartialOrd for CodeIndexOffset {
|
||||
#[inline(always)]
|
||||
impl<T: PartialOrd + Ord + RawBlockTraits> PartialOrd for TablePtr<'_, T> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for CodeIndexOffset {
|
||||
#[inline(always)]
|
||||
impl<T: Ord + RawBlockTraits> Ord for TablePtr<'_, T> {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.as_ptr().cmp(&other.as_ptr())
|
||||
(**self).cmp(&**other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for CodeIndexOffset {
|
||||
impl<T: Hash + RawBlockTraits> Hash for TablePtr<'_, T> {
|
||||
#[inline(always)]
|
||||
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||
self.as_ptr().hash(hasher)
|
||||
(self as &T).hash(hasher)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display + RawBlockTraits> fmt::Display for TablePtr<'_, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self as &T)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> Deref for TablePtr<'_, T> {
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match &self.0 {
|
||||
InnerTablePtr::Concurrent(rcu_ref) => rcu_ref,
|
||||
InnerTablePtr::Serial(ref_mut) => ref_mut,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,67 +348,103 @@ impl fmt::Display for CodeIndexOffset {
|
||||
}
|
||||
}
|
||||
|
||||
impl CodeIndexPtr {
|
||||
#[inline]
|
||||
pub fn set(&self, val: IndexPtr) {
|
||||
unsafe { *self.0.get() = val };
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn replace(&self, val: IndexPtr) -> IndexPtr {
|
||||
unsafe { self.0.get().replace(val) }
|
||||
}
|
||||
}
|
||||
|
||||
impl F64Offset {
|
||||
#[inline(always)]
|
||||
pub fn from_ptr(ptr: F64Ptr) -> Self {
|
||||
ptr.as_offset()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_ptr(self) -> F64Ptr {
|
||||
F64Ptr::from_offset(self)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_u64(self) -> u64 {
|
||||
self.0 as u64
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for F64Offset {
|
||||
#[inline(always)]
|
||||
fn eq(&self, other: &F64Offset) -> bool {
|
||||
self.as_ptr() == other.as_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for F64Offset {}
|
||||
|
||||
impl PartialOrd for F64Offset {
|
||||
#[inline(always)]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for F64Offset {
|
||||
#[inline(always)]
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.as_ptr().cmp(&other.as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for F64Offset {
|
||||
#[inline(always)]
|
||||
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||
self.as_ptr().hash(hasher)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for F64Offset {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "F64Offset({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TablePtrMut<'a, T: RawBlockTraits>(InnerTablePtrMut<'a, T>);
|
||||
|
||||
#[derive(Debug)]
|
||||
enum InnerTablePtrMut<'a, T: RawBlockTraits> {
|
||||
Concurrent(RcuRef<RawBlock<T>, UnsafeCell<T>>),
|
||||
Serial(&'a mut T),
|
||||
}
|
||||
|
||||
impl<T: PartialEq + RawBlockTraits> PartialEq for TablePtrMut<'_, T> {
|
||||
fn eq(&self, other: &TablePtrMut<'_, T>) -> bool {
|
||||
self.deref() == other.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Eq + RawBlockTraits> Eq for TablePtrMut<'_, T> {}
|
||||
|
||||
impl<T: PartialOrd + Ord + RawBlockTraits> PartialOrd for TablePtrMut<'_, T> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Ord + RawBlockTraits> Ord for TablePtrMut<'_, T> {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
(**self).cmp(&**other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Hash + RawBlockTraits> Hash for TablePtrMut<'_, T> {
|
||||
#[inline(always)]
|
||||
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||
(self as &T).hash(hasher)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display + RawBlockTraits> fmt::Display for TablePtrMut<'_, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self as &T)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> Deref for TablePtrMut<'_, T> {
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match &self.0 {
|
||||
InnerTablePtrMut::Concurrent(rcu_ref) => unsafe { rcu_ref.get().as_ref().unwrap() },
|
||||
InnerTablePtrMut::Serial(ref_mut) => ref_mut,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> DerefMut for TablePtrMut<'_, T> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
match &mut self.0 {
|
||||
InnerTablePtrMut::Concurrent(rcu_ref) => unsafe {
|
||||
&mut *rcu_ref.get().as_mut().unwrap()
|
||||
},
|
||||
InnerTablePtrMut::Serial(ref_mut) => ref_mut,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TablePtrMut<'_, IndexPtr> {
|
||||
#[inline]
|
||||
pub fn set(&mut self, val: IndexPtr) {
|
||||
match &mut self.0 {
|
||||
InnerTablePtrMut::Concurrent(rcu_ref) => unsafe {
|
||||
*rcu_ref.get() = val;
|
||||
},
|
||||
InnerTablePtrMut::Serial(ref_mut) => {
|
||||
**ref_mut = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn replace(&mut self, val: IndexPtr) -> IndexPtr {
|
||||
match &mut self.0 {
|
||||
InnerTablePtrMut::Concurrent(rcu_ref) => unsafe { rcu_ref.get().replace(val) },
|
||||
InnerTablePtrMut::Serial(ref_mut) => mem::replace(*ref_mut, val),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::machine::machine_indices::CodeIndex;
|
||||
use crate::offset_table::*;
|
||||
use crate::parser::char_reader::*;
|
||||
use crate::types::HeapCellValueTag;
|
||||
@@ -698,17 +697,18 @@ impl Not for Fixnum {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Literal {
|
||||
Atom(Atom),
|
||||
CodeIndex(CodeIndex),
|
||||
CodeIndexOffset(CodeIndexOffset),
|
||||
Fixnum(Fixnum),
|
||||
Integer(TypedArenaPtr<Integer>),
|
||||
Rational(TypedArenaPtr<Rational>),
|
||||
Float(F64Offset),
|
||||
F64Offset(F64Offset),
|
||||
}
|
||||
|
||||
impl From<F64Ptr> for Literal {
|
||||
/*
|
||||
impl From<F64Ptr<'_>> for Literal {
|
||||
#[inline(always)]
|
||||
fn from(ptr: F64Ptr) -> Literal {
|
||||
Literal::Float(ptr.as_offset())
|
||||
@@ -721,14 +721,15 @@ impl fmt::Display for Literal {
|
||||
Literal::Atom(ref atom) => {
|
||||
write!(f, "{}", atom.flat_index())
|
||||
}
|
||||
Literal::CodeIndex(i) => write!(f, "{:?}", *i.as_ptr()),
|
||||
Literal::CodeIndexOffset(i) => write!(f, "{}", *i),
|
||||
Literal::Fixnum(n) => write!(f, "{}", n.get_num()),
|
||||
Literal::Integer(ref n) => write!(f, "{}", n),
|
||||
Literal::Rational(ref n) => write!(f, "{}", n),
|
||||
Literal::Float(ref n) => write!(f, "{}", *n),
|
||||
Literal::FloatOffset(ref n) => write!(f, "{}", *n),
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl Literal {
|
||||
pub fn as_atom(&self, atom_tbl: &Arc<AtomTable>) -> Option<Atom> {
|
||||
@@ -874,7 +875,7 @@ impl Term {
|
||||
|
||||
pub(crate) fn unfold_by_str_once(term: &mut Term, s: Atom) -> Option<(Term, Term)> {
|
||||
if let Term::Clause(_, ref name, ref mut subterms) = term {
|
||||
if let Some(Term::Literal(_, Literal::CodeIndex(_))) = subterms.last() {
|
||||
if let Some(Term::Literal(_, Literal::CodeIndexOffset(_))) = subterms.last() {
|
||||
subterms.pop();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
pub use crate::machine::machine_state::*;
|
||||
use crate::offset_table::F64Ptr;
|
||||
use crate::offset_table::*;
|
||||
use crate::parser::ast::*;
|
||||
use crate::parser::char_reader::*;
|
||||
use crate::parser::dashu::Integer;
|
||||
@@ -30,7 +30,7 @@ struct LayoutInfo {
|
||||
more: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug)]
|
||||
pub enum Token {
|
||||
Literal(Literal),
|
||||
Var(String),
|
||||
@@ -58,7 +58,7 @@ impl Token {
|
||||
enum Number {
|
||||
BigInt(TypedArenaPtr<Integer>),
|
||||
Fixnum(Fixnum),
|
||||
Float(F64Ptr),
|
||||
Float(F64Offset),
|
||||
}
|
||||
|
||||
impl Number {
|
||||
@@ -67,7 +67,7 @@ impl Number {
|
||||
match self {
|
||||
Number::BigInt(ibig) => Literal::Integer(ibig),
|
||||
Number::Fixnum(fixnum) => Literal::Fixnum(fixnum),
|
||||
Number::Float(f) => Literal::Float(f.as_offset()),
|
||||
Number::Float(f) => Literal::F64Offset(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -944,8 +944,8 @@ impl<'a, R: CharRead> Lexer<'a, R> {
|
||||
Ok(n) => Ok(Token::Literal(n.to_literal())),
|
||||
Err(_) => {
|
||||
let n = parse_float_lossy(&token_string)?;
|
||||
Ok(Token::Literal(Literal::Float(
|
||||
float_alloc!(n, self.machine_st.arena).as_offset(),
|
||||
Ok(Token::Literal(Literal::F64Offset(
|
||||
float_alloc!(n, self.machine_st.arena),
|
||||
)))
|
||||
}
|
||||
},
|
||||
|
||||
@@ -3,12 +3,11 @@ use dashu::Rational;
|
||||
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::offset_table::OffsetTable;
|
||||
use crate::parser::ast::*;
|
||||
use crate::parser::char_reader::*;
|
||||
use crate::parser::lexer::*;
|
||||
|
||||
use ordered_float::OrderedFloat;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::mem;
|
||||
use std::ops::Neg;
|
||||
@@ -963,17 +962,21 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
||||
Token::Literal(Literal::Rational(n)) => {
|
||||
self.negate_number(n, negate_rat_rc, |r, _| Literal::Rational(r))
|
||||
}
|
||||
Token::Literal(Literal::Float(n)) if n.as_ptr().is_infinite() => {
|
||||
Token::Literal(Literal::F64Offset(n)) if self.lexer.machine_st.arena.f64_tbl.lookup(n).is_infinite() => {
|
||||
return Err(ParserError::InfiniteFloat(
|
||||
self.lexer.line_num,
|
||||
self.lexer.col_num,
|
||||
));
|
||||
}
|
||||
Token::Literal(Literal::Float(n)) => self.negate_number(
|
||||
**n.as_ptr(),
|
||||
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::from(float_alloc!(n, arena)),
|
||||
),
|
||||
|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))
|
||||
}
|
||||
|
||||
98
src/types.rs
98
src/types.rs
@@ -30,9 +30,9 @@ pub enum HeapCellValueTag {
|
||||
PStrLoc = 0b010011,
|
||||
// constants.
|
||||
Cons = 0b0,
|
||||
F64 = 0b010101,
|
||||
F64Offset = 0b010101,
|
||||
Fixnum = 0b011001,
|
||||
CodeIndex = 0b011011,
|
||||
CodeIndexOffset = 0b011011,
|
||||
Atom = 0b011111,
|
||||
CutPoint = 0b011101,
|
||||
// trail elements.
|
||||
@@ -57,9 +57,9 @@ pub enum HeapCellValueView {
|
||||
PStrLoc = 0b010011,
|
||||
// constants.
|
||||
Cons = 0b0,
|
||||
F64 = 0b010101,
|
||||
F64Offset = 0b010101,
|
||||
Fixnum = 0b011001,
|
||||
CodeIndex = 0b011011,
|
||||
CodeIndexOffset = 0b011011,
|
||||
Atom = 0b011111,
|
||||
CutPoint = 0b011101,
|
||||
// trail elements.
|
||||
@@ -261,9 +261,9 @@ pub struct HeapCellValue {
|
||||
impl fmt::Debug for HeapCellValue {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> fmt::Result {
|
||||
match self.get_tag() {
|
||||
HeapCellValueTag::F64 => f
|
||||
HeapCellValueTag::F64Offset => f
|
||||
.debug_struct("HeapCellValue")
|
||||
.field("tag", &HeapCellValueTag::F64)
|
||||
.field("tag", &HeapCellValueTag::F64Offset)
|
||||
.field("offset", &self.get_value())
|
||||
.field("m", &self.m())
|
||||
.field("f", &self.f())
|
||||
@@ -289,18 +289,6 @@ impl fmt::Debug for HeapCellValue {
|
||||
.field("f", &self.f())
|
||||
.finish()
|
||||
}
|
||||
/*
|
||||
HeapCellValueTag::PStr => {
|
||||
let (name, _) = cell_as_atom_cell!(self).get_name_and_arity();
|
||||
|
||||
f.debug_struct("HeapCellValue")
|
||||
.field("tag", &HeapCellValueTag::PStr)
|
||||
.field("contents", &name.as_str())
|
||||
.field("m", &self.m())
|
||||
.field("f", &self.f())
|
||||
.finish()
|
||||
}
|
||||
*/
|
||||
tag => f
|
||||
.debug_struct("HeapCellValue")
|
||||
.field("tag", &tag)
|
||||
@@ -317,7 +305,7 @@ impl From<Literal> for HeapCellValue {
|
||||
fn from(literal: Literal) -> Self {
|
||||
match literal {
|
||||
Literal::Atom(name) => atom_as_cell!(name),
|
||||
Literal::CodeIndex(idx) => HeapCellValue::from(idx),
|
||||
Literal::CodeIndexOffset(idx) => HeapCellValue::from(idx),
|
||||
Literal::Fixnum(n) => fixnum_as_cell!(n),
|
||||
Literal::Integer(bigint_ptr) => {
|
||||
typed_arena_ptr_as_cell!(bigint_ptr)
|
||||
@@ -325,7 +313,7 @@ impl From<Literal> for HeapCellValue {
|
||||
Literal::Rational(bigint_ptr) => {
|
||||
typed_arena_ptr_as_cell!(bigint_ptr)
|
||||
}
|
||||
Literal::Float(f) => HeapCellValue::from(f.as_ptr()),
|
||||
Literal::F64Offset(f) => HeapCellValue::from(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -345,11 +333,11 @@ impl TryFrom<HeapCellValue> for Literal {
|
||||
(HeapCellValueTag::Fixnum, n) => {
|
||||
Ok(Literal::Fixnum(n))
|
||||
}
|
||||
(HeapCellValueTag::F64, f) => {
|
||||
Ok(Literal::Float(f.as_offset()))
|
||||
(HeapCellValueTag::F64Offset, f) => {
|
||||
Ok(Literal::F64Offset(f))
|
||||
}
|
||||
(HeapCellValueTag::CodeIndex, idx) => {
|
||||
Ok(Literal::CodeIndex(idx))
|
||||
(HeapCellValueTag::CodeIndexOffset, idx) => {
|
||||
Ok(Literal::CodeIndexOffset(idx))
|
||||
}
|
||||
(HeapCellValueTag::Cons, cons_ptr) => {
|
||||
match_untyped_arena_ptr!(cons_ptr,
|
||||
@@ -381,19 +369,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl From<F64Ptr> for HeapCellValue {
|
||||
impl From<F64Offset> for HeapCellValue {
|
||||
#[inline]
|
||||
fn from(f64_ptr: F64Ptr) -> HeapCellValue {
|
||||
HeapCellValue::build_with(HeapCellValueTag::F64, f64_ptr.as_offset().to_u64())
|
||||
fn from(f64_offset: F64Offset) -> HeapCellValue {
|
||||
HeapCellValue::build_with(HeapCellValueTag::F64Offset, f64_offset.to_u64())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CodeIndexPtr> for HeapCellValue {
|
||||
impl From<CodeIndexOffset> for HeapCellValue {
|
||||
#[inline]
|
||||
fn from(code_index_ptr: CodeIndexPtr) -> HeapCellValue {
|
||||
fn from(code_index_offset: CodeIndexOffset) -> HeapCellValue {
|
||||
HeapCellValue::build_with(
|
||||
HeapCellValueTag::CodeIndex,
|
||||
code_index_ptr.as_offset().to_u64(),
|
||||
HeapCellValueTag::CodeIndexOffset,
|
||||
code_index_offset.to_u64(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -472,7 +460,7 @@ impl HeapCellValue {
|
||||
| HeapCellValueTag::Var
|
||||
| HeapCellValueTag::StackVar
|
||||
| HeapCellValueTag::AttrVar
|
||||
| HeapCellValueTag::PStrLoc // | HeapCellValueTag::PStrOffset
|
||||
| HeapCellValueTag::PStrLoc
|
||||
)
|
||||
}
|
||||
|
||||
@@ -496,7 +484,7 @@ impl HeapCellValue {
|
||||
pub fn is_constant(self) -> bool {
|
||||
match self.get_tag() {
|
||||
HeapCellValueTag::Cons
|
||||
| HeapCellValueTag::F64
|
||||
| HeapCellValueTag::F64Offset
|
||||
| HeapCellValueTag::Fixnum
|
||||
| HeapCellValueTag::CutPoint => true,
|
||||
HeapCellValueTag::Atom => cell_as_atom_cell!(self).get_arity() == 0,
|
||||
@@ -661,28 +649,41 @@ impl HeapCellValue {
|
||||
}
|
||||
|
||||
pub fn order_category(self, heap: &Heap) -> Option<TermOrderCategory> {
|
||||
match Number::try_from(self).ok() {
|
||||
Some(Number::Integer(_)) | Some(Number::Fixnum(_)) | Some(Number::Rational(_)) => {
|
||||
read_heap_cell!(self,
|
||||
(HeapCellValueTag::Cons, c) => {
|
||||
match_untyped_arena_ptr!(c,
|
||||
(ArenaHeaderTag::Integer, _n) => {
|
||||
Some(TermOrderCategory::Integer)
|
||||
}
|
||||
Some(Number::Float(_)) => Some(TermOrderCategory::FloatingPoint),
|
||||
None => match self.get_tag() {
|
||||
HeapCellValueTag::Var | HeapCellValueTag::StackVar | HeapCellValueTag::AttrVar => {
|
||||
(ArenaHeaderTag::Rational, _n) => {
|
||||
Some(TermOrderCategory::Integer)
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
)
|
||||
}
|
||||
(HeapCellValueTag::F64Offset) => {
|
||||
Some(TermOrderCategory::FloatingPoint)
|
||||
}
|
||||
(HeapCellValueTag::Fixnum | HeapCellValueTag::CutPoint) => {
|
||||
Some(TermOrderCategory::Integer)
|
||||
}
|
||||
(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::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 => {
|
||||
let value = heap[self.get_value() as usize];
|
||||
let arity = cell_as_atom_cell!(value).get_arity();
|
||||
(HeapCellValueTag::Str, s) => {
|
||||
let arity = cell_as_atom_cell!(heap[s]).get_arity();
|
||||
|
||||
if arity == 0 {
|
||||
Some(TermOrderCategory::Atom)
|
||||
@@ -690,9 +691,10 @@ impl HeapCellValue {
|
||||
Some(TermOrderCategory::Compound)
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
||||
Reference in New Issue
Block a user