remove LocalCodePtr::IndexingBuf

This commit is contained in:
Mark Thom
2021-12-15 23:41:00 -07:00
parent b056d40eba
commit 6f9b6a29c4
8 changed files with 233 additions and 216 deletions

View File

@@ -1,53 +1,19 @@
use crate::clause_types::*; use crate::clause_types::*;
use crate::instructions::*; use crate::instructions::*;
use crate::machine::MachineState;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
// TODO: remove this, replace with just 'Code'.
#[derive(Debug)] #[derive(Debug)]
pub struct CodeRepo { pub struct CodeRepo {
pub(super) code: Code, pub(super) code: Code,
} }
impl CodeRepo { impl CodeRepo {
#[inline] pub(super) fn lookup_instr<'a>(&'a self, machine_st: &MachineState, p: &CodePtr) -> Option<RefOrOwned<'a, Line>> {
pub(super) fn new() -> Self {
CodeRepo { code: Code::new() }
}
#[inline]
pub(super) fn lookup_local_instr<'a>(&'a self, p: LocalCodePtr) -> RefOrOwned<'a, Line> {
match p {
LocalCodePtr::Halt => {
// exit with the interrupt exit code.
std::process::exit(1);
}
LocalCodePtr::DirEntry(p) => RefOrOwned::Borrowed(&self.code[p as usize]),
LocalCodePtr::IndexingBuf(p, o, i) => match &self.code[p] {
&Line::IndexingCode(ref indexing_lines) => match &indexing_lines[o] {
&IndexingLine::IndexedChoice(ref indexed_choice_instrs) => {
RefOrOwned::Owned(Line::IndexedChoice(indexed_choice_instrs[i]))
}
&IndexingLine::DynamicIndexedChoice(ref indexed_choice_instrs) => {
RefOrOwned::Owned(Line::DynamicIndexedChoice(indexed_choice_instrs[i]))
}
_ => {
unreachable!()
}
},
_ => {
unreachable!()
}
},
}
}
pub(super) fn lookup_instr<'a>(
&'a self,
last_call: bool,
p: &CodePtr,
) -> Option<RefOrOwned<'a, Line>> {
match p { match p {
&CodePtr::Local(local) => { &CodePtr::Local(local) => {
return Some(self.lookup_local_instr(local)); return Some(self.lookup_local_instr(machine_st, local));
} }
&CodePtr::REPL(..) => None, &CodePtr::REPL(..) => None,
&CodePtr::BuiltInClause(ref built_in, _) => { &CodePtr::BuiltInClause(ref built_in, _) => {
@@ -55,33 +21,56 @@ impl CodeRepo {
ClauseType::BuiltIn(built_in.clone()), ClauseType::BuiltIn(built_in.clone()),
built_in.arity(), built_in.arity(),
0, 0,
last_call machine_st.last_call
); );
Some(RefOrOwned::Owned(call_clause)) Some(RefOrOwned::Owned(call_clause))
} }
&CodePtr::CallN(arity, _, last_call) => { &CodePtr::CallN(arity, _, last_call) => {
let call_clause = call_clause!(ClauseType::CallN, arity, 0, last_call); let call_clause = call_clause!(ClauseType::CallN, arity, 0, last_call);
Some(RefOrOwned::Owned(call_clause)) Some(RefOrOwned::Owned(call_clause))
} }
&CodePtr::VerifyAttrInterrupt(p) => Some(RefOrOwned::Borrowed(&self.code[p])), &CodePtr::VerifyAttrInterrupt(p) => Some(RefOrOwned::Borrowed(&self.code[p])),
} }
} }
pub(super) fn find_living_dynamic_else( #[inline]
&self, pub(super) fn lookup_local_instr<'a>(&'a self, machine_st: &MachineState, p: LocalCodePtr) -> RefOrOwned<'a, Line> {
mut p: usize, match p {
cc: usize, LocalCodePtr::Halt => {
) -> Option<(usize, usize)> { // exit with the interrupt exit code.
std::process::exit(1);
}
LocalCodePtr::DirEntry(p) => match &self.code[p] {
&Line::IndexingCode(ref indexing_lines) => {
match &indexing_lines[machine_st.oip as usize] {
&IndexingLine::IndexedChoice(ref indexed_choice_instrs) => {
RefOrOwned::Owned(Line::IndexedChoice(indexed_choice_instrs[machine_st.iip as usize]))
}
&IndexingLine::DynamicIndexedChoice(ref indexed_choice_instrs) => {
RefOrOwned::Owned(Line::DynamicIndexedChoice(indexed_choice_instrs[machine_st.iip as usize]))
}
_ => {
RefOrOwned::Borrowed(&self.code[p as usize])
}
}
}
_ => RefOrOwned::Borrowed(&self.code[p as usize]),
}
}
}
}
impl MachineState {
pub(super) fn find_living_dynamic_else(&self, code: &Code, mut p: usize) -> Option<(usize, usize)> {
loop { loop {
match &self.code[p] { match &code[p] {
&Line::Choice(ChoiceInstruction::DynamicElse( &Line::Choice(ChoiceInstruction::DynamicElse(
birth, birth,
death, death,
NextOrFail::Next(i), NextOrFail::Next(i),
)) => { )) => {
if birth < cc && Death::Finite(cc) <= death { if birth < self.cc && Death::Finite(self.cc) <= death {
return Some((p, i)); return Some((p, i));
} else if i > 0 { } else if i > 0 {
p += i; p += i;
@@ -94,7 +83,7 @@ impl CodeRepo {
death, death,
NextOrFail::Fail(_), NextOrFail::Fail(_),
)) => { )) => {
if birth < cc && Death::Finite(cc) <= death { if birth < self.cc && Death::Finite(self.cc) <= death {
return Some((p, 0)); return Some((p, 0));
} else { } else {
return None; return None;
@@ -105,7 +94,7 @@ impl CodeRepo {
death, death,
NextOrFail::Next(i), NextOrFail::Next(i),
)) => { )) => {
if birth < cc && Death::Finite(cc) <= death { if birth < self.cc && Death::Finite(self.cc) <= death {
return Some((p, i)); return Some((p, i));
} else if i > 0 { } else if i > 0 {
p += i; p += i;
@@ -118,7 +107,7 @@ impl CodeRepo {
death, death,
NextOrFail::Fail(_), NextOrFail::Fail(_),
)) => { )) => {
if birth < cc && Death::Finite(cc) <= death { if birth < self.cc && Death::Finite(self.cc) <= death {
return Some((p, 0)); return Some((p, 0));
} else { } else {
return None; return None;
@@ -134,18 +123,11 @@ impl CodeRepo {
} }
} }
pub(super) fn find_living_dynamic( pub(super) fn find_living_dynamic(&self, code: &Code, oi: u32, mut ii: u32) -> Option<(usize, u32, u32, bool)> {
&self, let p = self.p.local().abs_loc();
p: LocalCodePtr,
cc: usize,
) -> Option<(usize, usize, usize, bool)> {
let (p, oi, mut ii) = match p {
LocalCodePtr::IndexingBuf(p, oi, ii) => (p, oi, ii),
_ => unreachable!(),
};
let indexed_choice_instrs = match &self.code[p] { let indexed_choice_instrs = match &code[p] {
Line::IndexingCode(ref indexing_code) => match &indexing_code[oi] { Line::IndexingCode(ref indexing_code) => match &indexing_code[oi as usize] {
IndexingLine::DynamicIndexedChoice(ref indexed_choice_instrs) => { IndexingLine::DynamicIndexedChoice(ref indexed_choice_instrs) => {
indexed_choice_instrs indexed_choice_instrs
} }
@@ -155,14 +137,14 @@ impl CodeRepo {
}; };
loop { loop {
match &indexed_choice_instrs.get(ii) { match &indexed_choice_instrs.get(ii as usize) {
Some(&offset) => match &self.code[p + offset - 1] { Some(&offset) => match &code[p + offset - 1] {
&Line::Choice(ChoiceInstruction::DynamicInternalElse( &Line::Choice(ChoiceInstruction::DynamicInternalElse(
birth, birth,
death, death,
next_or_fail, next_or_fail,
)) => { )) => {
if birth < cc && Death::Finite(cc) <= death { if birth < self.cc && Death::Finite(self.cc) <= death {
return Some((offset, oi, ii, next_or_fail.is_next())); return Some((offset, oi, ii, next_or_fail.is_next()));
} else { } else {
ii += 1; ii += 1;
@@ -175,3 +157,10 @@ impl CodeRepo {
} }
} }
} }
impl CodeRepo {
#[inline]
pub(super) fn new() -> Self {
CodeRepo { code: Code::new() }
}
}

View File

@@ -322,8 +322,26 @@ impl CodePtr {
pub enum LocalCodePtr { pub enum LocalCodePtr {
DirEntry(usize), // offset DirEntry(usize), // offset
Halt, Halt,
IndexingBuf(usize, usize, usize), // DirEntry offset, first internal offset, second internal offset // IndexingBuf(usize, usize, usize), // DirEntry offset, first internal offset, second internal offset
// TopLevel(usize, usize), // chunk_num, offset // TopLevel(usize, usize), // chunk_num, offset
}
impl MachineState {
pub(crate) fn is_reset_cont_marker(&self, code_repo: &CodeRepo, p: LocalCodePtr) -> bool {
match code_repo.lookup_instr(self, &CodePtr::Local(p)) {
Some(line) => match line.as_ref() {
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
return true;
}
}
_ => {}
},
None => {}
}
false
}
} }
impl LocalCodePtr { impl LocalCodePtr {
@@ -338,27 +356,11 @@ impl LocalCodePtr {
pub fn abs_loc(&self) -> usize { pub fn abs_loc(&self) -> usize {
match self { match self {
LocalCodePtr::DirEntry(ref p) => *p, LocalCodePtr::DirEntry(ref p) => *p,
LocalCodePtr::IndexingBuf(ref p, ..) => *p, // LocalCodePtr::IndexingBuf(ref p, ..) => *p,
LocalCodePtr::Halt => unreachable!(), LocalCodePtr::Halt => unreachable!(),
} }
} }
pub(crate) fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) {
Some(line) => match line.as_ref() {
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
return true;
}
}
_ => {}
},
None => {}
}
false
}
pub(crate) fn as_functor(&self) -> MachineStub { pub(crate) fn as_functor(&self) -> MachineStub {
match self { match self {
LocalCodePtr::DirEntry(p) => { LocalCodePtr::DirEntry(p) => {
@@ -367,12 +369,14 @@ impl LocalCodePtr {
LocalCodePtr::Halt => { LocalCodePtr::Halt => {
functor!(atom!("halt")) functor!(atom!("halt"))
} }
/*
LocalCodePtr::IndexingBuf(p, o, i) => { LocalCodePtr::IndexingBuf(p, o, i) => {
functor!( functor!(
atom!("indexed_buf"), atom!("indexed_buf"),
[fixnum(*p), fixnum(*o), fixnum(*i)] [fixnum(*p), fixnum(*o), fixnum(*i)]
) )
} }
*/
} }
} }
} }
@@ -399,7 +403,7 @@ impl Add<usize> for LocalCodePtr {
match self { match self {
LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p + rhs), LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p + rhs),
LocalCodePtr::Halt => unreachable!(), LocalCodePtr::Halt => unreachable!(),
LocalCodePtr::IndexingBuf(p, o, i) => LocalCodePtr::IndexingBuf(p, o, i + rhs), // LocalCodePtr::IndexingBuf(p, o, i) => LocalCodePtr::IndexingBuf(p, o, i + rhs),
} }
} }
} }
@@ -412,9 +416,9 @@ impl Sub<usize> for LocalCodePtr {
match self { match self {
LocalCodePtr::DirEntry(p) => p.checked_sub(rhs).map(LocalCodePtr::DirEntry), LocalCodePtr::DirEntry(p) => p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
LocalCodePtr::Halt => unreachable!(), LocalCodePtr::Halt => unreachable!(),
LocalCodePtr::IndexingBuf(p, o, i) => i // LocalCodePtr::IndexingBuf(p, o, i) => i
.checked_sub(rhs) // .checked_sub(rhs)
.map(|r| LocalCodePtr::IndexingBuf(p, o, r)), // .map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
} }
} }
} }
@@ -424,7 +428,7 @@ impl SubAssign<usize> for LocalCodePtr {
fn sub_assign(&mut self, rhs: usize) { fn sub_assign(&mut self, rhs: usize) {
match self { match self {
LocalCodePtr::DirEntry(ref mut p) => *p -= rhs, LocalCodePtr::DirEntry(ref mut p) => *p -= rhs,
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) => unreachable!(), LocalCodePtr::Halt => unreachable!() // | LocalCodePtr::IndexingBuf(..) => unreachable!(),
} }
} }
} }
@@ -433,8 +437,8 @@ impl AddAssign<usize> for LocalCodePtr {
#[inline] #[inline]
fn add_assign(&mut self, rhs: usize) { fn add_assign(&mut self, rhs: usize) {
match self { match self {
&mut LocalCodePtr::DirEntry(ref mut i) &mut LocalCodePtr::DirEntry(ref mut i) => *i += rhs,
| &mut LocalCodePtr::IndexingBuf(_, _, ref mut i) => *i += rhs, // | &mut LocalCodePtr::IndexingBuf(_, _, ref mut i) => *i += rhs,
&mut LocalCodePtr::Halt => unreachable!(), &mut LocalCodePtr::Halt => unreachable!(),
} }
} }

View File

@@ -63,6 +63,8 @@ pub struct MachineState {
pub(super) pdl: Vec<HeapCellValue>, pub(super) pdl: Vec<HeapCellValue>,
pub(super) s: HeapPtr, pub(super) s: HeapPtr,
pub(super) p: CodePtr, pub(super) p: CodePtr,
pub(super) oip: u32, // first internal code ptr
pub(super) iip : u32, // second internal code ptr
pub(super) b: usize, pub(super) b: usize,
pub(super) b0: usize, pub(super) b0: usize,
pub(super) e: usize, pub(super) e: usize,
@@ -81,7 +83,7 @@ pub struct MachineState {
pub(super) ball: Ball, pub(super) ball: Ball,
pub(super) lifted_heap: Heap, pub(super) lifted_heap: Heap,
pub(super) interms: Vec<Number>, // intermediate numbers. pub(super) interms: Vec<Number>, // intermediate numbers.
pub(super) last_call: bool, pub(super) last_call: bool, // TODO: REMOVE THIS.
pub(crate) flags: MachineFlags, pub(crate) flags: MachineFlags,
pub(crate) cc: usize, pub(crate) cc: usize,
pub(crate) global_clock: usize, pub(crate) global_clock: usize,
@@ -191,38 +193,34 @@ pub trait CallPolicy: Any + fmt::Debug {
global_variables: &mut GlobalVarDir, global_variables: &mut GlobalVarDir,
) -> CallResult { ) -> CallResult {
let b = machine_st.b; let b = machine_st.b;
let n = machine_st let or_frame = machine_st.stack.index_or_frame_mut(b);
.stack let n = or_frame.prelude.univ_prelude.num_cells;
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1..n + 1 { for i in 0..n {
machine_st.registers[i] = machine_st.stack[stack_loc!(OrFrame, b, i - 1)]; machine_st.registers[i + 1] = or_frame[i];
} }
machine_st.num_of_args = n; machine_st.num_of_args = n;
machine_st.e = machine_st.stack.index_or_frame(b).prelude.e; machine_st.e = or_frame.prelude.e;
machine_st.cp = machine_st.stack.index_or_frame(b).prelude.cp; machine_st.cp = or_frame.prelude.cp;
machine_st.stack.index_or_frame_mut(b).prelude.bp = machine_st.p.local() + offset; or_frame.prelude.bp = machine_st.p.local() + offset;
let old_tr = machine_st.stack.index_or_frame(b).prelude.tr; let old_tr = or_frame.prelude.tr;
let curr_tr = machine_st.tr; let curr_tr = machine_st.tr;
let target_h = or_frame.prelude.h;
machine_st.unwind_trail(old_tr, curr_tr, global_variables); machine_st.tr = or_frame.prelude.tr;
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr);
machine_st
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
machine_st.attr_var_init.reset(); machine_st.attr_var_init.reset();
machine_st.hb = machine_st.heap.len(); machine_st.hb = machine_st.heap.len();
machine_st.p += 1; machine_st.p += 1;
machine_st.unwind_trail(old_tr, curr_tr, global_variables);
machine_st.trail.truncate(machine_st.tr);
machine_st.heap.truncate(target_h);
Ok(()) Ok(())
} }
@@ -233,38 +231,38 @@ pub trait CallPolicy: Any + fmt::Debug {
global_variables: &mut GlobalVarDir, global_variables: &mut GlobalVarDir,
) -> CallResult { ) -> CallResult {
let b = machine_st.b; let b = machine_st.b;
let n = machine_st let or_frame = machine_st.stack.index_or_frame_mut(b);
.stack let n = or_frame.prelude.univ_prelude.num_cells;
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1..n + 1 { for i in 0..n {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1]; machine_st.registers[i+1] = or_frame[i];
} }
machine_st.num_of_args = n; machine_st.num_of_args = n;
machine_st.e = machine_st.stack.index_or_frame(b).prelude.e; machine_st.e = or_frame.prelude.e;
machine_st.cp = machine_st.stack.index_or_frame(b).prelude.cp; machine_st.cp = or_frame.prelude.cp;
machine_st.stack.index_or_frame_mut(b).prelude.bp = machine_st.p.local() + 1; // WAS: or_frame.prelude.bp = machine_st.p.local() + 1;
or_frame.prelude.biip += 1;
let old_tr = machine_st.stack.index_or_frame(b).prelude.tr; let old_tr = or_frame.prelude.tr;
let curr_tr = machine_st.tr; let curr_tr = machine_st.tr;
let target_h = or_frame.prelude.h;
machine_st.tr = or_frame.prelude.tr;
machine_st.attr_var_init.reset();
machine_st.unwind_trail(old_tr, curr_tr, global_variables); machine_st.unwind_trail(old_tr, curr_tr, global_variables);
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr); machine_st.trail.truncate(machine_st.tr);
machine_st machine_st.heap.truncate(target_h);
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
machine_st.attr_var_init.reset();
machine_st.hb = machine_st.heap.len(); machine_st.hb = machine_st.heap.len();
machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset)); machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset));
machine_st.oip = 0;
machine_st.iip = 0;
Ok(()) Ok(())
} }
@@ -275,39 +273,38 @@ pub trait CallPolicy: Any + fmt::Debug {
global_variables: &mut GlobalVarDir, global_variables: &mut GlobalVarDir,
) -> CallResult { ) -> CallResult {
let b = machine_st.b; let b = machine_st.b;
let n = machine_st let or_frame = machine_st.stack.index_or_frame(b);
.stack let n = or_frame.prelude.univ_prelude.num_cells;
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1..n + 1 { for i in 0..n {
machine_st.registers[i] = machine_st.stack[stack_loc!(OrFrame, b, i - 1)]; machine_st.registers[i+1] = or_frame[i];
} }
machine_st.num_of_args = n; machine_st.num_of_args = n;
machine_st.e = machine_st.stack.index_or_frame(b).prelude.e; machine_st.e = or_frame.prelude.e;
machine_st.cp = machine_st.stack.index_or_frame(b).prelude.cp; machine_st.cp = or_frame.prelude.cp;
let old_tr = machine_st.stack.index_or_frame(b).prelude.tr; let old_tr = or_frame.prelude.tr;
let curr_tr = machine_st.tr; let curr_tr = machine_st.tr;
let target_h = or_frame.prelude.h;
machine_st.unwind_trail(old_tr, curr_tr, global_variables); machine_st.tr = or_frame.prelude.tr;
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr);
machine_st
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
machine_st.attr_var_init.reset(); machine_st.attr_var_init.reset();
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b; machine_st.b = or_frame.prelude.b;
machine_st.unwind_trail(old_tr, curr_tr, global_variables);
machine_st.trail.truncate(machine_st.tr);
machine_st.stack.truncate(b); machine_st.stack.truncate(b);
machine_st.heap.truncate(target_h);
machine_st.hb = machine_st.heap.len(); machine_st.hb = machine_st.heap.len();
machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset)); machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset));
machine_st.oip = 0;
machine_st.iip = 0;
Ok(()) Ok(())
} }
@@ -317,35 +314,31 @@ pub trait CallPolicy: Any + fmt::Debug {
global_variables: &mut GlobalVarDir, global_variables: &mut GlobalVarDir,
) -> CallResult { ) -> CallResult {
let b = machine_st.b; let b = machine_st.b;
let n = machine_st let or_frame = machine_st.stack.index_or_frame(b);
.stack let n = or_frame.prelude.univ_prelude.num_cells;
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1..n + 1 { for i in 0..n {
machine_st.registers[i] = machine_st.stack[stack_loc!(OrFrame, b, i - 1)]; machine_st.registers[i+1] = or_frame[i];
} }
machine_st.num_of_args = n; machine_st.num_of_args = n;
machine_st.e = machine_st.stack.index_or_frame(b).prelude.e; machine_st.e = or_frame.prelude.e;
machine_st.cp = machine_st.stack.index_or_frame(b).prelude.cp; machine_st.cp = or_frame.prelude.cp;
let old_tr = machine_st.stack.index_or_frame(b).prelude.tr; let old_tr = or_frame.prelude.tr;
let curr_tr = machine_st.tr; let curr_tr = machine_st.tr;
let target_h = or_frame.prelude.h;
machine_st.unwind_trail(old_tr, curr_tr, global_variables); machine_st.tr = or_frame.prelude.tr;
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr);
machine_st
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
machine_st.attr_var_init.reset(); machine_st.attr_var_init.reset();
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b; machine_st.b = or_frame.prelude.b;
machine_st.unwind_trail(old_tr, curr_tr, global_variables);
machine_st.trail.truncate(machine_st.tr);
machine_st.stack.truncate(b); machine_st.stack.truncate(b);
machine_st.heap.truncate(target_h);
machine_st.hb = machine_st.heap.len(); machine_st.hb = machine_st.heap.len();
machine_st.p += 1; machine_st.p += 1;
@@ -754,7 +747,6 @@ impl<'a> IndexMut<usize> for CopyTerm<'a> {
} }
} }
// the ordinary, heap term copier, used by duplicate_term.
impl<'a> CopierTarget for CopyTerm<'a> { impl<'a> CopierTarget for CopyTerm<'a> {
#[inline(always)] #[inline(always)]
fn threshold(&self) -> usize { fn threshold(&self) -> usize {
@@ -827,7 +819,6 @@ impl<'a> IndexMut<usize> for CopyBallTerm<'a> {
} }
} }
// the ordinary, heap term copier, used by duplicate_term.
impl<'a> CopierTarget for CopyBallTerm<'a> { impl<'a> CopierTarget for CopyBallTerm<'a> {
fn threshold(&self) -> usize { fn threshold(&self) -> usize {
self.heap_boundary + self.stub.len() self.heap_boundary + self.stub.len()

View File

@@ -37,6 +37,8 @@ impl MachineState {
pdl: Vec::with_capacity(1024), pdl: Vec::with_capacity(1024),
s: HeapPtr::default(), s: HeapPtr::default(),
p: CodePtr::default(), p: CodePtr::default(),
oip: 0,
iip: 0,
b: 0, b: 0,
b0: 0, b0: 0,
e: 0, e: 0,
@@ -1905,8 +1907,8 @@ impl MachineState {
None => unreachable!(), None => unreachable!(),
} }
} }
TrailEntryTag::TrailedAttachedValue => { TrailEntryTag::TrailedAttachedValue => {
} }
} }
} }
} }
@@ -2758,7 +2760,9 @@ impl MachineState {
} }
&IndexingLine::IndexedChoice(_) => { &IndexingLine::IndexedChoice(_) => {
if let LocalCodePtr::DirEntry(p) = self.p.local() { if let LocalCodePtr::DirEntry(p) = self.p.local() {
self.p = CodePtr::Local(LocalCodePtr::IndexingBuf(p, index, 0)); self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
self.oip = index as u32;
self.iip = 0;
} else { } else {
unreachable!() unreachable!()
} }
@@ -2769,7 +2773,9 @@ impl MachineState {
self.dynamic_mode = FirstOrNext::First; self.dynamic_mode = FirstOrNext::First;
if let LocalCodePtr::DirEntry(p) = self.p.local() { if let LocalCodePtr::DirEntry(p) = self.p.local() {
self.p = CodePtr::Local(LocalCodePtr::IndexingBuf(p, index, 0)); self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
self.oip = index as u32;
self.iip = 0;
} else { } else {
unreachable!() unreachable!()
} }
@@ -3886,9 +3892,11 @@ impl MachineState {
) { ) {
let p = self.p.local(); let p = self.p.local();
match code_repo.find_living_dynamic(p, self.cc) { match self.find_living_dynamic(&code_repo.code, self.oip, self.iip) {
Some((offset, oi, ii, is_next_clause)) => { Some((offset, oi, ii, is_next_clause)) => {
self.p = CodePtr::Local(LocalCodePtr::IndexingBuf(p.abs_loc(), oi, ii)); self.p = CodePtr::Local(LocalCodePtr::DirEntry(p.abs_loc()));
self.oip = oi;
self.iip = ii;
match self.dynamic_mode { match self.dynamic_mode {
FirstOrNext::First if !is_next_clause => { FirstOrNext::First if !is_next_clause => {
@@ -3898,14 +3906,15 @@ impl MachineState {
// there's a leading DynamicElse that sets self.cc. // there's a leading DynamicElse that sets self.cc.
// self.cc = self.global_clock; // self.cc = self.global_clock;
match code_repo.find_living_dynamic( // see that there is a following dynamic_else
LocalCodePtr::IndexingBuf(p.abs_loc(), oi, ii + 1), // clause so we avoid generating a choice
self.cc, // point in case there isn't.
) { match self.find_living_dynamic(&code_repo.code, oi, ii + 1) {
Some(_) => { Some(_) => {
self.registers[self.num_of_args + 1] = self.registers[self.num_of_args + 1] =
fixnum_as_cell!(Fixnum::build_with(self.cc as i64)); fixnum_as_cell!(Fixnum::build_with(self.cc as i64));
self.num_of_args += 1;
self.num_of_args += 2;
self.execute_indexed_choice_instr( self.execute_indexed_choice_instr(
&IndexedChoiceInstruction::Try(offset), &IndexedChoiceInstruction::Try(offset),
@@ -3913,39 +3922,39 @@ impl MachineState {
global_variables, global_variables,
); );
self.num_of_args -= 1; self.num_of_args -= 2;
} }
None => { None => {
self.p = self.p = CodePtr::Local(LocalCodePtr::DirEntry(p.abs_loc() + offset));
CodePtr::Local(LocalCodePtr::DirEntry(p.abs_loc() + offset)); self.oip = 0;
self.iip = 0;
} }
} }
} }
FirstOrNext::Next => { FirstOrNext::Next => {
let b = self.b;
let n = self let n = self
.stack .stack
.index_or_frame(self.b) .index_or_frame(b)
.prelude .prelude
.univ_prelude .univ_prelude
.num_cells; .num_cells;
self.cc = cell_as_fixnum!(self.stack[n - 1]).get_num() as usize; self.cc = cell_as_fixnum!(self.stack[stack_loc!(OrFrame, b, n-2)])
.get_num() as usize;
if is_next_clause { if is_next_clause {
match code_repo.find_living_dynamic( match self.find_living_dynamic(&code_repo.code, self.oip, self.iip) {
LocalCodePtr::IndexingBuf(p.abs_loc(), oi, ii + 1),
self.cc,
) {
Some(_) => { Some(_) => {
try_or_fail!( try_or_fail!(
self, self,
call_policy.retry(self, offset, global_variables,) call_policy.retry(self, offset, global_variables)
) );
} }
None => { None => {
try_or_fail!( try_or_fail!(
self, self,
call_policy.trust(self, offset, global_variables,) call_policy.trust(self, offset, global_variables)
) )
} }
} }
@@ -3979,19 +3988,36 @@ impl MachineState {
or_frame.prelude.e = self.e; or_frame.prelude.e = self.e;
or_frame.prelude.cp = self.cp; or_frame.prelude.cp = self.cp;
or_frame.prelude.b = self.b; or_frame.prelude.b = self.b;
or_frame.prelude.bp = self.p.local() + 1; or_frame.prelude.bp = self.p.local(); // + 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.tr = self.tr;
or_frame.prelude.h = self.heap.len(); or_frame.prelude.h = self.heap.len();
or_frame.prelude.b0 = self.b0; or_frame.prelude.b0 = self.b0;
self.b = b; self.b = b;
for i in 1..n + 1 { for i in 0..n {
self.stack.index_or_frame_mut(b)[i - 1] = self.registers[i]; or_frame[i] = self.registers[i+1];
} }
/*
self.iip += 1;
let oip_b = self.oip.to_ne_bytes();
let iip_b = self.iip.to_ne_bytes();
or_frame[n] = HeapCellValue::from_bytes(
[oip_b[0], oip_b[1], oip_b[2], oip_b[3],
iip_b[0], iip_b[1], iip_b[2], iip_b[3]],
);
*/
self.hb = self.heap.len(); self.hb = self.heap.len();
self.p = CodePtr::Local(dir_entry!(self.p.local().abs_loc() + offset)); self.p = CodePtr::Local(dir_entry!(self.p.local().abs_loc() + offset));
self.oip = 0;
self.iip = 0;
} }
&IndexedChoiceInstruction::Retry(l) => { &IndexedChoiceInstruction::Retry(l) => {
try_or_fail!(self, call_policy.retry(self, l, global_variables)); try_or_fail!(self, call_policy.retry(self, l, global_variables));
@@ -4017,7 +4043,7 @@ impl MachineState {
let p = self.p.local().abs_loc(); let p = self.p.local().abs_loc();
match code_repo.find_living_dynamic_else(p, self.cc) { match self.find_living_dynamic_else(&code_repo.code, p) {
Some((p, next_i)) => { Some((p, next_i)) => {
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p)); self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
@@ -4028,7 +4054,7 @@ impl MachineState {
FirstOrNext::First => { FirstOrNext::First => {
self.cc = self.global_clock; self.cc = self.global_clock;
match code_repo.find_living_dynamic_else(p + next_i, self.cc) { match self.find_living_dynamic_else(&code_repo.code, p + next_i) {
Some(_) => { Some(_) => {
self.registers[self.num_of_args + 1] = self.registers[self.num_of_args + 1] =
fixnum_as_cell!(Fixnum::build_with(self.cc as i64)); fixnum_as_cell!(Fixnum::build_with(self.cc as i64));
@@ -4056,11 +4082,11 @@ impl MachineState {
.univ_prelude .univ_prelude
.num_cells; .num_cells;
self.cc = cell_as_fixnum!(self.stack.index_or_frame(self.b)[n - 1]) self.cc = cell_as_fixnum!(self.stack[stack_loc!(OrFrame, self.b, n-1)])
.get_num() as usize; .get_num() as usize;
if next_i > 0 { if next_i > 0 {
match code_repo.find_living_dynamic_else(p + next_i, self.cc) { match self.find_living_dynamic_else(&code_repo.code, p + next_i) {
Some(_) => { Some(_) => {
try_or_fail!( try_or_fail!(
self, self,
@@ -4094,7 +4120,7 @@ impl MachineState {
&ChoiceInstruction::DynamicInternalElse(..) => { &ChoiceInstruction::DynamicInternalElse(..) => {
let p = self.p.local().abs_loc(); let p = self.p.local().abs_loc();
match code_repo.find_living_dynamic_else(p, self.cc) { match self.find_living_dynamic_else(&code_repo.code, p) {
Some((p, next_i)) => { Some((p, next_i)) => {
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p)); self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
@@ -4103,7 +4129,7 @@ impl MachineState {
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p + 1)); self.p = CodePtr::Local(LocalCodePtr::DirEntry(p + 1));
} }
FirstOrNext::First => { FirstOrNext::First => {
match code_repo.find_living_dynamic_else(p + next_i, self.cc) { match self.find_living_dynamic_else(&code_repo.code, p + next_i) {
Some(_) => { Some(_) => {
self.registers[self.num_of_args + 1] = self.registers[self.num_of_args + 1] =
fixnum_as_cell!(Fixnum::build_with(self.cc as i64)); fixnum_as_cell!(Fixnum::build_with(self.cc as i64));
@@ -4131,11 +4157,11 @@ impl MachineState {
.univ_prelude .univ_prelude
.num_cells; .num_cells;
self.cc = cell_as_fixnum!(self.stack.index_or_frame(self.b)[n - 1]) self.cc = cell_as_fixnum!(self.stack[stack_loc!(OrFrame, self.b, n-1)])
.get_num() as usize; .get_num() as usize;
if next_i > 0 { if next_i > 0 {
match code_repo.find_living_dynamic_else(p + next_i, self.cc) { match self.find_living_dynamic_else(&code_repo.code, p + next_i) {
Some(_) => { Some(_) => {
try_or_fail!( try_or_fail!(
self, self,
@@ -4149,14 +4175,14 @@ impl MachineState {
None => { None => {
try_or_fail!( try_or_fail!(
self, self,
call_policy.trust_me(self, global_variables,) call_policy.trust_me(self, global_variables)
) )
} }
} }
} else { } else {
try_or_fail!( try_or_fail!(
self, self,
call_policy.trust_me(self, global_variables,) call_policy.trust_me(self, global_variables)
) )
} }
} }
@@ -4179,6 +4205,8 @@ impl MachineState {
or_frame.prelude.cp = self.cp; or_frame.prelude.cp = self.cp;
or_frame.prelude.b = self.b; or_frame.prelude.b = self.b;
or_frame.prelude.bp = self.p.local() + offset; or_frame.prelude.bp = self.p.local() + offset;
or_frame.prelude.boip = 0;
or_frame.prelude.biip = 0;
or_frame.prelude.tr = self.tr; or_frame.prelude.tr = self.tr;
or_frame.prelude.h = self.heap.len(); or_frame.prelude.h = self.heap.len();
or_frame.prelude.b0 = self.b0; or_frame.prelude.b0 = self.b0;

View File

@@ -612,7 +612,7 @@ impl MachineState {
user_input: &mut Stream, user_input: &mut Stream,
user_output: &mut Stream, user_output: &mut Stream,
) { ) {
let instr = match code_repo.lookup_instr(self.last_call, &self.p) { let instr = match code_repo.lookup_instr(self, &self.p) {
Some(instr) => instr, Some(instr) => instr,
None => return, None => return,
}; };
@@ -629,9 +629,13 @@ impl MachineState {
fn backtrack(&mut self) { fn backtrack(&mut self) {
let b = self.b; let b = self.b;
let or_frame = self.stack.index_or_frame(b);
self.b0 = self.stack.index_or_frame(b).prelude.b0; self.b0 = or_frame.prelude.b0;
self.p = CodePtr::Local(self.stack.index_or_frame(b).prelude.bp); self.p = CodePtr::Local(or_frame.prelude.bp);
self.oip = or_frame.prelude.boip;
self.iip = or_frame.prelude.biip;
self.pdl.clear(); self.pdl.clear();
self.fail = false; self.fail = false;
@@ -639,8 +643,7 @@ impl MachineState {
fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool { fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool {
match self.p { match self.p {
CodePtr::Local(LocalCodePtr::DirEntry(p)) | CodePtr::Local(LocalCodePtr::DirEntry(p))
CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
if p < code_repo.code.len() => {} if p < code_repo.code.len() => {}
CodePtr::Local(LocalCodePtr::Halt) | CodePtr::REPL(..) => { CodePtr::Local(LocalCodePtr::Halt) | CodePtr::REPL(..) => {
return false; return false;
@@ -661,7 +664,7 @@ impl MachineState {
user_output: &mut Stream, user_output: &mut Stream,
) -> bool { ) -> bool {
loop { loop {
let instr = match code_repo.lookup_instr(self.last_call, &self.p) { let instr = match code_repo.lookup_instr(self, &self.p) {
Some(instr) => { Some(instr) => {
if instr.as_ref().is_head_instr() { if instr.as_ref().is_head_instr() {
instr instr
@@ -721,7 +724,7 @@ impl MachineState {
let instigating_p = CodePtr::Local(self.attr_var_init.instigating_p); let instigating_p = CodePtr::Local(self.attr_var_init.instigating_p);
let instigating_instr = code_repo let instigating_instr = code_repo
.lookup_instr(false, &instigating_p) .lookup_instr(self, &instigating_p)
.unwrap(); .unwrap();
if !instigating_instr.as_ref().is_head_instr() { if !instigating_instr.as_ref().is_head_instr() {

View File

@@ -121,6 +121,8 @@ pub(crate) struct OrFramePrelude {
pub(crate) cp: LocalCodePtr, pub(crate) cp: LocalCodePtr,
pub(crate) b: usize, pub(crate) b: usize,
pub(crate) bp: LocalCodePtr, pub(crate) bp: LocalCodePtr,
pub(crate) boip: u32,
pub(crate) biip: u32,
pub(crate) tr: usize, pub(crate) tr: usize,
pub(crate) h: usize, pub(crate) h: usize,
pub(crate) b0: usize, pub(crate) b0: usize,

View File

@@ -3145,7 +3145,7 @@ impl MachineState {
let p_functor = self.store(self.deref(self.registers[2])); let p_functor = self.store(self.deref(self.registers[2]));
let p = to_local_code_ptr(&self.heap, p_functor).unwrap(); let p = to_local_code_ptr(&self.heap, p_functor).unwrap();
let num_cells = match code_repo.lookup_instr(self.last_call, &CodePtr::Local(p)) { let num_cells = match code_repo.lookup_instr(self, &CodePtr::Local(p)) {
Some(line) => { Some(line) => {
let perm_vars = match line.as_ref() { let perm_vars = match line.as_ref() {
Line::Control(ref ctrl_instr) => ctrl_instr.perm_vars(), Line::Control(ref ctrl_instr) => ctrl_instr.perm_vars(),
@@ -3720,7 +3720,7 @@ impl MachineState {
} }
}; };
if p.is_reset_cont_marker(code_repo, self.last_call) { if self.is_reset_cont_marker(&code_repo, p) {
return return_from_clause!(self.last_call, self); return return_from_clause!(self.last_call, self);
} }
@@ -4408,7 +4408,7 @@ impl MachineState {
let mut cp = self.cp; let mut cp = self.cp;
while e > 0 { while e > 0 {
if cp.is_reset_cont_marker(code_repo, self.last_call) { if self.is_reset_cont_marker(code_repo, cp) {
self.e = e; self.e = e;
self.p = CodePtr::Local(cp + 1); // skip the reset marker. self.p = CodePtr::Local(cp + 1); // skip the reset marker.

View File

@@ -20,9 +20,9 @@ impl fmt::Display for LocalCodePtr {
match self { match self {
LocalCodePtr::DirEntry(p) => write!(f, "LocalCodePtr::DirEntry({})", p), LocalCodePtr::DirEntry(p) => write!(f, "LocalCodePtr::DirEntry({})", p),
LocalCodePtr::Halt => write!(f, "LocalCodePtr::Halt"), LocalCodePtr::Halt => write!(f, "LocalCodePtr::Halt"),
LocalCodePtr::IndexingBuf(p, o, i) => { // LocalCodePtr::IndexingBuf(p, o, i) => {
write!(f, "LocalCodePtr::IndexingBuf({}, {}, {})", p, o, i) // write!(f, "LocalCodePtr::IndexingBuf({}, {}, {})", p, o, i)
} // }
} }
} }
} }