@@ -598,7 +598,7 @@ enum InstructionTemplate {
|
|||||||
#[strum_discriminants(strum(props(Arity = "4", Name = "get_partial_string")))]
|
#[strum_discriminants(strum(props(Arity = "4", Name = "get_partial_string")))]
|
||||||
GetPartialString(Level, Atom, RegType, bool),
|
GetPartialString(Level, Atom, RegType, bool),
|
||||||
#[strum_discriminants(strum(props(Arity = "3", Name = "get_structure")))]
|
#[strum_discriminants(strum(props(Arity = "3", Name = "get_structure")))]
|
||||||
GetStructure(Atom, usize, RegType),
|
GetStructure(Level, Atom, usize, RegType),
|
||||||
#[strum_discriminants(strum(props(Arity = "2", Name = "get_variable")))]
|
#[strum_discriminants(strum(props(Arity = "2", Name = "get_variable")))]
|
||||||
GetVariable(RegType, usize),
|
GetVariable(RegType, usize),
|
||||||
#[strum_discriminants(strum(props(Arity = "2", Name = "get_value")))]
|
#[strum_discriminants(strum(props(Arity = "2", Name = "get_value")))]
|
||||||
@@ -2105,13 +2105,14 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
[lvl_stub, rt_stub]
|
[lvl_stub, rt_stub]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
&Instruction::GetStructure(name, arity, r) => {
|
&Instruction::GetStructure(lvl, name, arity, r) => {
|
||||||
|
let lvl_stub = lvl.into_functor();
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!(
|
||||||
atom!("get_structure"),
|
atom!("get_structure"),
|
||||||
[atom(name), fixnum(arity), str(h, 0)],
|
[str(h, 0), atom(name), fixnum(arity), str(h, 1)],
|
||||||
[rt_stub]
|
[lvl_stub, rt_stub]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
&Instruction::GetValue(r, arg) => {
|
&Instruction::GetValue(r, arg) => {
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ impl DebrayAllocator {
|
|||||||
fn trim_structure_by_last_arg(instr: &mut Instruction, last_arg: &Term) {
|
fn trim_structure_by_last_arg(instr: &mut Instruction, last_arg: &Term) {
|
||||||
match instr {
|
match instr {
|
||||||
Instruction::PutStructure(_, ref mut arity, _) |
|
Instruction::PutStructure(_, ref mut arity, _) |
|
||||||
Instruction::GetStructure(_, ref mut arity, _) => {
|
Instruction::GetStructure(.., ref mut arity, _) => {
|
||||||
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
|
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
|
||||||
// it is acceptable if arity == 0 is the result of
|
// it is acceptable if arity == 0 is the result of
|
||||||
// this decrement. call/N will have to read the index
|
// this decrement. call/N will have to read the index
|
||||||
@@ -447,7 +447,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
}
|
}
|
||||||
TermRef::Clause(lvl, cell, name, terms) => {
|
TermRef::Clause(lvl, cell, name, terms) => {
|
||||||
self.marker.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
|
self.marker.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
|
||||||
target.push_back(Target::to_structure(name, terms.len(), cell.get()));
|
target.push_back(Target::to_structure(lvl, name, terms.len(), cell.get()));
|
||||||
|
|
||||||
<CodeGenerator<'b> as AddToFreeList<'a, Target>>::add_term_to_free_list(self, cell.get());
|
<CodeGenerator<'b> as AddToFreeList<'a, Target>>::add_term_to_free_list(self, cell.get());
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ use crate::types::*;
|
|||||||
|
|
||||||
use crate::try_numeric_result;
|
use crate::try_numeric_result;
|
||||||
|
|
||||||
|
use fxhash::FxBuildHasher;
|
||||||
|
|
||||||
macro_rules! step_or_fail {
|
macro_rules! step_or_fail {
|
||||||
($self:expr, $step_e:expr) => {
|
($self:expr, $step_e:expr) => {
|
||||||
if $self.machine_st.fail {
|
if $self.machine_st.fail {
|
||||||
@@ -182,6 +184,128 @@ impl MachineState {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(crate) fn select_switch_on_term_index(
|
||||||
|
&self,
|
||||||
|
addr: HeapCellValue,
|
||||||
|
v: IndexingCodePtr,
|
||||||
|
c: IndexingCodePtr,
|
||||||
|
l: IndexingCodePtr,
|
||||||
|
s: IndexingCodePtr,
|
||||||
|
) -> IndexingCodePtr {
|
||||||
|
read_heap_cell!(addr,
|
||||||
|
(HeapCellValueTag::Var |
|
||||||
|
HeapCellValueTag::StackVar |
|
||||||
|
HeapCellValueTag::AttrVar) => {
|
||||||
|
v
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::PStrLoc |
|
||||||
|
HeapCellValueTag::Lis |
|
||||||
|
HeapCellValueTag::CStr) => {
|
||||||
|
l
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Fixnum |
|
||||||
|
HeapCellValueTag::Char |
|
||||||
|
HeapCellValueTag::F64) => {
|
||||||
|
c
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Atom, (_name, arity)) => {
|
||||||
|
// if arity == 0 { c } else { s }
|
||||||
|
debug_assert!(arity == 0);
|
||||||
|
c
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Str, st) => {
|
||||||
|
let (name, arity) = cell_as_atom_cell!(self.heap[st])
|
||||||
|
.get_name_and_arity();
|
||||||
|
|
||||||
|
match (name, arity) {
|
||||||
|
(atom!("."), 2) => l,
|
||||||
|
(_, 0) => c,
|
||||||
|
_ => s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Cons, ptr) => {
|
||||||
|
match ptr.get_tag() {
|
||||||
|
ArenaHeaderTag::Rational | ArenaHeaderTag::Integer => {
|
||||||
|
c
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
IndexingCodePtr::Fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(crate) fn constant_to_literal(&self, addr: HeapCellValue) -> Literal {
|
||||||
|
read_heap_cell!(addr,
|
||||||
|
(HeapCellValueTag::Char, c) => {
|
||||||
|
Literal::Char(c)
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Fixnum, n) => {
|
||||||
|
Literal::Fixnum(n)
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::F64, f) => {
|
||||||
|
Literal::Float(f.as_offset())
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Atom, (atom, arity)) => {
|
||||||
|
debug_assert_eq!(arity, 0);
|
||||||
|
Literal::Atom(atom)
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Str, s) => {
|
||||||
|
Literal::Atom(cell_as_atom_cell!(self.heap[s]).get_name())
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Cons, cons_ptr) => {
|
||||||
|
match_untyped_arena_ptr!(cons_ptr,
|
||||||
|
(ArenaHeaderTag::Rational, r) => {
|
||||||
|
Literal::Rational(r)
|
||||||
|
}
|
||||||
|
(ArenaHeaderTag::Integer, n) => {
|
||||||
|
Literal::Integer(n)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(crate) fn select_switch_on_structure_index(
|
||||||
|
&self,
|
||||||
|
addr: HeapCellValue,
|
||||||
|
hm: &IndexMap<(Atom, usize), IndexingCodePtr, FxBuildHasher>,
|
||||||
|
) -> IndexingCodePtr {
|
||||||
|
read_heap_cell!(addr,
|
||||||
|
(HeapCellValueTag::Atom, (name, arity)) => {
|
||||||
|
match hm.get(&(name, arity)) {
|
||||||
|
Some(offset) => *offset,
|
||||||
|
None => IndexingCodePtr::Fail,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Str, s) => {
|
||||||
|
let (name, arity) = cell_as_atom_cell!(self.heap[s])
|
||||||
|
.get_name_and_arity();
|
||||||
|
|
||||||
|
match hm.get(&(name, arity)) {
|
||||||
|
Some(offset) => *offset,
|
||||||
|
None => IndexingCodePtr::Fail,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
IndexingCodePtr::Fail
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Machine {
|
impl Machine {
|
||||||
@@ -349,51 +473,7 @@ impl Machine {
|
|||||||
loop {
|
loop {
|
||||||
match &indexing_lines[index] {
|
match &indexing_lines[index] {
|
||||||
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, v, c, l, s)) => {
|
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, v, c, l, s)) => {
|
||||||
let offset = read_heap_cell!(addr,
|
let offset = self.machine_st.select_switch_on_term_index(addr, v, c, l, s);
|
||||||
(HeapCellValueTag::Var |
|
|
||||||
HeapCellValueTag::StackVar |
|
|
||||||
HeapCellValueTag::AttrVar) => {
|
|
||||||
v
|
|
||||||
}
|
|
||||||
(HeapCellValueTag::PStrLoc |
|
|
||||||
HeapCellValueTag::Lis |
|
|
||||||
HeapCellValueTag::CStr) => {
|
|
||||||
l
|
|
||||||
}
|
|
||||||
(HeapCellValueTag::Fixnum |
|
|
||||||
HeapCellValueTag::Char |
|
|
||||||
HeapCellValueTag::F64) => {
|
|
||||||
c
|
|
||||||
}
|
|
||||||
(HeapCellValueTag::Atom, (_name, arity)) => {
|
|
||||||
// if arity == 0 { c } else { s }
|
|
||||||
debug_assert!(arity == 0);
|
|
||||||
c
|
|
||||||
}
|
|
||||||
(HeapCellValueTag::Str, st) => {
|
|
||||||
let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[st])
|
|
||||||
.get_name_and_arity();
|
|
||||||
|
|
||||||
match (name, arity) {
|
|
||||||
(atom!("."), 2) => l,
|
|
||||||
(_, 0) => c,
|
|
||||||
_ => s,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(HeapCellValueTag::Cons, ptr) => {
|
|
||||||
match ptr.get_tag() {
|
|
||||||
ArenaHeaderTag::Rational | ArenaHeaderTag::Integer => {
|
|
||||||
c
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
IndexingCodePtr::Fail
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
match offset {
|
match offset {
|
||||||
IndexingCodePtr::Fail => {
|
IndexingCodePtr::Fail => {
|
||||||
@@ -423,41 +503,8 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref hm)) => {
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(hm)) => {
|
||||||
let lit = read_heap_cell!(addr,
|
let lit = self.machine_st.constant_to_literal(addr);
|
||||||
(HeapCellValueTag::Char, c) => {
|
|
||||||
Literal::Char(c)
|
|
||||||
}
|
|
||||||
(HeapCellValueTag::Fixnum, n) => {
|
|
||||||
Literal::Fixnum(n)
|
|
||||||
}
|
|
||||||
(HeapCellValueTag::F64, f) => {
|
|
||||||
Literal::Float(f.as_offset())
|
|
||||||
}
|
|
||||||
(HeapCellValueTag::Atom, (atom, arity)) => {
|
|
||||||
debug_assert_eq!(arity, 0);
|
|
||||||
Literal::Atom(atom)
|
|
||||||
}
|
|
||||||
(HeapCellValueTag::Str, s) => {
|
|
||||||
Literal::Atom(cell_as_atom_cell!(self.machine_st.heap[s]).get_name())
|
|
||||||
}
|
|
||||||
(HeapCellValueTag::Cons, cons_ptr) => {
|
|
||||||
match_untyped_arena_ptr!(cons_ptr,
|
|
||||||
(ArenaHeaderTag::Rational, r) => {
|
|
||||||
Literal::Rational(r)
|
|
||||||
}
|
|
||||||
(ArenaHeaderTag::Integer, n) => {
|
|
||||||
Literal::Integer(n)
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
let offset = match hm.get(&lit) {
|
let offset = match hm.get(&lit) {
|
||||||
Some(offset) => *offset,
|
Some(offset) => *offset,
|
||||||
@@ -492,27 +539,8 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref hm)) => {
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(hm)) => {
|
||||||
let offset = read_heap_cell!(addr,
|
let offset = self.machine_st.select_switch_on_structure_index(addr, hm);
|
||||||
(HeapCellValueTag::Atom, (name, arity)) => {
|
|
||||||
match hm.get(&(name, arity)) {
|
|
||||||
Some(offset) => *offset,
|
|
||||||
None => IndexingCodePtr::Fail,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(HeapCellValueTag::Str, s) => {
|
|
||||||
let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
|
|
||||||
.get_name_and_arity();
|
|
||||||
|
|
||||||
match hm.get(&(name, arity)) {
|
|
||||||
Some(offset) => *offset,
|
|
||||||
None => IndexingCodePtr::Fail,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
IndexingCodePtr::Fail
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
match offset {
|
match offset {
|
||||||
IndexingCodePtr::Fail => {
|
IndexingCodePtr::Fail => {
|
||||||
@@ -997,7 +1025,7 @@ impl Machine {
|
|||||||
fixnum_as_cell!(Fixnum::build_with(self.machine_st.cc as i64));
|
fixnum_as_cell!(Fixnum::build_with(self.machine_st.cc as i64));
|
||||||
|
|
||||||
self.machine_st.num_of_args += 1;
|
self.machine_st.num_of_args += 1;
|
||||||
self.machine_st.try_me_else(next_i);
|
self.try_me_else(next_i);
|
||||||
self.machine_st.num_of_args -= 1;
|
self.machine_st.num_of_args -= 1;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
@@ -1067,7 +1095,7 @@ impl Machine {
|
|||||||
fixnum_as_cell!(Fixnum::build_with(self.machine_st.cc as i64));
|
fixnum_as_cell!(Fixnum::build_with(self.machine_st.cc as i64));
|
||||||
|
|
||||||
self.machine_st.num_of_args += 1;
|
self.machine_st.num_of_args += 1;
|
||||||
self.machine_st.try_me_else(next_i);
|
self.try_me_else(next_i);
|
||||||
self.machine_st.num_of_args -= 1;
|
self.machine_st.num_of_args -= 1;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
@@ -1118,7 +1146,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::TryMeElse(offset) => {
|
&Instruction::TryMeElse(offset) => {
|
||||||
self.machine_st.try_me_else(offset);
|
self.try_me_else(offset);
|
||||||
}
|
}
|
||||||
&Instruction::DefaultRetryMeElse(offset) => {
|
&Instruction::DefaultRetryMeElse(offset) => {
|
||||||
self.retry_me_else(offset);
|
self.retry_me_else(offset);
|
||||||
@@ -2879,7 +2907,7 @@ impl Machine {
|
|||||||
|
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
}
|
}
|
||||||
&Instruction::GetStructure(name, arity, reg) => {
|
&Instruction::GetStructure(_lvl, name, arity, reg) => {
|
||||||
let deref_v = self.machine_st.deref(self.machine_st[reg]);
|
let deref_v = self.machine_st.deref(self.machine_st[reg]);
|
||||||
let store_v = self.machine_st.store(deref_v);
|
let store_v = self.machine_st.store(deref_v);
|
||||||
|
|
||||||
@@ -3076,7 +3104,7 @@ impl Machine {
|
|||||||
IndexingLine::IndexedChoice(ref indexed_choice) => {
|
IndexingLine::IndexedChoice(ref indexed_choice) => {
|
||||||
match &indexed_choice[self.machine_st.iip as usize] {
|
match &indexed_choice[self.machine_st.iip as usize] {
|
||||||
&IndexedChoiceInstruction::Try(offset) => {
|
&IndexedChoiceInstruction::Try(offset) => {
|
||||||
self.machine_st.indexed_try(offset);
|
self.indexed_try(offset);
|
||||||
}
|
}
|
||||||
&IndexedChoiceInstruction::Retry(l) => {
|
&IndexedChoiceInstruction::Retry(l) => {
|
||||||
self.retry(l);
|
self.retry(l);
|
||||||
@@ -3122,7 +3150,7 @@ impl Machine {
|
|||||||
fixnum_as_cell!(Fixnum::build_with(self.machine_st.cc as i64));
|
fixnum_as_cell!(Fixnum::build_with(self.machine_st.cc as i64));
|
||||||
|
|
||||||
self.machine_st.num_of_args += 1;
|
self.machine_st.num_of_args += 1;
|
||||||
self.machine_st.indexed_try(offset);
|
self.indexed_try(offset);
|
||||||
self.machine_st.num_of_args -= 1;
|
self.machine_st.num_of_args -= 1;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
|||||||
@@ -858,65 +858,6 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub(super) fn try_me_else(&mut self, offset: usize) {
|
|
||||||
let n = self.num_of_args;
|
|
||||||
let b = self.stack.allocate_or_frame(n);
|
|
||||||
let or_frame = self.stack.index_or_frame_mut(b);
|
|
||||||
|
|
||||||
or_frame.prelude.num_cells = n;
|
|
||||||
or_frame.prelude.e = self.e;
|
|
||||||
or_frame.prelude.cp = self.cp;
|
|
||||||
or_frame.prelude.b = self.b;
|
|
||||||
or_frame.prelude.bp = self.p + offset;
|
|
||||||
or_frame.prelude.boip = 0;
|
|
||||||
or_frame.prelude.biip = 0;
|
|
||||||
or_frame.prelude.tr = self.tr;
|
|
||||||
or_frame.prelude.h = self.heap.len();
|
|
||||||
or_frame.prelude.b0 = self.b0;
|
|
||||||
or_frame.prelude.attr_var_queue_len = self.attr_var_init.attr_var_queue.len();
|
|
||||||
|
|
||||||
self.b = b;
|
|
||||||
|
|
||||||
for i in 0..n {
|
|
||||||
or_frame[i] = self.registers[i+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
self.hb = self.heap.len();
|
|
||||||
self.p += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub(super) fn indexed_try(&mut self, offset: usize) {
|
|
||||||
let n = self.num_of_args;
|
|
||||||
let b = self.stack.allocate_or_frame(n);
|
|
||||||
let or_frame = self.stack.index_or_frame_mut(b);
|
|
||||||
|
|
||||||
or_frame.prelude.num_cells = n;
|
|
||||||
or_frame.prelude.e = self.e;
|
|
||||||
or_frame.prelude.cp = self.cp;
|
|
||||||
or_frame.prelude.b = self.b;
|
|
||||||
or_frame.prelude.bp = self.p; // + 1; in self.iip now!
|
|
||||||
or_frame.prelude.boip = self.oip;
|
|
||||||
or_frame.prelude.biip = self.iip + 1;
|
|
||||||
or_frame.prelude.tr = self.tr;
|
|
||||||
or_frame.prelude.h = self.heap.len();
|
|
||||||
or_frame.prelude.b0 = self.b0;
|
|
||||||
or_frame.prelude.attr_var_queue_len = self.attr_var_init.attr_var_queue.len();
|
|
||||||
|
|
||||||
self.b = b;
|
|
||||||
|
|
||||||
for i in 0..n {
|
|
||||||
or_frame[i] = self.registers[i+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
self.hb = self.heap.len();
|
|
||||||
self.p = self.p + offset;
|
|
||||||
|
|
||||||
self.oip = 0;
|
|
||||||
self.iip = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -547,38 +547,351 @@ impl Machine {
|
|||||||
self.machine_st.verify_attr_interrupt(p, arity);
|
self.machine_st.verify_attr_interrupt(p, arity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn next_clause_applicable(&mut self, mut offset: usize) -> bool {
|
||||||
|
loop {
|
||||||
|
match &self.code[offset] {
|
||||||
|
Instruction::IndexingCode(indexing_lines) => {
|
||||||
|
let mut oip = 0;
|
||||||
|
let mut cell = empty_list_as_cell!();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let indexing_code_ptr = match &indexing_lines[oip] {
|
||||||
|
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(arg, v, c, l, s)) => {
|
||||||
|
cell = self.deref_register(arg);
|
||||||
|
self.machine_st.select_switch_on_term_index(cell, v, c, l, s)
|
||||||
|
}
|
||||||
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(hm)) => {
|
||||||
|
let lit = self.machine_st.constant_to_literal(cell);
|
||||||
|
hm.get(&lit).cloned().unwrap_or(IndexingCodePtr::Fail)
|
||||||
|
}
|
||||||
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(hm)) => {
|
||||||
|
self.machine_st.select_switch_on_structure_index(cell, hm)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
offset += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match indexing_code_ptr {
|
||||||
|
IndexingCodePtr::External(_) | IndexingCodePtr::DynamicExternal(_) => {
|
||||||
|
offset += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
IndexingCodePtr::Internal(i) => oip += i,
|
||||||
|
IndexingCodePtr::Fail => return false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&Instruction::GetConstant(Level::Shallow, lit, RegType::Temp(t)) => {
|
||||||
|
let cell = self.deref_register(t);
|
||||||
|
|
||||||
|
if cell.is_var() {
|
||||||
|
offset += 1;
|
||||||
|
} else if lit.get_tag() == HeapCellValueTag::CStr {
|
||||||
|
read_heap_cell!(cell,
|
||||||
|
(HeapCellValueTag::CStr) => {
|
||||||
|
if cell == lit {
|
||||||
|
offset += 1;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc) => {
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Str, s) => {
|
||||||
|
let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
|
||||||
|
.get_name_and_arity();
|
||||||
|
|
||||||
|
if name == atom!(".") && arity == 2 {
|
||||||
|
offset += 1;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.machine_st.write_literal_to_var(cell, lit);
|
||||||
|
|
||||||
|
if self.machine_st.fail {
|
||||||
|
self.machine_st.fail = false;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&Instruction::GetList(Level::Shallow, RegType::Temp(t)) => {
|
||||||
|
let cell = self.deref_register(t);
|
||||||
|
|
||||||
|
read_heap_cell!(cell,
|
||||||
|
(HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc | HeapCellValueTag::CStr) => {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => {
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
&Instruction::GetStructure(Level::Shallow, name, arity, RegType::Temp(t)) => {
|
||||||
|
let cell = self.deref_register(t);
|
||||||
|
|
||||||
|
read_heap_cell!(cell,
|
||||||
|
(HeapCellValueTag::Str, s) => {
|
||||||
|
if (name, arity) == cell_as_atom_cell!(self.machine_st.heap[s]).get_name_and_arity() {
|
||||||
|
offset += 1;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => {
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
&Instruction::GetPartialString(Level::Shallow, string, RegType::Temp(t), has_tail) => {
|
||||||
|
let cell = self.deref_register(t);
|
||||||
|
|
||||||
|
read_heap_cell!(cell,
|
||||||
|
(HeapCellValueTag::CStr, cstr) => {
|
||||||
|
if !has_tail && string != cstr {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => {
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Instruction::GetConstant(..) |
|
||||||
|
Instruction::GetList(..) |
|
||||||
|
Instruction::GetStructure(..) |
|
||||||
|
Instruction::GetPartialString(..) |
|
||||||
|
&Instruction::UnifyVoid(..) |
|
||||||
|
&Instruction::UnifyConstant(..) |
|
||||||
|
&Instruction::GetVariable(..) |
|
||||||
|
&Instruction::GetValue(..) |
|
||||||
|
&Instruction::UnifyVariable(..) |
|
||||||
|
&Instruction::UnifyValue(..) |
|
||||||
|
&Instruction::UnifyLocalValue(..) => {
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_applicable_clause(&mut self, mut offset: usize) -> Option<usize> {
|
||||||
|
while !self.next_clause_applicable(self.machine_st.p + offset + 1) {
|
||||||
|
match &self.code[self.machine_st.p + offset] {
|
||||||
|
&Instruction::DefaultRetryMeElse(o) | &Instruction::RetryMeElse(o) |
|
||||||
|
&Instruction::DynamicElse(.., NextOrFail::Next(o)) |
|
||||||
|
&Instruction::DynamicInternalElse(.., NextOrFail::Next(o)) => offset += o,
|
||||||
|
_ => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_inner_applicable_clause(&mut self) -> Option<u32> {
|
||||||
|
let mut inner_offset = 1u32;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match &self.code[self.machine_st.p] {
|
||||||
|
Instruction::IndexingCode(indexing_lines) => {
|
||||||
|
match &indexing_lines[self.machine_st.oip as usize] {
|
||||||
|
IndexingLine::IndexedChoice(indexed_choice) => {
|
||||||
|
match &indexed_choice[(self.machine_st.iip + inner_offset) as usize] {
|
||||||
|
&IndexedChoiceInstruction::Retry(o) => {
|
||||||
|
if self.next_clause_applicable(self.machine_st.p + o) {
|
||||||
|
return Some(inner_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
inner_offset += 1;
|
||||||
|
}
|
||||||
|
&IndexedChoiceInstruction::Trust(o) => {
|
||||||
|
return if self.next_clause_applicable(self.machine_st.p + o) {
|
||||||
|
Some(inner_offset)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IndexingLine::DynamicIndexedChoice(indexed_choice) => {
|
||||||
|
let idx = (self.machine_st.iip + inner_offset) as usize;
|
||||||
|
let o = indexed_choice[idx];
|
||||||
|
|
||||||
|
if idx + 1 == indexed_choice.len() {
|
||||||
|
return if self.next_clause_applicable(self.machine_st.p + o) {
|
||||||
|
Some(inner_offset)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
if self.next_clause_applicable(self.machine_st.p + o) {
|
||||||
|
return Some(inner_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
inner_offset += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(super) fn try_me_else(&mut self, offset: usize) {
|
||||||
|
if let Some(offset) = self.next_applicable_clause(offset) {
|
||||||
|
let n = self.machine_st.num_of_args;
|
||||||
|
let b = self.machine_st.stack.allocate_or_frame(n);
|
||||||
|
let or_frame = self.machine_st.stack.index_or_frame_mut(b);
|
||||||
|
|
||||||
|
or_frame.prelude.num_cells = n;
|
||||||
|
or_frame.prelude.e = self.machine_st.e;
|
||||||
|
or_frame.prelude.cp = self.machine_st.cp;
|
||||||
|
or_frame.prelude.b = self.machine_st.b;
|
||||||
|
or_frame.prelude.bp = self.machine_st.p + offset;
|
||||||
|
or_frame.prelude.boip = 0;
|
||||||
|
or_frame.prelude.biip = 0;
|
||||||
|
or_frame.prelude.tr = self.machine_st.tr;
|
||||||
|
or_frame.prelude.h = self.machine_st.heap.len();
|
||||||
|
or_frame.prelude.b0 = self.machine_st.b0;
|
||||||
|
or_frame.prelude.attr_var_queue_len = self.machine_st.attr_var_init.attr_var_queue.len();
|
||||||
|
|
||||||
|
self.machine_st.b = b;
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
or_frame[i] = self.machine_st.registers[i+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.machine_st.hb = self.machine_st.heap.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.machine_st.p += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(super) fn indexed_try(&mut self, offset: usize) {
|
||||||
|
if let Some(iip_offset) = self.next_inner_applicable_clause() {
|
||||||
|
let n = self.machine_st.num_of_args;
|
||||||
|
let b = self.machine_st.stack.allocate_or_frame(n);
|
||||||
|
let or_frame = self.machine_st.stack.index_or_frame_mut(b);
|
||||||
|
|
||||||
|
or_frame.prelude.num_cells = n;
|
||||||
|
or_frame.prelude.e = self.machine_st.e;
|
||||||
|
or_frame.prelude.cp = self.machine_st.cp;
|
||||||
|
or_frame.prelude.b = self.machine_st.b;
|
||||||
|
or_frame.prelude.bp = self.machine_st.p;
|
||||||
|
or_frame.prelude.boip = self.machine_st.oip;
|
||||||
|
or_frame.prelude.biip = self.machine_st.iip + iip_offset; // 1
|
||||||
|
or_frame.prelude.tr = self.machine_st.tr;
|
||||||
|
or_frame.prelude.h = self.machine_st.heap.len();
|
||||||
|
or_frame.prelude.b0 = self.machine_st.b0;
|
||||||
|
or_frame.prelude.attr_var_queue_len = self.machine_st.attr_var_init.attr_var_queue.len();
|
||||||
|
|
||||||
|
self.machine_st.b = b;
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
or_frame[i] = self.machine_st.registers[i+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.machine_st.hb = self.machine_st.heap.len();
|
||||||
|
|
||||||
|
self.machine_st.oip = 0;
|
||||||
|
self.machine_st.iip = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.machine_st.p += offset;
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn retry_me_else(&mut self, offset: usize) {
|
fn retry_me_else(&mut self, offset: usize) {
|
||||||
let b = self.machine_st.b;
|
let b = self.machine_st.b;
|
||||||
let or_frame = self.machine_st.stack.index_or_frame_mut(b);
|
let or_frame = self.machine_st.stack.index_or_frame_mut(b);
|
||||||
let n = or_frame.prelude.num_cells;
|
let n = or_frame.prelude.num_cells;
|
||||||
|
|
||||||
|
let old_tr = or_frame.prelude.tr;
|
||||||
|
let curr_tr = self.machine_st.tr;
|
||||||
|
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
self.machine_st.registers[i + 1] = or_frame[i];
|
self.machine_st.registers[i + 1] = or_frame[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
self.machine_st.num_of_args = n;
|
|
||||||
self.machine_st.e = or_frame.prelude.e;
|
|
||||||
self.machine_st.cp = or_frame.prelude.cp;
|
|
||||||
|
|
||||||
or_frame.prelude.bp = self.machine_st.p + offset;
|
|
||||||
|
|
||||||
let old_tr = or_frame.prelude.tr;
|
|
||||||
let curr_tr = self.machine_st.tr;
|
|
||||||
let target_h = or_frame.prelude.h;
|
|
||||||
let attr_var_queue_len = or_frame.prelude.attr_var_queue_len;
|
|
||||||
|
|
||||||
self.machine_st.tr = or_frame.prelude.tr;
|
|
||||||
self.reset_attr_var_state(attr_var_queue_len);
|
|
||||||
|
|
||||||
self.machine_st.hb = target_h;
|
|
||||||
|
|
||||||
self.unwind_trail(old_tr, curr_tr);
|
self.unwind_trail(old_tr, curr_tr);
|
||||||
|
|
||||||
self.machine_st.trail.truncate(self.machine_st.tr);
|
if let Some(offset) = self.next_applicable_clause(offset) {
|
||||||
self.machine_st.heap.truncate(target_h);
|
let or_frame = self.machine_st.stack.index_or_frame_mut(b);
|
||||||
|
|
||||||
self.machine_st.p += 1;
|
self.machine_st.num_of_args = n;
|
||||||
|
self.machine_st.e = or_frame.prelude.e;
|
||||||
|
self.machine_st.cp = or_frame.prelude.cp;
|
||||||
|
|
||||||
|
or_frame.prelude.bp = self.machine_st.p + offset;
|
||||||
|
|
||||||
|
let target_h = or_frame.prelude.h;
|
||||||
|
let attr_var_queue_len = or_frame.prelude.attr_var_queue_len;
|
||||||
|
|
||||||
|
self.machine_st.tr = or_frame.prelude.tr;
|
||||||
|
self.reset_attr_var_state(attr_var_queue_len);
|
||||||
|
|
||||||
|
self.machine_st.hb = target_h;
|
||||||
|
|
||||||
|
self.machine_st.trail.truncate(self.machine_st.tr);
|
||||||
|
self.machine_st.heap.truncate(target_h);
|
||||||
|
|
||||||
|
self.machine_st.p += 1;
|
||||||
|
} else {
|
||||||
|
self.trust_me_epilogue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -587,34 +900,42 @@ impl Machine {
|
|||||||
let or_frame = self.machine_st.stack.index_or_frame_mut(b);
|
let or_frame = self.machine_st.stack.index_or_frame_mut(b);
|
||||||
let n = or_frame.prelude.num_cells;
|
let n = or_frame.prelude.num_cells;
|
||||||
|
|
||||||
|
let old_tr = or_frame.prelude.tr;
|
||||||
|
let curr_tr = self.machine_st.tr;
|
||||||
|
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
self.machine_st.registers[i+1] = or_frame[i];
|
self.machine_st.registers[i+1] = or_frame[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
self.machine_st.num_of_args = n;
|
|
||||||
self.machine_st.e = or_frame.prelude.e;
|
|
||||||
self.machine_st.cp = or_frame.prelude.cp;
|
|
||||||
|
|
||||||
or_frame.prelude.biip += 1;
|
|
||||||
|
|
||||||
let old_tr = or_frame.prelude.tr;
|
|
||||||
let curr_tr = self.machine_st.tr;
|
|
||||||
let target_h = or_frame.prelude.h;
|
|
||||||
let attr_var_queue_len = or_frame.prelude.attr_var_queue_len;
|
|
||||||
|
|
||||||
self.machine_st.tr = or_frame.prelude.tr;
|
|
||||||
self.reset_attr_var_state(attr_var_queue_len);
|
|
||||||
|
|
||||||
self.machine_st.hb = target_h;
|
|
||||||
self.machine_st.p = self.machine_st.p + offset;
|
|
||||||
|
|
||||||
self.unwind_trail(old_tr, curr_tr);
|
self.unwind_trail(old_tr, curr_tr);
|
||||||
|
|
||||||
self.machine_st.trail.truncate(self.machine_st.tr);
|
if let Some(iip_offset) = self.next_inner_applicable_clause() {
|
||||||
self.machine_st.heap.truncate(target_h);
|
let or_frame = self.machine_st.stack.index_or_frame_mut(b);
|
||||||
|
|
||||||
self.machine_st.oip = 0;
|
self.machine_st.num_of_args = n;
|
||||||
self.machine_st.iip = 0;
|
self.machine_st.e = or_frame.prelude.e;
|
||||||
|
self.machine_st.cp = or_frame.prelude.cp;
|
||||||
|
|
||||||
|
or_frame.prelude.biip += iip_offset;
|
||||||
|
|
||||||
|
let target_h = or_frame.prelude.h;
|
||||||
|
let attr_var_queue_len = or_frame.prelude.attr_var_queue_len;
|
||||||
|
|
||||||
|
self.machine_st.tr = or_frame.prelude.tr;
|
||||||
|
self.machine_st.trail.truncate(self.machine_st.tr);
|
||||||
|
|
||||||
|
self.reset_attr_var_state(attr_var_queue_len);
|
||||||
|
|
||||||
|
self.machine_st.hb = target_h;
|
||||||
|
self.machine_st.p += offset;
|
||||||
|
|
||||||
|
self.machine_st.heap.truncate(target_h);
|
||||||
|
|
||||||
|
self.machine_st.oip = 0;
|
||||||
|
self.machine_st.iip = 0;
|
||||||
|
} else {
|
||||||
|
self.trust_epilogue(offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -623,19 +944,32 @@ impl Machine {
|
|||||||
let or_frame = self.machine_st.stack.index_or_frame(b);
|
let or_frame = self.machine_st.stack.index_or_frame(b);
|
||||||
let n = or_frame.prelude.num_cells;
|
let n = or_frame.prelude.num_cells;
|
||||||
|
|
||||||
|
let old_tr = or_frame.prelude.tr;
|
||||||
|
let curr_tr = self.machine_st.tr;
|
||||||
|
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
self.machine_st.registers[i+1] = or_frame[i];
|
self.machine_st.registers[i+1] = or_frame[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.unwind_trail(old_tr, curr_tr);
|
||||||
|
self.trust_epilogue(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn trust_epilogue(&mut self, offset: usize) {
|
||||||
|
let b = self.machine_st.b;
|
||||||
|
let or_frame = self.machine_st.stack.index_or_frame(b);
|
||||||
|
let n = or_frame.prelude.num_cells;
|
||||||
|
|
||||||
self.machine_st.num_of_args = n;
|
self.machine_st.num_of_args = n;
|
||||||
self.machine_st.e = or_frame.prelude.e;
|
self.machine_st.e = or_frame.prelude.e;
|
||||||
self.machine_st.cp = or_frame.prelude.cp;
|
self.machine_st.cp = or_frame.prelude.cp;
|
||||||
|
|
||||||
let old_tr = or_frame.prelude.tr;
|
|
||||||
let curr_tr = self.machine_st.tr;
|
|
||||||
let target_h = or_frame.prelude.h;
|
let target_h = or_frame.prelude.h;
|
||||||
|
|
||||||
self.machine_st.tr = or_frame.prelude.tr;
|
self.machine_st.tr = or_frame.prelude.tr;
|
||||||
|
self.machine_st.trail.truncate(self.machine_st.tr);
|
||||||
|
|
||||||
self.machine_st.b = or_frame.prelude.b;
|
self.machine_st.b = or_frame.prelude.b;
|
||||||
|
|
||||||
self.reset_attr_var_state(or_frame.prelude.attr_var_queue_len);
|
self.reset_attr_var_state(or_frame.prelude.attr_var_queue_len);
|
||||||
@@ -643,9 +977,6 @@ impl Machine {
|
|||||||
self.machine_st.hb = target_h;
|
self.machine_st.hb = target_h;
|
||||||
self.machine_st.p = self.machine_st.p + offset;
|
self.machine_st.p = self.machine_st.p + offset;
|
||||||
|
|
||||||
self.unwind_trail(old_tr, curr_tr);
|
|
||||||
|
|
||||||
self.machine_st.trail.truncate(self.machine_st.tr);
|
|
||||||
self.machine_st.stack.truncate(b);
|
self.machine_st.stack.truncate(b);
|
||||||
self.machine_st.heap.truncate(target_h);
|
self.machine_st.heap.truncate(target_h);
|
||||||
|
|
||||||
@@ -663,12 +994,24 @@ impl Machine {
|
|||||||
self.machine_st.registers[i+1] = or_frame[i];
|
self.machine_st.registers[i+1] = or_frame[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let old_tr = or_frame.prelude.tr;
|
||||||
|
let curr_tr = self.machine_st.tr;
|
||||||
|
|
||||||
|
self.unwind_trail(old_tr, curr_tr);
|
||||||
|
|
||||||
|
self.trust_me_epilogue();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn trust_me_epilogue(&mut self) {
|
||||||
|
let b = self.machine_st.b;
|
||||||
|
let or_frame = self.machine_st.stack.index_or_frame(b);
|
||||||
|
let n = or_frame.prelude.num_cells;
|
||||||
|
|
||||||
self.machine_st.num_of_args = n;
|
self.machine_st.num_of_args = n;
|
||||||
self.machine_st.e = or_frame.prelude.e;
|
self.machine_st.e = or_frame.prelude.e;
|
||||||
self.machine_st.cp = or_frame.prelude.cp;
|
self.machine_st.cp = or_frame.prelude.cp;
|
||||||
|
|
||||||
let old_tr = or_frame.prelude.tr;
|
|
||||||
let curr_tr = self.machine_st.tr;
|
|
||||||
let target_h = or_frame.prelude.h;
|
let target_h = or_frame.prelude.h;
|
||||||
|
|
||||||
self.machine_st.tr = or_frame.prelude.tr;
|
self.machine_st.tr = or_frame.prelude.tr;
|
||||||
@@ -679,8 +1022,6 @@ impl Machine {
|
|||||||
self.machine_st.hb = target_h;
|
self.machine_st.hb = target_h;
|
||||||
self.machine_st.p += 1;
|
self.machine_st.p += 1;
|
||||||
|
|
||||||
self.unwind_trail(old_tr, curr_tr);
|
|
||||||
|
|
||||||
self.machine_st.trail.truncate(self.machine_st.tr);
|
self.machine_st.trail.truncate(self.machine_st.tr);
|
||||||
self.machine_st.stack.truncate(b);
|
self.machine_st.stack.truncate(b);
|
||||||
self.machine_st.heap.truncate(target_h);
|
self.machine_st.heap.truncate(target_h);
|
||||||
|
|||||||
@@ -1277,7 +1277,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn deref_register(&mut self, i: usize) -> HeapCellValue {
|
pub(crate) fn deref_register(&self, i: usize) -> HeapCellValue {
|
||||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[i]))
|
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub(crate) trait CompilationTarget<'a> {
|
|||||||
|
|
||||||
fn to_constant(lvl: Level, literal: Literal, r: RegType) -> Instruction;
|
fn to_constant(lvl: Level, literal: Literal, r: RegType) -> Instruction;
|
||||||
fn to_list(lvl: Level, r: RegType) -> Instruction;
|
fn to_list(lvl: Level, r: RegType) -> Instruction;
|
||||||
fn to_structure(name: Atom, arity: usize, r: RegType) -> Instruction;
|
fn to_structure(lvl: Level, name: Atom, arity: usize, r: RegType) -> Instruction;
|
||||||
|
|
||||||
fn to_void(num_subterms: usize) -> Instruction;
|
fn to_void(num_subterms: usize) -> Instruction;
|
||||||
fn is_void_instr(instr: &Instruction) -> bool;
|
fn is_void_instr(instr: &Instruction) -> bool;
|
||||||
@@ -51,8 +51,8 @@ impl<'a> CompilationTarget<'a> for FactInstruction {
|
|||||||
Instruction::GetConstant(lvl, HeapCellValue::from(constant), reg)
|
Instruction::GetConstant(lvl, HeapCellValue::from(constant), reg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_structure(name: Atom, arity: usize, reg: RegType) -> Instruction {
|
fn to_structure(lvl: Level, name: Atom, arity: usize, reg: RegType) -> Instruction {
|
||||||
Instruction::GetStructure(name, arity, reg)
|
Instruction::GetStructure(lvl, name, arity, reg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_list(lvl: Level, reg: RegType) -> Instruction {
|
fn to_list(lvl: Level, reg: RegType) -> Instruction {
|
||||||
@@ -125,7 +125,7 @@ impl<'a> CompilationTarget<'a> for QueryInstruction {
|
|||||||
post_order_iter(term)
|
post_order_iter(term)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_structure(name: Atom, arity: usize, r: RegType) -> Instruction {
|
fn to_structure(_lvl: Level, name: Atom, arity: usize, r: RegType) -> Instruction {
|
||||||
Instruction::PutStructure(name, arity, r)
|
Instruction::PutStructure(name, arity, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user