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