flatten the instruction dispatch loop
This commit is contained in:
@@ -3,7 +3,6 @@ use divrem::*;
|
||||
use crate::arena::*;
|
||||
use crate::arithmetic::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::heap_iter::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
@@ -1080,7 +1079,7 @@ impl MachineState {
|
||||
pub fn get_number(&mut self, at: &ArithmeticTerm) -> Result<Number, MachineStub> {
|
||||
match at {
|
||||
&ArithmeticTerm::Reg(r) => {
|
||||
let value = self.store(self.deref(self[r]));
|
||||
let value = self.store(self.deref(self[r]));
|
||||
|
||||
match Number::try_from(value) {
|
||||
Ok(n) => Ok(n),
|
||||
|
||||
@@ -15,8 +15,9 @@ pub(super) type Bindings = Vec<(usize, HeapCellValue)>;
|
||||
pub(super) struct AttrVarInitializer {
|
||||
pub(super) attr_var_queue: Vec<usize>,
|
||||
pub(super) bindings: Bindings,
|
||||
pub(super) cp: LocalCodePtr,
|
||||
pub(super) instigating_p: LocalCodePtr,
|
||||
pub(super) p: usize,
|
||||
pub(super) cp: usize,
|
||||
// pub(super) instigating_p: usize,
|
||||
pub(super) verify_attrs_loc: usize,
|
||||
}
|
||||
|
||||
@@ -25,8 +26,8 @@ impl AttrVarInitializer {
|
||||
AttrVarInitializer {
|
||||
attr_var_queue: vec![],
|
||||
bindings: vec![],
|
||||
instigating_p: LocalCodePtr::default(),
|
||||
cp: LocalCodePtr::default(),
|
||||
p: 0,
|
||||
cp: 0,
|
||||
verify_attrs_loc,
|
||||
}
|
||||
}
|
||||
@@ -41,15 +42,14 @@ impl AttrVarInitializer {
|
||||
impl MachineState {
|
||||
pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: HeapCellValue) {
|
||||
if self.attr_var_init.bindings.is_empty() {
|
||||
self.attr_var_init.instigating_p = self.p.local();
|
||||
// save self.p and self.cp and ensure that the next
|
||||
// instruction is InstallVerifyAttrInterrupt.
|
||||
|
||||
if self.last_call {
|
||||
self.attr_var_init.cp = self.cp;
|
||||
} else {
|
||||
self.attr_var_init.cp = self.p.local() + 1;
|
||||
}
|
||||
self.attr_var_init.p = self.p;
|
||||
self.attr_var_init.cp = self.cp;
|
||||
|
||||
self.p = CodePtr::VerifyAttrInterrupt(self.attr_var_init.verify_attrs_loc);
|
||||
self.p = INSTALL_VERIFY_ATTR_INTERRUPT - 1;
|
||||
self.cp = INSTALL_VERIFY_ATTR_INTERRUPT;
|
||||
}
|
||||
|
||||
self.attr_var_init.bindings.push((h, addr));
|
||||
@@ -109,25 +109,27 @@ impl MachineState {
|
||||
}
|
||||
|
||||
pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
|
||||
self.allocate(self.num_of_args + 2);
|
||||
self.allocate(self.num_of_args + 3);
|
||||
|
||||
let e = self.e;
|
||||
self.stack.index_and_frame_mut(e).prelude.interrupt_cp = self.attr_var_init.cp;
|
||||
let and_frame = self.stack.index_and_frame_mut(e);
|
||||
|
||||
for i in 1..self.num_of_args + 1 {
|
||||
self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)];
|
||||
and_frame[i] = self.registers[i];
|
||||
}
|
||||
|
||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] =
|
||||
and_frame[self.num_of_args + 1] =
|
||||
fixnum_as_cell!(Fixnum::build_with(self.b0 as i64));
|
||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] =
|
||||
and_frame[self.num_of_args + 2] =
|
||||
fixnum_as_cell!(Fixnum::build_with(self.num_of_args as i64));
|
||||
and_frame[self.num_of_args + 3] =
|
||||
fixnum_as_cell!(Fixnum::build_with(self.attr_var_init.cp as i64));
|
||||
|
||||
self.verify_attributes();
|
||||
|
||||
self.num_of_args = 2;
|
||||
self.num_of_args = 3;
|
||||
self.b0 = self.b;
|
||||
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
|
||||
self.p = p;
|
||||
}
|
||||
|
||||
pub(super) fn attr_vars_of_term(&mut self, cell: HeapCellValue) -> Vec<HeapCellValue> {
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
use crate::clause_types::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::{Machine, MachineState};
|
||||
use crate::machine::machine_indices::*;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
pub(crate) enum OwnedOrIndexed {
|
||||
Indexed(usize),
|
||||
Owned(Line),
|
||||
}
|
||||
|
||||
impl fmt::Debug for OwnedOrIndexed {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
&OwnedOrIndexed::Indexed(ref index) => write!(f, "Indexed({:?})", index),
|
||||
&OwnedOrIndexed::Owned(ref owned) => write!(f, "Owned({:?})", owned),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OwnedOrIndexed {
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_ref<'a>(&'a self, code: &'a Code) -> &'a Line {
|
||||
match self {
|
||||
&OwnedOrIndexed::Indexed(p) => &code[p],
|
||||
&OwnedOrIndexed::Owned(ref r) => r,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: remove this, replace with just 'Code'.
|
||||
#[derive(Debug)]
|
||||
pub struct CodeRepo {
|
||||
pub(super) code: Code,
|
||||
}
|
||||
|
||||
impl CodeRepo {
|
||||
pub(super) fn lookup_instr(&self, machine_st: &MachineState, p: &CodePtr) -> Option<OwnedOrIndexed> {
|
||||
match p {
|
||||
&CodePtr::Local(local) => {
|
||||
return Some(self.lookup_local_instr(machine_st, local));
|
||||
}
|
||||
&CodePtr::REPL(..) => None,
|
||||
&CodePtr::BuiltInClause(ref built_in, _) => {
|
||||
let call_clause = call_clause!(
|
||||
ClauseType::BuiltIn(built_in.clone()),
|
||||
built_in.arity(),
|
||||
0,
|
||||
machine_st.last_call
|
||||
);
|
||||
|
||||
Some(OwnedOrIndexed::Owned(call_clause))
|
||||
}
|
||||
&CodePtr::CallN(arity, _, last_call) => {
|
||||
let call_clause = call_clause!(ClauseType::CallN, arity, 0, last_call);
|
||||
Some(OwnedOrIndexed::Owned(call_clause))
|
||||
}
|
||||
&CodePtr::VerifyAttrInterrupt(p) => Some(OwnedOrIndexed::Indexed(p)),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn lookup_local_instr(&self, machine_st: &MachineState, p: LocalCodePtr) -> OwnedOrIndexed {
|
||||
match p {
|
||||
LocalCodePtr::Halt => {
|
||||
// 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) => {
|
||||
OwnedOrIndexed::Owned(
|
||||
Line::IndexedChoice(indexed_choice_instrs[machine_st.iip as usize])
|
||||
)
|
||||
}
|
||||
&IndexingLine::DynamicIndexedChoice(ref indexed_choice_instrs) => {
|
||||
OwnedOrIndexed::Owned(
|
||||
Line::DynamicIndexedChoice(indexed_choice_instrs[machine_st.iip as usize])
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
OwnedOrIndexed::Indexed(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => OwnedOrIndexed::Indexed(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub(super) fn find_living_dynamic_else(&self, mut p: usize) -> Option<(usize, usize)> {
|
||||
loop {
|
||||
match &self.code_repo.code[p] {
|
||||
&Line::Choice(ChoiceInstruction::DynamicElse(
|
||||
birth,
|
||||
death,
|
||||
NextOrFail::Next(i),
|
||||
)) => {
|
||||
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
||||
return Some((p, i));
|
||||
} else if i > 0 {
|
||||
p += i;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DynamicElse(
|
||||
birth,
|
||||
death,
|
||||
NextOrFail::Fail(_),
|
||||
)) => {
|
||||
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
||||
return Some((p, 0));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
birth,
|
||||
death,
|
||||
NextOrFail::Next(i),
|
||||
)) => {
|
||||
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
||||
return Some((p, i));
|
||||
} else if i > 0 {
|
||||
p += i;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
birth,
|
||||
death,
|
||||
NextOrFail::Fail(_),
|
||||
)) => {
|
||||
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
||||
return Some((p, 0));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
&Line::Control(ControlInstruction::RevJmpBy(i)) => {
|
||||
p -= i;
|
||||
}
|
||||
_ => {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn find_living_dynamic(&self, oi: u32, mut ii: u32) -> Option<(usize, u32, u32, bool)> {
|
||||
let p = self.machine_st.p.local().abs_loc();
|
||||
|
||||
let indexed_choice_instrs = match &self.code_repo.code[p] {
|
||||
Line::IndexingCode(ref indexing_code) => match &indexing_code[oi as usize] {
|
||||
IndexingLine::DynamicIndexedChoice(ref indexed_choice_instrs) => {
|
||||
indexed_choice_instrs
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
loop {
|
||||
match &indexed_choice_instrs.get(ii as usize) {
|
||||
Some(&offset) => match &self.code_repo.code[p + offset - 1] {
|
||||
&Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
birth,
|
||||
death,
|
||||
next_or_fail,
|
||||
)) => {
|
||||
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
||||
return Some((offset, oi, ii, next_or_fail.is_next()));
|
||||
} else {
|
||||
ii += 1;
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => return None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CodeRepo {
|
||||
#[inline]
|
||||
pub(super) fn new() -> Self {
|
||||
CodeRepo { code: Code::new() }
|
||||
}
|
||||
}
|
||||
@@ -2,45 +2,47 @@ use crate::instructions::*;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
|
||||
fn capture_offset(line: &Line, index: usize, stack: &mut Vec<usize>) -> bool {
|
||||
fn capture_offset(line: &Instruction, index: usize, stack: &mut Vec<usize>) -> bool {
|
||||
match line {
|
||||
&Line::Choice(ChoiceInstruction::TryMeElse(offset)) if offset > 0 => {
|
||||
&Instruction::TryMeElse(offset) if offset > 0 => {
|
||||
stack.push(index + offset);
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DefaultRetryMeElse(offset))
|
||||
| &Line::Choice(ChoiceInstruction::RetryMeElse(offset))
|
||||
&Instruction::DefaultRetryMeElse(offset) |
|
||||
&Instruction::RetryMeElse(offset)
|
||||
if offset > 0 =>
|
||||
{
|
||||
stack.push(index + offset);
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(offset)))
|
||||
&Instruction::DynamicElse(_, _, NextOrFail::Next(offset))
|
||||
if offset > 0 =>
|
||||
{
|
||||
stack.push(index + offset);
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(offset)))
|
||||
&Instruction::DynamicInternalElse(_, _, NextOrFail::Next(offset))
|
||||
if offset > 0 =>
|
||||
{
|
||||
stack.push(index + offset);
|
||||
}
|
||||
&Line::Control(ControlInstruction::JmpBy(_, offset, _, false)) => {
|
||||
&Instruction::JmpByCall(_, offset, _) => {
|
||||
stack.push(index + offset);
|
||||
}
|
||||
&Line::Control(ControlInstruction::JmpBy(_, offset, _, true)) => {
|
||||
&Instruction::JmpByExecute(_, offset, _) => {
|
||||
stack.push(index + offset);
|
||||
return true;
|
||||
}
|
||||
&Line::Control(ControlInstruction::Proceed)
|
||||
| &Line::Control(ControlInstruction::CallClause(_, _, _, true, _)) => {
|
||||
&Instruction::Proceed => {
|
||||
return true;
|
||||
}
|
||||
&Line::Control(ControlInstruction::RevJmpBy(offset)) => {
|
||||
&Instruction::RevJmpBy(offset) => {
|
||||
if offset > 0 {
|
||||
stack.push(index - offset);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
instr if instr.is_execute() => {
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
@@ -51,7 +53,7 @@ fn capture_offset(line: &Line, index: usize, stack: &mut Vec<usize>) -> bool {
|
||||
* begin in code at the offset p. Each instruction is passed to the
|
||||
* walker function.
|
||||
*/
|
||||
pub(crate) fn walk_code(code: &Code, p: usize, mut walker: impl FnMut(&Line)) {
|
||||
pub(crate) fn walk_code(code: &Code, p: usize, mut walker: impl FnMut(&Instruction)) {
|
||||
let mut stack = vec![p];
|
||||
let mut visited_indices = IndexSet::new();
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ pub(super) fn bootstrapping_compile(
|
||||
);
|
||||
|
||||
let payload = BootstrappingLoadState(
|
||||
LoadStatePayload::new(wam_prelude.code_repo.code.len(), term_stream)
|
||||
LoadStatePayload::new(wam_prelude.code.len(), term_stream)
|
||||
);
|
||||
|
||||
let loader: Loader<'_, BootstrappingLoadState> = Loader { payload, wam_prelude };
|
||||
@@ -73,7 +73,8 @@ pub(super) fn compile_appendix(
|
||||
let code_len = code.len();
|
||||
|
||||
match &mut code[jmp_by_offset] {
|
||||
&mut Line::Control(ControlInstruction::JmpBy(_, ref mut offset, ..)) => {
|
||||
&mut Instruction::JmpByCall(_, ref mut offset, ..) |
|
||||
&mut Instruction::JmpByExecute(_, ref mut offset, ..) => {
|
||||
*offset = code_len - jmp_by_offset;
|
||||
}
|
||||
_ => {
|
||||
@@ -144,20 +145,20 @@ fn derelictize_try_me_else(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) -> Option<usize> {
|
||||
match &mut code[index] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(0))) => None,
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(ref mut o))) => {
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(0)) => None,
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(ref mut o)) => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(index, *o));
|
||||
Some(mem::replace(o, 0))
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(0))) => None,
|
||||
Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(ref mut o))) => {
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(0)) => None,
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(ref mut o)) => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(index, *o));
|
||||
Some(mem::replace(o, 0))
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Fail(_)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Fail(_))) => None,
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(0)) => None,
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) => {
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Fail(_)) |
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(_)) => None,
|
||||
Instruction::TryMeElse(0) => None,
|
||||
Instruction::TryMeElse(ref mut o) => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(index, *o));
|
||||
Some(mem::replace(o, 0))
|
||||
}
|
||||
@@ -183,7 +184,7 @@ fn merge_indices(
|
||||
let clause_loc =
|
||||
find_inner_choice_instr(code, skeleton[clause_index].clause_start, index_loc);
|
||||
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[target_index_loc]).unwrap();
|
||||
let target_indexing_line = code[target_index_loc].to_indexing_line_mut().unwrap();
|
||||
|
||||
skeleton[clause_index]
|
||||
.opt_arg_index_key
|
||||
@@ -210,8 +211,8 @@ fn merge_indices(
|
||||
fn find_outer_choice_instr(code: &Code, mut index: usize) -> usize {
|
||||
loop {
|
||||
match &code[index] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(i)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(i)))
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(i)) |
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(i))
|
||||
if *i > 0 =>
|
||||
{
|
||||
index += i;
|
||||
@@ -226,15 +227,15 @@ fn find_outer_choice_instr(code: &Code, mut index: usize) -> usize {
|
||||
fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> usize {
|
||||
loop {
|
||||
match &code[index] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(o))
|
||||
| Line::Choice(ChoiceInstruction::RetryMeElse(o)) => {
|
||||
Instruction::TryMeElse(o) |
|
||||
Instruction::RetryMeElse(o) => {
|
||||
if *o > 0 {
|
||||
return index;
|
||||
} else {
|
||||
index = index_loc;
|
||||
}
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DynamicElse(_, _, next_or_fail)) => match next_or_fail
|
||||
&Instruction::DynamicElse(_, _, next_or_fail) => match next_or_fail
|
||||
{
|
||||
NextOrFail::Next(i) => {
|
||||
if i == 0 {
|
||||
@@ -247,7 +248,7 @@ fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> u
|
||||
index = index_loc;
|
||||
}
|
||||
},
|
||||
&Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, next_or_fail)) => {
|
||||
&Instruction::DynamicInternalElse(_, _, next_or_fail) => {
|
||||
match next_or_fail {
|
||||
NextOrFail::Next(i) => {
|
||||
if i == 0 {
|
||||
@@ -261,20 +262,20 @@ fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> u
|
||||
}
|
||||
}
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TrustMe(_)) => {
|
||||
Instruction::TrustMe(_) => {
|
||||
return index;
|
||||
}
|
||||
Line::IndexingCode(indexing_code) => match &indexing_code[0] {
|
||||
Instruction::IndexingCode(indexing_code) => match &indexing_code[0] {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, v, ..)) => match v {
|
||||
IndexingCodePtr::External(v) => {
|
||||
index += v;
|
||||
}
|
||||
IndexingCodePtr::DynamicExternal(v) => match &code[index + v] {
|
||||
&Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
&Instruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
NextOrFail::Next(0),
|
||||
)) => {
|
||||
) => {
|
||||
return index + v;
|
||||
}
|
||||
_ => {
|
||||
@@ -287,7 +288,7 @@ fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> u
|
||||
unreachable!();
|
||||
}
|
||||
},
|
||||
Line::Control(ControlInstruction::RevJmpBy(offset)) => {
|
||||
Instruction::RevJmpBy(offset) => {
|
||||
index -= offset;
|
||||
}
|
||||
_ => {
|
||||
@@ -310,9 +311,7 @@ fn remove_index_from_subsequence(
|
||||
) {
|
||||
if let Some(index_loc) = opt_arg_index_key.switch_on_term_loc() {
|
||||
let clause_start = find_inner_choice_instr(code, clause_start, index_loc);
|
||||
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[index_loc]).unwrap();
|
||||
|
||||
let target_indexing_line = code[index_loc].to_indexing_line_mut().unwrap();
|
||||
let offset = clause_start - index_loc + 1;
|
||||
|
||||
remove_index(opt_arg_index_key, target_indexing_line, offset);
|
||||
@@ -351,7 +350,7 @@ fn merge_indexed_subsequences(
|
||||
);
|
||||
|
||||
match &mut code[inner_try_me_else_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) => {
|
||||
Instruction::TryMeElse(ref mut o) => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
|
||||
inner_try_me_else_loc,
|
||||
*o,
|
||||
@@ -359,15 +358,15 @@ fn merge_indexed_subsequences(
|
||||
|
||||
match *o {
|
||||
0 => {
|
||||
code[inner_try_me_else_loc] = Line::Choice(ChoiceInstruction::TrustMe(0));
|
||||
code[inner_try_me_else_loc] = Instruction::TrustMe(0);
|
||||
}
|
||||
o => match &code[inner_try_me_else_loc + o] {
|
||||
Line::Control(ControlInstruction::RevJmpBy(0)) => {
|
||||
code[inner_try_me_else_loc] = Line::Choice(ChoiceInstruction::TrustMe(o));
|
||||
Instruction::RevJmpBy(0) => {
|
||||
code[inner_try_me_else_loc] = Instruction::TrustMe(o);
|
||||
}
|
||||
_ => {
|
||||
code[inner_try_me_else_loc] =
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(o));
|
||||
Instruction::RetryMeElse(o);
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -403,7 +402,7 @@ fn merge_indexed_subsequences(
|
||||
);
|
||||
}
|
||||
None => match &mut code[outer_threaded_choice_instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) => {
|
||||
Instruction::TryMeElse(ref mut o) => {
|
||||
retraction_info
|
||||
.push_record(RetractionRecord::ModifiedTryMeElse(inner_trust_me_loc, *o));
|
||||
|
||||
@@ -461,60 +460,55 @@ fn blunt_leading_choice_instr(
|
||||
) -> usize {
|
||||
loop {
|
||||
match &mut code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(o)) => {
|
||||
Instruction::RetryMeElse(o) => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedRetryMeElse(instr_loc, *o));
|
||||
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::TryMeElse(*o));
|
||||
|
||||
code[instr_loc] = Instruction::TryMeElse(*o);
|
||||
return instr_loc;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(_)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(_))) => {
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(_)) |
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(_)) => {
|
||||
return instr_loc;
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicElse(b, d, NextOrFail::Fail(o))) => {
|
||||
&mut Instruction::DynamicElse(b, d, NextOrFail::Fail(o)) => {
|
||||
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(
|
||||
instr_loc,
|
||||
NextOrFail::Fail(o),
|
||||
));
|
||||
|
||||
code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(b, d, NextOrFail::Next(0)));
|
||||
|
||||
code[instr_loc] = Instruction::DynamicElse(b, d, NextOrFail::Next(0));
|
||||
return instr_loc;
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
&mut Instruction::DynamicInternalElse(
|
||||
b,
|
||||
d,
|
||||
NextOrFail::Fail(o),
|
||||
)) => {
|
||||
) => {
|
||||
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(
|
||||
instr_loc,
|
||||
NextOrFail::Fail(o),
|
||||
));
|
||||
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
code[instr_loc] = Instruction::DynamicInternalElse(
|
||||
b,
|
||||
d,
|
||||
NextOrFail::Next(0),
|
||||
));
|
||||
);
|
||||
|
||||
return instr_loc;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TrustMe(o)) => {
|
||||
retraction_info
|
||||
.push_record(RetractionRecord::AppendedTrustMe(instr_loc, *o, false));
|
||||
Instruction::TrustMe(o) => {
|
||||
retraction_info.push_record(RetractionRecord::AppendedTrustMe(instr_loc, *o, false));
|
||||
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::TryMeElse(0));
|
||||
code[instr_loc] = Instruction::TryMeElse(0);
|
||||
return instr_loc + 1;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(0)) => {
|
||||
Instruction::TryMeElse(0) => {
|
||||
return instr_loc + 1;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(o)) => {
|
||||
Instruction::TryMeElse(o) => {
|
||||
instr_loc += *o;
|
||||
}
|
||||
Line::Control(ControlInstruction::RevJmpBy(o)) => {
|
||||
Instruction::RevJmpBy(o) => {
|
||||
instr_loc -= *o;
|
||||
}
|
||||
_ => {
|
||||
@@ -530,7 +524,7 @@ fn set_switch_var_offset_to_choice_instr(
|
||||
offset: usize,
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) {
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[index_loc]).unwrap();
|
||||
let target_indexing_line = code[index_loc].to_indexing_line_mut().unwrap();
|
||||
|
||||
let v = match &target_indexing_line[0] {
|
||||
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, v, ..)) => match v {
|
||||
@@ -543,9 +537,9 @@ fn set_switch_var_offset_to_choice_instr(
|
||||
};
|
||||
|
||||
match &code[index_loc + v] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(_))
|
||||
| Line::Choice(ChoiceInstruction::DynamicElse(..))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(..)) => {}
|
||||
Instruction::TryMeElse(_) |
|
||||
Instruction::DynamicElse(..) |
|
||||
Instruction::DynamicInternalElse(..) => {}
|
||||
_ => {
|
||||
set_switch_var_offset(code, index_loc, offset, retraction_info);
|
||||
}
|
||||
@@ -559,7 +553,7 @@ fn set_switch_var_offset(
|
||||
offset: usize,
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) {
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[index_loc]).unwrap();
|
||||
let target_indexing_line = code[index_loc].to_indexing_line_mut().unwrap();
|
||||
|
||||
let old_v = match &mut target_indexing_line[0] {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, ref mut v, ..)) => match *v {
|
||||
@@ -585,72 +579,67 @@ fn internalize_choice_instr_at(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) {
|
||||
match &mut code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Fail(_)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Fail(_))) => {}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, ref mut o @ NextOrFail::Next(0))) => {
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Fail(_)) |
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(_)) => {
|
||||
}
|
||||
Instruction::DynamicElse(_, _, ref mut o @ NextOrFail::Next(0)) => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(instr_loc, 0));
|
||||
*o = NextOrFail::Fail(0);
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicElse(b, d, NextOrFail::Next(o))) => {
|
||||
&mut Instruction::DynamicElse(b, d, NextOrFail::Next(o)) => {
|
||||
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(
|
||||
instr_loc,
|
||||
NextOrFail::Next(o),
|
||||
));
|
||||
|
||||
match &mut code[instr_loc + o] {
|
||||
Line::Control(ControlInstruction::RevJmpBy(p)) if *p == 0 => {
|
||||
code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(b, d, NextOrFail::Fail(o)));
|
||||
Instruction::RevJmpBy(p) if *p == 0 => {
|
||||
code[instr_loc] = Instruction::DynamicElse(b, d, NextOrFail::Fail(o));
|
||||
}
|
||||
_ => {
|
||||
code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(b, d, NextOrFail::Next(o)));
|
||||
code[instr_loc] = Instruction::DynamicElse(b, d, NextOrFail::Next(o));
|
||||
}
|
||||
}
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
ref mut o @ NextOrFail::Next(0),
|
||||
)) => {
|
||||
Instruction::DynamicInternalElse(_, _, ref mut o @ NextOrFail::Next(0)) => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(instr_loc, 0));
|
||||
*o = NextOrFail::Fail(0);
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicInternalElse(b, d, NextOrFail::Next(o))) => {
|
||||
&mut Instruction::DynamicInternalElse(b, d, NextOrFail::Next(o)) => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(instr_loc, o));
|
||||
|
||||
match &mut code[instr_loc + o] {
|
||||
Line::Control(ControlInstruction::RevJmpBy(p)) if *p == 0 => {
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
Instruction::RevJmpBy(p) if *p == 0 => {
|
||||
code[instr_loc] = Instruction::DynamicInternalElse(
|
||||
b,
|
||||
d,
|
||||
NextOrFail::Fail(o),
|
||||
));
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
code[instr_loc] = Instruction::DynamicInternalElse(
|
||||
b,
|
||||
d,
|
||||
NextOrFail::Next(o),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(0)) => {
|
||||
Instruction::TryMeElse(0) => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(instr_loc, 0));
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::TrustMe(0));
|
||||
code[instr_loc] = Instruction::TrustMe(0);
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(o)) => {
|
||||
Instruction::TryMeElse(o) => {
|
||||
let o = *o;
|
||||
|
||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(instr_loc, o));
|
||||
|
||||
match &mut code[instr_loc + o] {
|
||||
Line::Control(ControlInstruction::RevJmpBy(p)) if *p == 0 => {
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::TrustMe(o));
|
||||
Instruction::RevJmpBy(p) if *p == 0 => {
|
||||
code[instr_loc] = Instruction::TrustMe(o);
|
||||
}
|
||||
_ => {
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::RetryMeElse(o));
|
||||
code[instr_loc] = Instruction::RetryMeElse(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -668,8 +657,7 @@ fn thread_choice_instr_at_to(
|
||||
) {
|
||||
loop {
|
||||
match &mut code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o))
|
||||
| Line::Choice(ChoiceInstruction::RetryMeElse(ref mut o))
|
||||
Instruction::TryMeElse(ref mut o) | Instruction::RetryMeElse(ref mut o)
|
||||
if target_loc >= instr_loc =>
|
||||
{
|
||||
retraction_info.push_record(RetractionRecord::ReplacedChoiceOffset(instr_loc, *o));
|
||||
@@ -677,82 +665,80 @@ fn thread_choice_instr_at_to(
|
||||
*o = target_loc - instr_loc;
|
||||
return;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(ref mut o)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(ref mut o)) |
|
||||
Instruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
NextOrFail::Next(ref mut o),
|
||||
)) if target_loc >= instr_loc => {
|
||||
) if target_loc >= instr_loc => {
|
||||
retraction_info
|
||||
.push_record(RetractionRecord::ReplacedDynamicElseOffset(instr_loc, *o));
|
||||
*o = target_loc - instr_loc;
|
||||
return;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(o)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(o))) => {
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(o)) |
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(o)) => {
|
||||
instr_loc += *o;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(o))
|
||||
| Line::Choice(ChoiceInstruction::RetryMeElse(o)) => {
|
||||
Instruction::TryMeElse(o)
|
||||
| Instruction::RetryMeElse(o) => {
|
||||
instr_loc += *o;
|
||||
}
|
||||
Line::Control(ControlInstruction::RevJmpBy(ref mut o)) if instr_loc >= target_loc => {
|
||||
Instruction::RevJmpBy(ref mut o) if instr_loc >= target_loc => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedRevJmpBy(instr_loc, *o));
|
||||
|
||||
*o = instr_loc - target_loc;
|
||||
return;
|
||||
}
|
||||
&mut Line::Control(ControlInstruction::RevJmpBy(o)) => {
|
||||
&mut Instruction::RevJmpBy(o) => {
|
||||
instr_loc -= o;
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicElse(birth, death, ref mut fail))
|
||||
&mut Instruction::DynamicElse(birth, death, ref mut fail)
|
||||
if target_loc >= instr_loc =>
|
||||
{
|
||||
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(instr_loc, *fail));
|
||||
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::DynamicElse(
|
||||
code[instr_loc] = instr!("dynamic_else",
|
||||
birth,
|
||||
death,
|
||||
NextOrFail::Next(target_loc - instr_loc),
|
||||
));
|
||||
NextOrFail::Next(target_loc - instr_loc)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Fail(o))) if *o > 0 => {
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Fail(o)) if *o > 0 => {
|
||||
instr_loc += *o;
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
&mut Instruction::DynamicInternalElse(
|
||||
birth,
|
||||
death,
|
||||
ref mut fail,
|
||||
)) if target_loc >= instr_loc => {
|
||||
) if target_loc >= instr_loc => {
|
||||
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(instr_loc, *fail));
|
||||
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
code[instr_loc] = instr!("dynamic_internal_else",
|
||||
birth,
|
||||
death,
|
||||
NextOrFail::Next(target_loc - instr_loc),
|
||||
));
|
||||
NextOrFail::Next(target_loc - instr_loc)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Fail(o)))
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(o))
|
||||
if *o > 0 =>
|
||||
{
|
||||
instr_loc += *o;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TrustMe(ref mut o)) if target_loc >= instr_loc => {
|
||||
Instruction::TrustMe(ref mut o) if target_loc >= instr_loc => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::AppendedTrustMe(instr_loc, *o, false),
|
||||
//choice_instr.is_default()),
|
||||
);
|
||||
|
||||
code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(target_loc - instr_loc));
|
||||
|
||||
code[instr_loc] = instr!("retry_me_else", target_loc - instr_loc);
|
||||
return;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TrustMe(o)) if *o > 0 => {
|
||||
Instruction::TrustMe(o) if *o > 0 => {
|
||||
instr_loc += *o;
|
||||
}
|
||||
_ => {
|
||||
@@ -769,7 +755,7 @@ fn remove_non_leading_clause(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) -> Option<IndexPtr> {
|
||||
match &mut code[non_indexed_choice_instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(ref mut o)) => {
|
||||
Instruction::RetryMeElse(ref mut o) => {
|
||||
let o = *o;
|
||||
|
||||
thread_choice_instr_at_to(
|
||||
@@ -781,19 +767,19 @@ fn remove_non_leading_clause(
|
||||
|
||||
None
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TrustMe(_)) => {
|
||||
Instruction::TrustMe(_) => {
|
||||
match &mut code[preceding_choice_instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(o)) => {
|
||||
Instruction::RetryMeElse(o) => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedRetryMeElse(
|
||||
preceding_choice_instr_loc,
|
||||
*o,
|
||||
));
|
||||
|
||||
code[preceding_choice_instr_loc] = Line::Choice(ChoiceInstruction::TrustMe(0));
|
||||
code[preceding_choice_instr_loc] = Instruction::TrustMe(0);
|
||||
|
||||
None
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) => {
|
||||
Instruction::TryMeElse(ref mut o) => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
|
||||
preceding_choice_instr_loc,
|
||||
*o,
|
||||
@@ -850,7 +836,7 @@ fn remove_leading_unindexed_clause(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) -> Option<IndexPtr> {
|
||||
match &mut code[non_indexed_choice_instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) => {
|
||||
Instruction::TryMeElse(ref mut o) => {
|
||||
if *o > 0 {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
|
||||
non_indexed_choice_instr_loc,
|
||||
@@ -878,7 +864,7 @@ fn remove_leading_unindexed_clause(
|
||||
|
||||
fn find_dynamic_outer_choice_instr(code: &Code, index_loc: usize) -> usize {
|
||||
match &code[index_loc] {
|
||||
Line::IndexingCode(indexing_code) => match &indexing_code[0] {
|
||||
Instruction::IndexingCode(indexing_code) => match &indexing_code[0] {
|
||||
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
IndexingCodePtr::DynamicExternal(v),
|
||||
@@ -951,22 +937,16 @@ fn prepend_compiled_clause(
|
||||
let inner_thread_rev_offset =
|
||||
3 + prepend_queue.len() + clause_loc - skeleton.clauses[1].clause_start;
|
||||
|
||||
prepend_queue.push_back(Line::Control(ControlInstruction::RevJmpBy(
|
||||
inner_thread_rev_offset,
|
||||
)));
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(inner_thread_rev_offset));
|
||||
|
||||
prepend_queue.push_front(Line::Choice(
|
||||
settings.internal_try_me_else(prepend_queue.len()),
|
||||
));
|
||||
prepend_queue.push_front(settings.internal_try_me_else(prepend_queue.len()));
|
||||
|
||||
// prepend_queue is now:
|
||||
// | TryMeElse N_2
|
||||
// | (clause_code)
|
||||
// +N_2 | RevJmpBy (RetryMeElse(M_1) or TryMeElse(0) at index_loc + 1)
|
||||
|
||||
prepend_queue.push_front(Line::Control(ControlInstruction::RevJmpBy(
|
||||
1 + clause_loc - index_loc,
|
||||
)));
|
||||
prepend_queue.push_front(Instruction::RevJmpBy(1 + clause_loc - index_loc));
|
||||
|
||||
let outer_thread_choice_offset = // outer_thread_choice_loc WAS index_loc - 1..
|
||||
match derelictize_try_me_else(code, outer_thread_choice_loc, retraction_info) {
|
||||
@@ -978,7 +958,7 @@ fn prepend_compiled_clause(
|
||||
next_subseq_offset;
|
||||
|
||||
prepend_queue.push_back(
|
||||
Line::Control(ControlInstruction::RevJmpBy(outer_thread_rev_offset))
|
||||
Instruction::RevJmpBy(outer_thread_rev_offset)
|
||||
);
|
||||
|
||||
prepend_queue.len()
|
||||
@@ -994,17 +974,13 @@ fn prepend_compiled_clause(
|
||||
// awaiting the addition of unindexed
|
||||
// clauses.
|
||||
|
||||
prepend_queue.push_back(
|
||||
Line::Control(ControlInstruction::RevJmpBy(0)),
|
||||
);
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(0));
|
||||
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
prepend_queue.push_front(Line::Choice(
|
||||
settings.try_me_else(outer_thread_choice_offset),
|
||||
));
|
||||
prepend_queue.push_front(settings.try_me_else(outer_thread_choice_offset));
|
||||
|
||||
// prepend_queue is now:
|
||||
// | TryMeElse N_3
|
||||
@@ -1014,7 +990,7 @@ fn prepend_compiled_clause(
|
||||
// N_2 | RevJmpBy (RetryMeElse(M_1) or TryMeElse(0) at index_loc + 1)
|
||||
// N_3 | RevJmpBy (TryMeElse(N_1) at index_loc - 1 or TrustMe if N_1 == 0)
|
||||
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[index_loc]).unwrap();
|
||||
let target_indexing_line = code[index_loc].to_indexing_line_mut().unwrap();
|
||||
|
||||
merge_clause_index(
|
||||
target_indexing_line,
|
||||
@@ -1060,19 +1036,19 @@ fn prepend_compiled_clause(
|
||||
|
||||
// this is a stub for chaining inner-threaded choice
|
||||
// instructions.
|
||||
prepend_queue.push_back(Line::Control(ControlInstruction::RevJmpBy(0)));
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(0));
|
||||
|
||||
let prepend_queue_len = prepend_queue.len();
|
||||
|
||||
match &mut prepend_queue[1] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) if *o == 0 => {
|
||||
Instruction::TryMeElse(ref mut o) if *o == 0 => {
|
||||
*o = prepend_queue_len - 2;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
Instruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
ref mut o @ NextOrFail::Next(0),
|
||||
)) => {
|
||||
) => {
|
||||
*o = NextOrFail::Fail(prepend_queue_len - 2);
|
||||
}
|
||||
_ => {
|
||||
@@ -1080,11 +1056,8 @@ fn prepend_compiled_clause(
|
||||
}
|
||||
}
|
||||
|
||||
prepend_queue.push_back(Line::Control(ControlInstruction::RevJmpBy(
|
||||
inner_thread_rev_offset,
|
||||
)));
|
||||
|
||||
prepend_queue.push_front(Line::Choice(settings.try_me_else(prepend_queue.len())));
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(inner_thread_rev_offset));
|
||||
prepend_queue.push_front(settings.try_me_else(prepend_queue.len()));
|
||||
|
||||
// prepend_queue is now:
|
||||
// | TryMeElse(N_2)
|
||||
@@ -1114,11 +1087,8 @@ fn prepend_compiled_clause(
|
||||
let inner_thread_rev_offset =
|
||||
1 + prepend_queue.len() + clause_loc - old_clause_start;
|
||||
|
||||
prepend_queue.push_back(Line::Control(ControlInstruction::RevJmpBy(
|
||||
inner_thread_rev_offset,
|
||||
)));
|
||||
|
||||
prepend_queue.push_front(Line::Choice(settings.try_me_else(prepend_queue.len())));
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(inner_thread_rev_offset));
|
||||
prepend_queue.push_front(settings.try_me_else(prepend_queue.len()));
|
||||
|
||||
// prepend_queue is now:
|
||||
// | TryMeElse(N_2)
|
||||
@@ -1142,11 +1112,8 @@ fn prepend_compiled_clause(
|
||||
let inner_thread_rev_offset =
|
||||
1 + prepend_queue.len() + clause_loc - old_clause_start;
|
||||
|
||||
prepend_queue.push_back(Line::Control(ControlInstruction::RevJmpBy(
|
||||
inner_thread_rev_offset,
|
||||
)));
|
||||
|
||||
prepend_queue.push_front(Line::Choice(settings.try_me_else(prepend_queue.len())));
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(inner_thread_rev_offset));
|
||||
prepend_queue.push_front(settings.try_me_else(prepend_queue.len()));
|
||||
|
||||
// prepend_queue is now:
|
||||
// | TryMeElse(N_2)
|
||||
@@ -1205,7 +1172,7 @@ fn append_compiled_clause(
|
||||
.switch_on_term_loc()
|
||||
{
|
||||
Some(index_loc) if lower_bound_arg_num == target_arg_num => {
|
||||
code.push(Line::Choice(settings.internal_trust_me()));
|
||||
code.push(settings.internal_trust_me());
|
||||
|
||||
code.extend(clause_code.drain(3..)); // skip the indexing code
|
||||
|
||||
@@ -1218,7 +1185,7 @@ fn append_compiled_clause(
|
||||
skeleton.clauses[target_pos].clause_start,
|
||||
));
|
||||
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[index_loc]).unwrap();
|
||||
let target_indexing_line = code[index_loc].to_indexing_line_mut().unwrap();
|
||||
|
||||
merge_clause_index(
|
||||
target_indexing_line,
|
||||
@@ -1252,7 +1219,7 @@ fn append_compiled_clause(
|
||||
target_pos_clause_start // skeleton.clauses[target_pos - 1].clause_start
|
||||
}
|
||||
_ => {
|
||||
code.push(Line::Choice(settings.trust_me()));
|
||||
code.push(settings.trust_me());
|
||||
|
||||
skeleton.clauses[target_pos].opt_arg_index_key += clause_loc;
|
||||
code.extend(clause_code.drain(1..));
|
||||
@@ -1331,9 +1298,9 @@ fn print_overwrite_warning(
|
||||
key: &PredicateKey,
|
||||
is_dynamic: bool,
|
||||
) {
|
||||
if let CompilationTarget::Module(ref module_name) = compilation_target {
|
||||
match module_name.as_str() {
|
||||
"builtins" | "loader" => return,
|
||||
if let CompilationTarget::Module(module_name) = compilation_target {
|
||||
match module_name {
|
||||
atom!("builtins") | atom!("loader") => return,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -1405,7 +1372,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
) -> Result<CodeIndex, SessionError> {
|
||||
let code_index = self.get_or_insert_code_index(key, predicates.compilation_target);
|
||||
|
||||
let code_len = self.wam_prelude.code_repo.code.len();
|
||||
let code_len = self.wam_prelude.code.len();
|
||||
let mut code_ptr = code_len;
|
||||
|
||||
let mut clauses = vec![];
|
||||
@@ -1443,7 +1410,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
|
||||
match &mut code[0] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(0)) => {
|
||||
Instruction::TryMeElse(0) => {
|
||||
code_ptr += 1;
|
||||
}
|
||||
_ => {}
|
||||
@@ -1514,7 +1481,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
index_ptr,
|
||||
);
|
||||
|
||||
self.wam_prelude.code_repo.code.extend(code.into_iter());
|
||||
self.wam_prelude.code.extend(code.into_iter());
|
||||
Ok(code_index)
|
||||
}
|
||||
|
||||
@@ -1690,7 +1657,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
mut standalone_skeleton,
|
||||
} = self.compile_standalone_clause(clause, settings)?;
|
||||
|
||||
let code_len = self.wam_prelude.code_repo.code.len();
|
||||
let code_len = self.wam_prelude.code.len();
|
||||
|
||||
let skeleton = match self
|
||||
.wam_prelude
|
||||
@@ -1717,7 +1684,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
let global_clock = LS::machine_st(&mut self.payload).global_clock;
|
||||
|
||||
let result = append_compiled_clause(
|
||||
&mut self.wam_prelude.code_repo.code,
|
||||
&mut self.wam_prelude.code,
|
||||
clause_code,
|
||||
skeleton,
|
||||
&mut self.payload.retraction_info,
|
||||
@@ -1757,7 +1724,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
let global_clock = LS::machine_st(&mut self.payload).global_clock;
|
||||
|
||||
let new_code_ptr = prepend_compiled_clause(
|
||||
&mut self.wam_prelude.code_repo.code,
|
||||
&mut self.wam_prelude.code,
|
||||
compilation_target,
|
||||
key,
|
||||
clause_code,
|
||||
@@ -1801,16 +1768,16 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
.switch_on_term_loc()
|
||||
{
|
||||
Some(index_loc) => find_inner_choice_instr(
|
||||
&self.wam_prelude.code_repo.code,
|
||||
&self.wam_prelude.code,
|
||||
skeleton.clauses[target_pos].clause_start,
|
||||
index_loc,
|
||||
),
|
||||
None => skeleton.clauses[target_pos].clause_start,
|
||||
};
|
||||
|
||||
match &mut self.wam_prelude.code_repo.code[clause_loc] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, ref mut d, _))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, ref mut d, _)) => {
|
||||
match &mut self.wam_prelude.code[clause_loc] {
|
||||
Instruction::DynamicElse(_, ref mut d, _) |
|
||||
Instruction::DynamicInternalElse(_, ref mut d, _) => {
|
||||
*d = Death::Finite(LS::machine_st(&mut self.payload).global_clock);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
@@ -1840,7 +1807,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
};
|
||||
|
||||
let code = &mut self.wam_prelude.code_repo.code;
|
||||
let code = &mut self.wam_prelude.code;
|
||||
let lower_bound = lower_bound_of_target_clause(skeleton, target_pos);
|
||||
let lower_bound_is_unindexed = !skeleton.clauses[lower_bound].opt_arg_index_key.is_some();
|
||||
|
||||
@@ -1975,13 +1942,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
Some(later_indexing_loc) if later_indexing_loc < target_indexing_loc => {
|
||||
let target_indexing_line = mem::replace(
|
||||
&mut code[target_indexing_loc],
|
||||
Line::Control(ControlInstruction::RevJmpBy(
|
||||
target_indexing_loc - later_indexing_loc,
|
||||
)),
|
||||
Instruction::RevJmpBy(target_indexing_loc - later_indexing_loc),
|
||||
);
|
||||
|
||||
match target_indexing_line {
|
||||
Line::IndexingCode(indexing_code) => {
|
||||
Instruction::IndexingCode(indexing_code) => {
|
||||
self.payload.retraction_info.push_record(
|
||||
RetractionRecord::ReplacedIndexingLine(
|
||||
target_indexing_loc,
|
||||
@@ -2073,7 +2038,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
);
|
||||
|
||||
match &mut code[preceding_choice_instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(0)) => {
|
||||
Instruction::TryMeElse(0) => {
|
||||
set_switch_var_offset(
|
||||
code,
|
||||
index_loc,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,6 @@ use crate::types::*;
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
// TODO: rename to 'unmark_if_iter', 'mark_if_gc'
|
||||
pub(crate) trait UnmarkPolicy {
|
||||
fn unmark(heap: &mut [HeapCellValue], current: usize) -> bool;
|
||||
fn mark(heap: &mut [HeapCellValue], current: usize);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::partial_string::*;
|
||||
use crate::parser::ast::*;
|
||||
use crate::types::*;
|
||||
@@ -251,7 +250,7 @@ where
|
||||
filtered_iter_to_heap_list(heap, values, |_, _| true)
|
||||
}
|
||||
|
||||
pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<LocalCodePtr> {
|
||||
pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<usize> {
|
||||
let extract_integer = |s: usize| -> Option<usize> {
|
||||
match Number::try_from(heap[s]) {
|
||||
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
|
||||
@@ -265,7 +264,7 @@ pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<Loca
|
||||
let (name, arity) = cell_as_atom_cell!(heap[s]).get_name_and_arity();
|
||||
|
||||
if name == atom!("dir_entry") && arity == 1 {
|
||||
extract_integer(s+1).map(LocalCodePtr::DirEntry)
|
||||
extract_integer(s+1)
|
||||
} else {
|
||||
panic!(
|
||||
"to_local_code_ptr crashed with p.i. {}/{}",
|
||||
@@ -279,182 +278,3 @@ pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<Loca
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
#[inline]
|
||||
pub(crate) fn new() -> Self {
|
||||
HeapTemplate {
|
||||
buf: RawBlock::new(),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: move this to the WAM, then remove the temporary (and by
|
||||
// then, unnecessary and impossible) "arena" argument. OR, remove
|
||||
// this thing totally! if we can. by that I mean, just convert a
|
||||
// little to a HeapCellValue. don't bother writing to the
|
||||
// heap at all. Each of these data is either already inlinable in a
|
||||
// HeapCellValue or a pointer to an GC'ed location in memory.
|
||||
#[inline]
|
||||
pub(crate) fn put_literal(&mut self, literal: Literal) -> HeapCellValue {
|
||||
match literal {
|
||||
Literal::Atom(name) => atom_as_cell!(name),
|
||||
Literal::Char(c) => char_as_cell!(c),
|
||||
Literal::EmptyList => empty_list_as_cell!(),
|
||||
Literal::Fixnum(n) => fixnum_as_cell!(n),
|
||||
Literal::Integer(bigint_ptr) => {
|
||||
let h = self.push(typed_arena_ptr_as_cell!(bigint_ptr));
|
||||
self[h]
|
||||
}
|
||||
Literal::Rational(bigint_ptr) => {
|
||||
let h = self.push(typed_arena_ptr_as_cell!(bigint_ptr));
|
||||
self[h]
|
||||
}
|
||||
Literal::Float(f) => typed_arena_ptr_as_cell!(f),
|
||||
Literal::String(s) => {
|
||||
if s.as_str().is_empty() {
|
||||
empty_list_as_cell!()
|
||||
} else {
|
||||
// TODO: how do we know where the tail is located?? well, there is no tail. separate tag?
|
||||
untyped_arena_ptr_as_cell!(s) // self.put_complete_string(arena, &s)
|
||||
}
|
||||
} // Literal::Usize(n) => Addr::Usize(n),
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
self.h() == 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn pop(&mut self) {
|
||||
let h = self.h();
|
||||
|
||||
if h > 0 {
|
||||
self.truncate(h - 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn push(&mut self, val: HeapCellValue) -> usize {
|
||||
let h = self.h();
|
||||
|
||||
unsafe {
|
||||
let new_ptr = self.buf.alloc(mem::size_of::<HeapCellValue>());
|
||||
ptr::write(new_ptr as *mut _, val);
|
||||
}
|
||||
|
||||
h
|
||||
}
|
||||
|
||||
/*
|
||||
#[inline]
|
||||
pub(crate) fn atom_at(&self, h: usize) -> bool {
|
||||
if let HeapCellValue::Atom(..) = &self[h] {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn to_unifiable(&mut self, non_heap_value: HeapCellValue) -> Addr {
|
||||
match non_heap_value {
|
||||
HeapCellValue::Addr(addr) => addr,
|
||||
val @ HeapCellValue::Atom(..)
|
||||
| val @ HeapCellValue::Integer(_)
|
||||
| val @ HeapCellValue::DBRef(_)
|
||||
| val @ HeapCellValue::Rational(_) => Addr::Con(self.push(val)),
|
||||
val @ HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(self.push(val)),
|
||||
val @ HeapCellValue::NamedStr(..) => Addr::Str(self.push(val)),
|
||||
HeapCellValue::PartialString(pstr, has_tail) => {
|
||||
let h = self.push(HeapCellValue::PartialString(pstr, has_tail));
|
||||
|
||||
if has_tail {
|
||||
self.push(HeapCellValue::Addr(Addr::EmptyList));
|
||||
}
|
||||
|
||||
Addr::Con(h)
|
||||
}
|
||||
val @ HeapCellValue::Stream(..) => Addr::Stream(self.push(val)),
|
||||
val @ HeapCellValue::TcpListener(..) => Addr::TcpListener(self.push(val)),
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn truncate(&mut self, h: usize) {
|
||||
let new_ptr = self.buf.top as usize - h * mem::size_of::<HeapCellValue>();
|
||||
self.buf.ptr = new_ptr as *mut _;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn h(&self) -> usize {
|
||||
(self.buf.top as usize - self.buf.ptr as usize) / mem::size_of::<HeapCellValue>()
|
||||
}
|
||||
|
||||
pub(crate) fn append(&mut self, vals: Vec<HeapCellValue>) {
|
||||
for val in vals {
|
||||
self.push(val);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn clear(&mut self) {
|
||||
if !self.buf.base.is_null() {
|
||||
self.truncate(0);
|
||||
self.buf.top = self.buf.base;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: get rid of this!!
|
||||
#[inline]
|
||||
pub(crate) fn index_addr<'a>(&'a self, addr: &Addr) -> RefOrOwned<'a, HeapCellValue> {
|
||||
match addr {
|
||||
&Addr::Con(h) | &Addr::Str(h) | &Addr::Stream(h) | &Addr::TcpListener(h) => {
|
||||
RefOrOwned::Borrowed(&self[h])
|
||||
}
|
||||
addr => RefOrOwned::Owned(HeapCellValue::Addr(*addr)),
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> Index<u64> for HeapTemplate<T> {
|
||||
type Output = HeapCellValue;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: u64) -> &Self::Output {
|
||||
unsafe {
|
||||
let ptr =
|
||||
self.buf.top as usize - (index as usize + 1) * mem::size_of::<HeapCellValue>();
|
||||
&*(ptr as *const HeapCellValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> Index<usize> for HeapTemplate<T> {
|
||||
type Output = HeapCellValue;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
unsafe {
|
||||
let ptr = self.buf.top as usize - (index + 1) * mem::size_of::<HeapCellValue>();
|
||||
&*(ptr as *const HeapCellValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> IndexMut<usize> for HeapTemplate<T> {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||
unsafe {
|
||||
let ptr = self.buf.top as usize - (index + 1) * mem::size_of::<HeapCellValue>();
|
||||
&mut *(ptr as *mut HeapCellValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::loader::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
@@ -8,6 +7,7 @@ use crate::machine::term_stream::*;
|
||||
use crate::machine::*;
|
||||
use crate::parser::ast::*;
|
||||
|
||||
use fxhash::FxBuildHasher;
|
||||
use indexmap::IndexSet;
|
||||
use ref_thread_local::RefThreadLocal;
|
||||
use slice_deque::{sdeq, SliceDeque};
|
||||
@@ -753,7 +753,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
pub(super) fn get_clause_type(&mut self, name: Atom, arity: usize) -> ClauseType {
|
||||
match ClauseType::from(name, arity) {
|
||||
ClauseType::Named(name, arity, _) => {
|
||||
ClauseType::Named(arity, name, _) => {
|
||||
let payload_compilation_target = self.payload.compilation_target;
|
||||
|
||||
let idx = self.get_or_insert_code_index(
|
||||
@@ -761,7 +761,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
payload_compilation_target,
|
||||
);
|
||||
|
||||
ClauseType::Named(name, arity, idx)
|
||||
ClauseType::Named(arity, name, idx)
|
||||
}
|
||||
ct => ct,
|
||||
}
|
||||
@@ -774,11 +774,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
arity: usize,
|
||||
) -> ClauseType {
|
||||
match ClauseType::from(name, arity) {
|
||||
ClauseType::Named(name, arity, _) => {
|
||||
ClauseType::Named(arity, name, _) => {
|
||||
let key = (name, arity);
|
||||
let idx = self.get_or_insert_qualified_code_index(module_name, key);
|
||||
|
||||
ClauseType::Named(name, arity, idx)
|
||||
ClauseType::Named(arity, name, idx)
|
||||
}
|
||||
ct => ct,
|
||||
}
|
||||
@@ -922,7 +922,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
let local_extensible_predicates = mem::replace(
|
||||
&mut module.local_extensible_predicates,
|
||||
LocalExtensiblePredicates::new(),
|
||||
LocalExtensiblePredicates::with_hasher(FxBuildHasher::default()),
|
||||
);
|
||||
|
||||
for ((compilation_target, key), skeleton) in local_extensible_predicates.iter() {
|
||||
@@ -1162,11 +1162,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
let subloader: Loader<'_, BootstrappingLoadState> = Loader {
|
||||
payload: BootstrappingLoadState(
|
||||
LoadStatePayload::new(self.wam_prelude.code_repo.code.len(), term_stream)
|
||||
LoadStatePayload::new(self.wam_prelude.code.len(), term_stream)
|
||||
),
|
||||
wam_prelude: MachinePreludeView {
|
||||
indices: self.wam_prelude.indices,
|
||||
code_repo: self.wam_prelude.code_repo,
|
||||
code: self.wam_prelude.code,
|
||||
load_contexts: self.wam_prelude.load_contexts,
|
||||
}
|
||||
};
|
||||
@@ -1225,11 +1225,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
let subloader: Loader<'_, BootstrappingLoadState> = Loader {
|
||||
payload: BootstrappingLoadState(
|
||||
LoadStatePayload::new(self.wam_prelude.code_repo.code.len(), term_stream),
|
||||
LoadStatePayload::new(self.wam_prelude.code.len(), term_stream),
|
||||
),
|
||||
wam_prelude: MachinePreludeView {
|
||||
indices: self.wam_prelude.indices,
|
||||
code_repo: self.wam_prelude.code_repo,
|
||||
code: self.wam_prelude.code,
|
||||
load_contexts: self.wam_prelude.load_contexts,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::heap_iter::*;
|
||||
use crate::indexing::*;
|
||||
@@ -327,7 +326,7 @@ impl<'a> LoadState<'a> for BootstrappingLoadState<'a> {
|
||||
loader.compile_and_submit()?;
|
||||
}
|
||||
|
||||
let repo_len = loader.wam_prelude.code_repo.code.len();
|
||||
let repo_len = loader.wam_prelude.code.len();
|
||||
|
||||
loader
|
||||
.payload
|
||||
@@ -363,7 +362,7 @@ pub struct Loader<'a, LS: LoadState<'a>> {
|
||||
impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
#[inline]
|
||||
pub(super) fn new(wam: &'a mut Machine, term_stream: <LS as LoadState<'a>>::TS) -> Self {
|
||||
let payload = LoadStatePayload::new(wam.code_repo.code.len(), term_stream);
|
||||
let payload = LoadStatePayload::new(wam.code.len(), term_stream);
|
||||
let (wam_prelude, machine_st) = wam.prelude_view_and_machine_st();
|
||||
|
||||
Self {
|
||||
@@ -696,8 +695,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
RetractionRecord::AddedIndex(index_key, clause_loc) => {
|
||||
// WAS: inner_index_locs) => {
|
||||
if let Some(index_loc) = index_key.switch_on_term_loc() {
|
||||
let indexing_code = match &mut self.wam_prelude.code_repo.code[index_loc] {
|
||||
Line::IndexingCode(indexing_code) => indexing_code,
|
||||
let indexing_code = match &mut self.wam_prelude.code[index_loc] {
|
||||
Instruction::IndexingCode(indexing_code) => indexing_code,
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
@@ -743,10 +742,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
// write the retraction logic of this arm.
|
||||
}
|
||||
RetractionRecord::ReplacedChoiceOffset(instr_loc, offset) => {
|
||||
match self.wam_prelude.code_repo.code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o))
|
||||
| Line::Choice(ChoiceInstruction::RetryMeElse(ref mut o))
|
||||
| Line::Choice(ChoiceInstruction::DefaultRetryMeElse(ref mut o)) => {
|
||||
match self.wam_prelude.code[instr_loc] {
|
||||
Instruction::TryMeElse(ref mut o) |
|
||||
Instruction::RetryMeElse(ref mut o) |
|
||||
Instruction::DefaultRetryMeElse(ref mut o) => {
|
||||
*o = offset;
|
||||
}
|
||||
_ => {
|
||||
@@ -755,22 +754,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
}
|
||||
RetractionRecord::AppendedTrustMe(instr_loc, offset, is_default) => {
|
||||
match self.wam_prelude.code_repo.code[instr_loc] {
|
||||
Line::Choice(ref mut choice_instr) => {
|
||||
*choice_instr = if is_default {
|
||||
ChoiceInstruction::DefaultTrustMe(offset)
|
||||
} else {
|
||||
ChoiceInstruction::TrustMe(offset)
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
self.wam_prelude.code[instr_loc] = if is_default {
|
||||
Instruction::DefaultTrustMe(offset)
|
||||
} else {
|
||||
Instruction::TrustMe(offset)
|
||||
};
|
||||
}
|
||||
RetractionRecord::ReplacedSwitchOnTermVarIndex(index_loc, old_v) => {
|
||||
match self.wam_prelude.code_repo.code[index_loc] {
|
||||
Line::IndexingCode(ref mut indexing_code) => match &mut indexing_code[0] {
|
||||
match self.wam_prelude.code[index_loc] {
|
||||
Instruction::IndexingCode(ref mut indexing_code) => match &mut indexing_code[0] {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
ref mut v,
|
||||
@@ -784,16 +776,13 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
}
|
||||
RetractionRecord::ModifiedTryMeElse(instr_loc, o) => {
|
||||
self.wam_prelude.code_repo.code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(o));
|
||||
self.wam_prelude.code[instr_loc] = Instruction::TryMeElse(o);
|
||||
}
|
||||
RetractionRecord::ModifiedRetryMeElse(instr_loc, o) => {
|
||||
self.wam_prelude.code_repo.code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(o));
|
||||
self.wam_prelude.code[instr_loc] = Instruction::RetryMeElse(o);
|
||||
}
|
||||
RetractionRecord::ModifiedRevJmpBy(instr_loc, o) => {
|
||||
self.wam_prelude.code_repo.code[instr_loc] =
|
||||
Line::Control(ControlInstruction::RevJmpBy(o));
|
||||
self.wam_prelude.code[instr_loc] = Instruction::RevJmpBy(o);
|
||||
}
|
||||
RetractionRecord::SkeletonClausePopBack(compilation_target, key) => {
|
||||
match self
|
||||
@@ -959,7 +948,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
}
|
||||
RetractionRecord::ReplacedIndexingLine(index_loc, indexing_code) => {
|
||||
self.wam_prelude.code_repo.code[index_loc] = Line::IndexingCode(indexing_code);
|
||||
self.wam_prelude.code[index_loc] = Instruction::IndexingCode(indexing_code);
|
||||
}
|
||||
RetractionRecord::RemovedLocalSkeletonClauseLocations(
|
||||
compilation_target,
|
||||
@@ -992,34 +981,34 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
}
|
||||
RetractionRecord::ReplacedDynamicElseOffset(instr_loc, next) => {
|
||||
match self.wam_prelude.code_repo.code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(
|
||||
match self.wam_prelude.code[instr_loc] {
|
||||
Instruction::DynamicElse(
|
||||
_,
|
||||
_,
|
||||
NextOrFail::Next(ref mut o),
|
||||
))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
)
|
||||
| Instruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
NextOrFail::Next(ref mut o),
|
||||
)) => {
|
||||
) => {
|
||||
*o = next;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
RetractionRecord::AppendedNextOrFail(instr_loc, fail) => {
|
||||
match self.wam_prelude.code_repo.code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(
|
||||
match self.wam_prelude.code[instr_loc] {
|
||||
Instruction::DynamicElse(
|
||||
_,
|
||||
_,
|
||||
ref mut next_or_fail,
|
||||
))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
)
|
||||
| Instruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
ref mut next_or_fail,
|
||||
)) => {
|
||||
) => {
|
||||
*next_or_fail = fail;
|
||||
}
|
||||
_ => {}
|
||||
@@ -1384,7 +1373,7 @@ impl<'a> MachinePreludeView<'a> {
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub(crate) fn use_module(&mut self) {
|
||||
pub(crate) fn use_module(&mut self) -> CallResult {
|
||||
let subevacuable_addr = self
|
||||
.machine_st
|
||||
.store(self.machine_st.deref(self.machine_st.registers[2]));
|
||||
@@ -1395,7 +1384,7 @@ impl Machine {
|
||||
match payload.compilation_target {
|
||||
CompilationTarget::Module(module_name) => module_name,
|
||||
CompilationTarget::User => {
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1415,10 +1404,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = use_module();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn load_compiled_library(&mut self) {
|
||||
pub(crate) fn load_compiled_library(&mut self) -> CallResult {
|
||||
let library = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -1426,7 +1415,7 @@ impl Machine {
|
||||
if let Some(module) = self.indices.modules.get(&library) {
|
||||
if let ListingSource::DynamicallyGenerated = module.listing_src {
|
||||
self.machine_st.fail = true;
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut loader = self.loader_from_heap_evacuable(temp_v!(3));
|
||||
@@ -1444,13 +1433,14 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = import_module();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
} else {
|
||||
self.machine_st.fail = true;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn declare_module(&mut self) {
|
||||
pub(crate) fn declare_module(&mut self) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -1471,34 +1461,34 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = declare_module();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn add_discontiguous_predicate(&mut self) {
|
||||
pub(crate) fn add_discontiguous_predicate(&mut self) -> CallResult {
|
||||
self.add_extensible_predicate_declaration(
|
||||
|loader, compilation_target, clause_name, arity| {
|
||||
loader.add_discontiguous_predicate(compilation_target, clause_name, arity)
|
||||
},
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn add_dynamic_predicate(&mut self) {
|
||||
pub(crate) fn add_dynamic_predicate(&mut self) -> CallResult {
|
||||
self.add_extensible_predicate_declaration(
|
||||
|loader, compilation_target, clause_name, arity| {
|
||||
loader.add_dynamic_predicate(compilation_target, clause_name, arity)
|
||||
},
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn add_multifile_predicate(&mut self) {
|
||||
pub(crate) fn add_multifile_predicate(&mut self) -> CallResult {
|
||||
self.add_extensible_predicate_declaration(
|
||||
|loader, compilation_target, clause_name, arity| {
|
||||
loader.add_multifile_predicate(compilation_target, clause_name, arity)
|
||||
},
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
fn add_extensible_predicate_declaration(
|
||||
@@ -1509,7 +1499,7 @@ impl Machine {
|
||||
Atom,
|
||||
usize,
|
||||
) -> Result<(), SessionError>,
|
||||
) {
|
||||
) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -1543,10 +1533,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = add_predicate_decl();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn add_term_expansion_clause(&mut self) {
|
||||
pub(crate) fn add_term_expansion_clause(&mut self) -> CallResult {
|
||||
let mut loader = self.loader_from_heap_evacuable(temp_v!(2));
|
||||
|
||||
let add_clause = || {
|
||||
@@ -1564,10 +1554,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = add_clause();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn add_goal_expansion_clause(&mut self) {
|
||||
pub(crate) fn add_goal_expansion_clause(&mut self) -> CallResult {
|
||||
let target_module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -1594,10 +1584,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = add_clause();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn add_in_situ_filename_module(&mut self) {
|
||||
pub(crate) fn add_in_situ_filename_module(&mut self) -> CallResult {
|
||||
let mut loader = self.loader_from_heap_evacuable(temp_v!(1));
|
||||
|
||||
let add_in_situ_filename_module = || {
|
||||
@@ -1643,7 +1633,7 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = add_in_situ_filename_module();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn loader_from_heap_evacuable<'a>(
|
||||
@@ -1668,15 +1658,13 @@ impl Machine {
|
||||
pub(crate) fn push_load_state_payload(&mut self) {
|
||||
let payload = arena_alloc!(
|
||||
LoadStatePayload::new(
|
||||
self.code_repo.code.len(),
|
||||
self.code.len(),
|
||||
LiveTermStream::new(ListingSource::User),
|
||||
),
|
||||
&mut self.machine_st.arena
|
||||
);
|
||||
|
||||
let var = self.machine_st.deref(
|
||||
self.machine_st.registers[1]
|
||||
);
|
||||
let var = self.machine_st.deref(self.machine_st.registers[1]);
|
||||
|
||||
self.machine_st.bind(
|
||||
var.as_var().unwrap(),
|
||||
@@ -1718,38 +1706,40 @@ impl Machine {
|
||||
self.load_contexts.pop();
|
||||
}
|
||||
|
||||
pub(crate) fn push_load_context(&mut self) {
|
||||
let stream = try_or_fail!(
|
||||
self.machine_st,
|
||||
self.machine_st.get_stream_or_alias(
|
||||
self.machine_st.registers[1],
|
||||
&self.indices.stream_aliases,
|
||||
atom!("$push_load_context"),
|
||||
2,
|
||||
)
|
||||
);
|
||||
pub(crate) fn push_load_context(&mut self) -> CallResult {
|
||||
let stream = self.machine_st.get_stream_or_alias(
|
||||
self.machine_st.registers[1],
|
||||
&self.indices.stream_aliases,
|
||||
atom!("$push_load_context"),
|
||||
2,
|
||||
)?;
|
||||
|
||||
let path = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[2]))
|
||||
);
|
||||
|
||||
self.load_contexts.push(LoadContext::new(path.as_str(), stream));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn restore_load_state_payload(
|
||||
&mut self,
|
||||
result: Result<TypedArenaPtr<LiveLoadState>, SessionError>,
|
||||
) {
|
||||
) -> CallResult {
|
||||
match result {
|
||||
Ok(_payload) => {
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
self.throw_session_error(e, (atom!("load"), 1));
|
||||
let err = self.machine_st.session_error(e);
|
||||
let stub = functor_stub(atom!("load"), 1);
|
||||
|
||||
Err(self.machine_st.error_form(err, stub))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn scoped_clause_to_evacuable(&mut self) {
|
||||
pub(crate) fn scoped_clause_to_evacuable(&mut self) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -1762,18 +1752,18 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = loader.read_and_enqueue_term(temp_v!(2), compilation_target);
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn clause_to_evacuable(&mut self) {
|
||||
pub(crate) fn clause_to_evacuable(&mut self) -> CallResult {
|
||||
let loader = self.loader_from_heap_evacuable(temp_v!(2));
|
||||
let compilation_target = loader.payload.compilation_target;
|
||||
|
||||
let result = loader.read_and_enqueue_term(temp_v!(1), compilation_target);
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn conclude_load(&mut self) {
|
||||
pub(crate) fn conclude_load(&mut self) -> CallResult {
|
||||
let mut loader = self.loader_from_heap_evacuable(temp_v!(1));
|
||||
|
||||
let compile_final_terms = || {
|
||||
@@ -1786,7 +1776,7 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = compile_final_terms();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn load_context_source(&mut self) {
|
||||
@@ -1852,7 +1842,7 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compile_assert<'a>(&'a mut self, append_or_prepend: AppendOrPrepend) {
|
||||
pub(crate) fn compile_assert<'a>(&'a mut self, append_or_prepend: AppendOrPrepend) -> CallResult {
|
||||
let key = self
|
||||
.machine_st
|
||||
.read_predicate_key(self.machine_st[temp_v!(3)], self.machine_st[temp_v!(4)]);
|
||||
@@ -1906,26 +1896,27 @@ impl Machine {
|
||||
};
|
||||
|
||||
match compile_assert() {
|
||||
Ok(_) => {}
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
let error_pi = match append_or_prepend {
|
||||
AppendOrPrepend::Append => (atom!("assertz"), 1),
|
||||
AppendOrPrepend::Prepend => (atom!("asserta"), 1),
|
||||
let stub = match append_or_prepend {
|
||||
AppendOrPrepend::Append => functor_stub(atom!("assertz"), 1),
|
||||
AppendOrPrepend::Prepend => functor_stub(atom!("asserta"), 1),
|
||||
};
|
||||
let err = self.machine_st.session_error(e);
|
||||
|
||||
self.throw_session_error(e, error_pi);
|
||||
Err(self.machine_st.error_form(err, stub))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn abolish_clause(&mut self) {
|
||||
pub(crate) fn abolish_clause(&mut self) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
|
||||
let key = self
|
||||
.machine_st
|
||||
.read_predicate_key(self.machine_st[temp_v!(2)], self.machine_st[temp_v!(3)]);
|
||||
.read_predicate_key(self.machine_st.registers[2], self.machine_st.registers[3]);
|
||||
|
||||
let compilation_target = match module_name {
|
||||
atom!("user") => CompilationTarget::User,
|
||||
@@ -2000,14 +1991,16 @@ impl Machine {
|
||||
};
|
||||
|
||||
match abolish_clause() {
|
||||
Ok(_) => {}
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
self.throw_session_error(e, (atom!("abolish"), 1));
|
||||
let stub = functor_stub(atom!("abolish"), 1);
|
||||
let err = self.machine_st.session_error(e);
|
||||
Err(self.machine_st.error_form(err, stub))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn retract_clause(&mut self) {
|
||||
pub(crate) fn retract_clause(&mut self) -> CallResult {
|
||||
let key = self
|
||||
.machine_st
|
||||
.read_predicate_key(self.machine_st[temp_v!(1)], self.machine_st[temp_v!(2)]);
|
||||
@@ -2066,14 +2059,17 @@ impl Machine {
|
||||
};
|
||||
|
||||
match retract_clause() {
|
||||
Ok(_) => {}
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
self.throw_session_error(e, (atom!("retract"), 1));
|
||||
let stub = functor_stub(atom!("retract"), 1);
|
||||
let err = self.machine_st.session_error(e);
|
||||
|
||||
Err(self.machine_st.error_form(err, stub))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_consistent_with_term_queue(&mut self) {
|
||||
pub(crate) fn is_consistent_with_term_queue(&mut self) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -2095,10 +2091,10 @@ impl Machine {
|
||||
|| !key.is_consistent(&loader.payload.predicates);
|
||||
|
||||
let result = LiveLoadAndMachineState::evacuate(loader);
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn flush_term_queue(&mut self) {
|
||||
pub(crate) fn flush_term_queue(&mut self) -> CallResult {
|
||||
let mut loader = self.loader_from_heap_evacuable(temp_v!(1));
|
||||
|
||||
let flush_term_queue = || {
|
||||
@@ -2110,10 +2106,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = flush_term_queue();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn remove_module_exports(&mut self) {
|
||||
pub(crate) fn remove_module_exports(&mut self) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -2126,10 +2122,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = remove_module_exports();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn add_non_counted_backtracking(&mut self) {
|
||||
pub(crate) fn add_non_counted_backtracking(&mut self) -> CallResult {
|
||||
let key = self
|
||||
.machine_st
|
||||
.read_predicate_key(self.machine_st[temp_v!(1)], self.machine_st[temp_v!(2)]);
|
||||
@@ -2138,7 +2134,7 @@ impl Machine {
|
||||
loader.payload.non_counted_bt_preds.insert(key);
|
||||
|
||||
let result = LiveLoadAndMachineState::evacuate(loader);
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn meta_predicate_property(&mut self) {
|
||||
@@ -2271,10 +2267,10 @@ impl Machine {
|
||||
.read_predicate_key(self.machine_st.registers[1], self.machine_st.registers[2]);
|
||||
|
||||
match ClauseType::from(key.0, key.1) {
|
||||
ClauseType::BuiltIn(_) | ClauseType::Inlined(..) | ClauseType::CallN => {
|
||||
ClauseType::BuiltIn(_) | ClauseType::Inlined(..) | ClauseType::CallN(_) => {
|
||||
return;
|
||||
}
|
||||
ClauseType::Named(name, arity, _) => {
|
||||
ClauseType::Named(arity, name, _) => {
|
||||
if let Some(module) = self.indices.modules.get(&(atom!("builtins"))) {
|
||||
self.machine_st.fail = !module.code_dir.contains_key(&(name, arity));
|
||||
return;
|
||||
|
||||
@@ -538,13 +538,18 @@ impl MachineState {
|
||||
|
||||
pub(super) fn throw_exception(&mut self, err: MachineStub) {
|
||||
let h = self.heap.len();
|
||||
let err_len = err.len();
|
||||
|
||||
self.ball.boundary = 0;
|
||||
self.ball.stub.truncate(0);
|
||||
|
||||
self.heap.extend(err.into_iter());
|
||||
|
||||
self.registers[1] = str_loc_as_cell!(h);
|
||||
self.registers[1] = if err_len == 1 {
|
||||
heap_loc_as_cell!(h)
|
||||
} else {
|
||||
str_loc_as_cell!(h)
|
||||
};
|
||||
|
||||
self.set_ball();
|
||||
self.unwind_stack();
|
||||
|
||||
@@ -2,30 +2,22 @@ use crate::parser::ast::*;
|
||||
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::loader::*;
|
||||
use crate::machine::machine_errors::MachineStub;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::machine::streams::Stream;
|
||||
|
||||
use fxhash::FxBuildHasher;
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::BTreeSet;
|
||||
use std::ops::{Add, AddAssign, Deref, Sub, SubAssign};
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
// these statics store the locations of one-off control instructions
|
||||
// in the code vector.
|
||||
|
||||
pub static HALT_CODE: usize = 0;
|
||||
|
||||
use crate::types::*;
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub(crate) struct OrderedOpDirKey(pub(crate) Atom, pub(crate) Fixity);
|
||||
@@ -134,6 +126,7 @@ impl Default for CodeIndex {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
|
||||
pub enum REPLCodePtr {
|
||||
AddDiscontiguousPredicate,
|
||||
@@ -174,158 +167,30 @@ pub enum REPLCodePtr {
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum CodePtr {
|
||||
BuiltInClause(BuiltInClauseType, LocalCodePtr), // local is the successor call.
|
||||
CallN(usize, LocalCodePtr, bool), // arity, local, last call.
|
||||
Local(LocalCodePtr),
|
||||
REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
|
||||
BuiltInClause(BuiltInClauseType, usize), // local is the successor call.
|
||||
CallN(usize, usize, bool), // arity, local, last call.
|
||||
Local(usize),
|
||||
REPL(REPLCodePtr, usize), // the REPL code, the return pointer.
|
||||
VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir.
|
||||
}
|
||||
|
||||
impl CodePtr {
|
||||
pub(crate) fn local(&self) -> LocalCodePtr {
|
||||
pub(crate) fn local(&self) -> usize {
|
||||
match self {
|
||||
&CodePtr::BuiltInClause(_, ref local)
|
||||
| &CodePtr::CallN(_, ref local, _)
|
||||
| &CodePtr::Local(ref local) => local.clone(),
|
||||
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
|
||||
&CodePtr::REPL(_, p) => p, // | &CodePtr::DynamicTransaction(_, p) => p,
|
||||
&CodePtr::BuiltInClause(_, ref local) |
|
||||
&CodePtr::CallN(_, ref local, _) |
|
||||
&CodePtr::Local(ref local) => *local,
|
||||
&CodePtr::VerifyAttrInterrupt(p) => p,
|
||||
&CodePtr::REPL(_, p) => p,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn is_halt(&self) -> bool {
|
||||
if let CodePtr::Local(LocalCodePtr::Halt) = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum LocalCodePtr {
|
||||
DirEntry(usize), // offset
|
||||
Halt,
|
||||
// IndexingBuf(usize, usize, usize), // DirEntry offset, first internal offset, second internal offset
|
||||
// TopLevel(usize, usize), // chunk_num, offset
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub(crate) fn is_reset_cont_marker(&self, p: LocalCodePtr) -> bool {
|
||||
match self.code_repo.lookup_instr(&self.machine_st, &CodePtr::Local(p)) {
|
||||
Some(line) => match line.as_ref(&self.code_repo.code) {
|
||||
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
|
||||
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl LocalCodePtr {
|
||||
pub fn assign_if_local(&mut self, cp: CodePtr) {
|
||||
match cp {
|
||||
CodePtr::Local(local) => *self = local,
|
||||
pub fn assign_if_local(&self, cp: &mut usize) {
|
||||
match self {
|
||||
CodePtr::Local(local) => *cp = *local,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn abs_loc(&self) -> usize {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(ref p) => *p,
|
||||
// LocalCodePtr::IndexingBuf(ref p, ..) => *p,
|
||||
LocalCodePtr::Halt => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn as_functor(&self) -> MachineStub {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) => {
|
||||
functor!(atom!("dir_entry"), [fixnum(*p)])
|
||||
}
|
||||
LocalCodePtr::Halt => {
|
||||
functor!(atom!("halt"))
|
||||
}
|
||||
/*
|
||||
LocalCodePtr::IndexingBuf(p, o, i) => {
|
||||
functor!(
|
||||
atom!("indexed_buf"),
|
||||
[fixnum(*p), fixnum(*o), fixnum(*i)]
|
||||
)
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CodePtr {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
CodePtr::Local(LocalCodePtr::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for LocalCodePtr {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
LocalCodePtr::DirEntry(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<usize> for LocalCodePtr {
|
||||
type Output = LocalCodePtr;
|
||||
|
||||
#[inline]
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p + rhs),
|
||||
LocalCodePtr::Halt => unreachable!(),
|
||||
// LocalCodePtr::IndexingBuf(p, o, i) => LocalCodePtr::IndexingBuf(p, o, i + rhs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<usize> for LocalCodePtr {
|
||||
type Output = Option<LocalCodePtr>;
|
||||
|
||||
#[inline]
|
||||
fn sub(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) => p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
|
||||
LocalCodePtr::Halt => unreachable!(),
|
||||
// LocalCodePtr::IndexingBuf(p, o, i) => i
|
||||
// .checked_sub(rhs)
|
||||
// .map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SubAssign<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, rhs: usize) {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(ref mut p) => *p -= rhs,
|
||||
LocalCodePtr::Halt => unreachable!() // | LocalCodePtr::IndexingBuf(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn add_assign(&mut self, rhs: usize) {
|
||||
match self {
|
||||
&mut LocalCodePtr::DirEntry(ref mut i) => *i += rhs,
|
||||
// | &mut LocalCodePtr::IndexingBuf(_, _, ref mut i) => *i += rhs,
|
||||
&mut LocalCodePtr::Halt => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<usize> for CodePtr {
|
||||
@@ -333,7 +198,9 @@ impl Add<usize> for CodePtr {
|
||||
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => p,
|
||||
p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => {
|
||||
p
|
||||
}
|
||||
CodePtr::Local(local) => CodePtr::Local(local + rhs),
|
||||
CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => {
|
||||
CodePtr::Local(local + rhs)
|
||||
@@ -362,20 +229,30 @@ impl SubAssign<usize> for CodePtr {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type HeapVarDict = IndexMap<Rc<String>, HeapCellValue>;
|
||||
pub(crate) type AllocVarDict = IndexMap<Rc<String>, VarData>;
|
||||
impl Default for CodePtr {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
CodePtr::Local(0)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
pub(crate) type GlobalVarDir = IndexMap<Atom, (Ball, Option<HeapCellValue>)>;
|
||||
pub(crate) type HeapVarDict = IndexMap<Rc<String>, HeapCellValue, FxBuildHasher>;
|
||||
pub(crate) type AllocVarDict = IndexMap<Rc<String>, VarData, FxBuildHasher>;
|
||||
|
||||
pub(crate) type StreamAliasDir = IndexMap<Atom, Stream>;
|
||||
pub(crate) type GlobalVarDir = IndexMap<Atom, (Ball, Option<HeapCellValue>), FxBuildHasher>;
|
||||
|
||||
pub(crate) type StreamAliasDir = IndexMap<Atom, Stream, FxBuildHasher>;
|
||||
pub(crate) type StreamDir = BTreeSet<Stream>;
|
||||
|
||||
pub(crate) type MetaPredicateDir = IndexMap<PredicateKey, Vec<MetaSpec>>;
|
||||
pub(crate) type MetaPredicateDir = IndexMap<PredicateKey, Vec<MetaSpec>, FxBuildHasher>;
|
||||
|
||||
pub(crate) type ExtensiblePredicates = IndexMap<PredicateKey, PredicateSkeleton>;
|
||||
pub(crate) type ExtensiblePredicates = IndexMap<PredicateKey, PredicateSkeleton, FxBuildHasher>;
|
||||
|
||||
pub(crate) type LocalExtensiblePredicates =
|
||||
IndexMap<(CompilationTarget, PredicateKey), LocalPredicateSkeleton>;
|
||||
IndexMap<(CompilationTarget, PredicateKey), LocalPredicateSkeleton, FxBuildHasher>;
|
||||
|
||||
pub(crate) type CodeDir = IndexMap<PredicateKey, CodeIndex, FxBuildHasher>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IndexStore {
|
||||
@@ -504,14 +381,14 @@ impl IndexStore {
|
||||
) -> Option<CodeIndex> {
|
||||
if module == atom!("user") {
|
||||
match ClauseType::from(name, arity) {
|
||||
ClauseType::Named(name, arity, _) => self.code_dir.get(&(name, arity)).cloned(),
|
||||
ClauseType::Named(arity, name, _) => self.code_dir.get(&(name, arity)).cloned(),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
self.modules
|
||||
.get(&module)
|
||||
.and_then(|module| match ClauseType::from(name, arity) {
|
||||
ClauseType::Named(name, arity, _) => {
|
||||
ClauseType::Named(arity, name, _) => {
|
||||
module.code_dir.get(&(name, arity)).cloned()
|
||||
}
|
||||
_ => None,
|
||||
@@ -561,8 +438,10 @@ impl IndexStore {
|
||||
|
||||
#[inline]
|
||||
pub(super) fn new() -> Self {
|
||||
index_store!(CodeDir::new(), default_op_dir(), ModuleDir::new())
|
||||
index_store!(
|
||||
CodeDir::with_hasher(FxBuildHasher::default()),
|
||||
default_op_dir(),
|
||||
ModuleDir::with_hasher(FxBuildHasher::default())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type CodeDir = IndexMap<PredicateKey, CodeIndex>;
|
||||
|
||||
@@ -55,14 +55,14 @@ pub struct MachineState {
|
||||
pub arena: Arena,
|
||||
pub(super) pdl: Vec<HeapCellValue>,
|
||||
pub(super) s: HeapPtr,
|
||||
pub(super) p: CodePtr,
|
||||
pub(super) p: usize,
|
||||
pub(super) oip: u32, // first internal code ptr
|
||||
pub(super) iip : u32, // second internal code ptr
|
||||
pub(super) b: usize,
|
||||
pub(super) b0: usize,
|
||||
pub(super) e: usize,
|
||||
pub(super) num_of_args: usize,
|
||||
pub(super) cp: LocalCodePtr,
|
||||
pub(super) cp: usize,
|
||||
pub(super) attr_var_init: AttrVarInitializer,
|
||||
pub(super) fail: bool,
|
||||
pub heap: Heap,
|
||||
@@ -79,7 +79,6 @@ pub struct MachineState {
|
||||
// locations of cleaners, cut points, the previous block. for setup_call_cleanup.
|
||||
pub(super) cont_pts: Vec<(HeapCellValue, usize, usize)>,
|
||||
pub(super) cwil: CWIL,
|
||||
pub(super) last_call: bool, // TODO: REMOVE THIS.
|
||||
pub(crate) flags: MachineFlags,
|
||||
pub(crate) cc: usize,
|
||||
pub(crate) global_clock: usize,
|
||||
@@ -115,7 +114,6 @@ impl fmt::Debug for MachineState {
|
||||
.field("ball", &self.ball)
|
||||
.field("lifted_heap", &self.lifted_heap)
|
||||
.field("interms", &self.interms)
|
||||
.field("last_call", &self.last_call)
|
||||
.field("flags", &self.flags)
|
||||
.field("cc", &self.cc)
|
||||
.field("global_clock", &self.global_clock)
|
||||
@@ -365,6 +363,20 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
pub(crate) fn backtrack(&mut self) {
|
||||
let b = self.b;
|
||||
let or_frame = self.stack.index_or_frame(b);
|
||||
|
||||
self.b0 = or_frame.prelude.b0;
|
||||
self.p = or_frame.prelude.bp;
|
||||
|
||||
self.oip = or_frame.prelude.boip;
|
||||
self.iip = or_frame.prelude.biip;
|
||||
|
||||
self.pdl.clear();
|
||||
self.fail = false;
|
||||
}
|
||||
|
||||
pub(crate) fn increment_call_count(&mut self) -> CallResult {
|
||||
if self.cwil.inference_limit_exceeded || self.ball.stub.len() > 0 {
|
||||
return Ok(());
|
||||
@@ -422,17 +434,19 @@ impl MachineState {
|
||||
self.error_form(err, stub)
|
||||
}
|
||||
|
||||
pub(super) fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
self.cp.assign_if_local(self.p + 1);
|
||||
#[inline(always)]
|
||||
pub(super) fn call_at_index(&mut self, arity: usize, p: usize) {
|
||||
self.cp = self.p + 1;
|
||||
self.p = p;
|
||||
self.num_of_args = arity;
|
||||
self.b0 = self.b;
|
||||
self.p = CodePtr::Local(p);
|
||||
}
|
||||
|
||||
pub(super) fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
#[inline(always)]
|
||||
pub(super) fn execute_at_index(&mut self, arity: usize, p: usize) {
|
||||
self.num_of_args = arity;
|
||||
self.b0 = self.b;
|
||||
self.p = CodePtr::Local(p);
|
||||
self.p = p;
|
||||
}
|
||||
|
||||
pub fn read_term(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult {
|
||||
@@ -467,7 +481,7 @@ impl MachineState {
|
||||
|
||||
if stream.past_end_of_stream() {
|
||||
if EOFAction::Reset != stream.options().eof_action() {
|
||||
return return_from_clause!(self.last_call, self);
|
||||
return Ok(());
|
||||
} else if self.fail {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -710,7 +724,7 @@ impl MachineState {
|
||||
or_frame.prelude.e = self.e;
|
||||
or_frame.prelude.cp = self.cp;
|
||||
or_frame.prelude.b = self.b;
|
||||
or_frame.prelude.bp = self.p.local() + offset;
|
||||
or_frame.prelude.bp = self.p + offset;
|
||||
or_frame.prelude.boip = 0;
|
||||
or_frame.prelude.biip = 0;
|
||||
or_frame.prelude.tr = self.tr;
|
||||
@@ -720,7 +734,7 @@ impl MachineState {
|
||||
self.b = b;
|
||||
|
||||
for i in 0..n {
|
||||
self.stack[stack_loc!(OrFrame, b, i)] = self.registers[i+1];
|
||||
or_frame[i] = self.registers[i+1];
|
||||
}
|
||||
|
||||
self.hb = self.heap.len();
|
||||
@@ -737,7 +751,7 @@ impl MachineState {
|
||||
or_frame.prelude.e = self.e;
|
||||
or_frame.prelude.cp = self.cp;
|
||||
or_frame.prelude.b = self.b;
|
||||
or_frame.prelude.bp = self.p.local(); // + 1; in self.iip now!
|
||||
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;
|
||||
@@ -751,7 +765,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
self.hb = self.heap.len();
|
||||
self.p = CodePtr::Local(dir_entry!(self.p.local().abs_loc() + offset));
|
||||
self.p = self.p + offset;
|
||||
|
||||
self.oip = 0;
|
||||
self.iip = 0;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::types::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::heap_iter::*;
|
||||
use crate::machine::attributed_variables::*;
|
||||
use crate::machine::copier::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::Machine;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
@@ -23,11 +21,6 @@ use indexmap::IndexSet;
|
||||
use std::cmp::Ordering;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
// TODO: move this block to.. a place.
|
||||
impl Machine {
|
||||
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
pub(crate) fn new() -> Self {
|
||||
MachineState {
|
||||
@@ -35,14 +28,14 @@ impl MachineState {
|
||||
atom_tbl: AtomTable::new(),
|
||||
pdl: Vec::with_capacity(1024),
|
||||
s: HeapPtr::default(),
|
||||
p: CodePtr::default(),
|
||||
p: 0,
|
||||
oip: 0,
|
||||
iip: 0,
|
||||
b: 0,
|
||||
b0: 0,
|
||||
e: 0,
|
||||
num_of_args: 0,
|
||||
cp: LocalCodePtr::default(),
|
||||
cp: 0,
|
||||
attr_var_init: AttrVarInitializer::new(0),
|
||||
fail: false,
|
||||
heap: Heap::with_capacity(256 * 256),
|
||||
@@ -58,7 +51,6 @@ impl MachineState {
|
||||
interms: vec![Number::default();256],
|
||||
cont_pts: Vec::with_capacity(256),
|
||||
cwil: CWIL::new(),
|
||||
last_call: false,
|
||||
flags: MachineFlags::default(),
|
||||
cc: 0,
|
||||
global_clock: 0,
|
||||
@@ -202,16 +194,16 @@ impl MachineState {
|
||||
match r1.get_tag() {
|
||||
RefTag::StackCell => {
|
||||
self.stack[r1.get_value() as usize] = t2;
|
||||
self.trail(TrailRef::Ref(r1));
|
||||
}
|
||||
RefTag::HeapCell => {
|
||||
self.heap[r1.get_value() as usize] = t2;
|
||||
self.trail(TrailRef::Ref(r1));
|
||||
}
|
||||
RefTag::AttrVar => {
|
||||
self.bind_attr_var(r1.get_value() as usize, t2);
|
||||
}
|
||||
};
|
||||
|
||||
self.trail(TrailRef::Ref(r1));
|
||||
} else {
|
||||
read_heap_cell!(a2,
|
||||
(HeapCellValueTag::StackVar, s) => {
|
||||
@@ -864,17 +856,6 @@ impl MachineState {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn copy_term(&mut self, attr_var_policy: AttrVarPolicy) {
|
||||
let old_h = self.heap.len();
|
||||
|
||||
let a1 = self.registers[1];
|
||||
let a2 = self.registers[2];
|
||||
|
||||
copy_term(CopyTerm::new(self), a1, attr_var_policy);
|
||||
|
||||
unify_fn!(*self, heap_loc_as_cell!(old_h), a2);
|
||||
}
|
||||
|
||||
pub(super) fn unwind_stack(&mut self) {
|
||||
self.b = self.block;
|
||||
self.fail = true;
|
||||
@@ -1912,9 +1893,6 @@ impl MachineState {
|
||||
);
|
||||
}
|
||||
Some(PStrPrefixCmpResult { prefix_len, .. }) => {
|
||||
// TODO: this is woefully insufficient! you need to
|
||||
// match the remaining portion of string if offset <
|
||||
// pstr.len().
|
||||
let focus = heap_pstr_iter.focus();
|
||||
let tail_addr = self.heap[focus];
|
||||
|
||||
@@ -1996,23 +1974,7 @@ impl MachineState {
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn handle_internal_call_n(&mut self, arity: usize) {
|
||||
let arity = arity + 1;
|
||||
let pred = self.registers[1];
|
||||
|
||||
for i in 2..arity {
|
||||
self.registers[i - 1] = self.registers[i];
|
||||
}
|
||||
|
||||
if arity > 1 {
|
||||
self.registers[arity - 1] = pred;
|
||||
return;
|
||||
}
|
||||
|
||||
self.fail = true;
|
||||
}
|
||||
|
||||
pub(super) fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey> {
|
||||
pub(super) fn setup_call_n(&mut self, arity: usize) -> Result<PredicateKey, MachineStub> {
|
||||
let addr = self.store(self.deref(self.registers[arity]));
|
||||
|
||||
let (name, narity) = read_heap_cell!(addr,
|
||||
@@ -2022,10 +1984,7 @@ impl MachineState {
|
||||
if narity + arity > MAX_ARITY {
|
||||
let stub = functor_stub(atom!("call"), arity + 1);
|
||||
let err = self.representation_error(RepFlag::MaxArity);
|
||||
let representation_error = self.error_form(err, stub);
|
||||
|
||||
self.throw_exception(representation_error);
|
||||
return None;
|
||||
return Err(self.error_form(err, stub));
|
||||
}
|
||||
|
||||
for i in (1..arity).rev() {
|
||||
@@ -2039,12 +1998,8 @@ impl MachineState {
|
||||
(name, narity)
|
||||
}
|
||||
(HeapCellValueTag::Atom, (name, arity)) => {
|
||||
if arity == 0 {
|
||||
(name, 0)
|
||||
} else {
|
||||
self.fail = true;
|
||||
return None;
|
||||
}
|
||||
debug_assert_eq!(arity, 0);
|
||||
(name, 0)
|
||||
}
|
||||
(HeapCellValueTag::Char, c) => {
|
||||
(self.atom_tbl.build_with(&c.to_string()), 0)
|
||||
@@ -2052,22 +2007,16 @@ impl MachineState {
|
||||
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar, _h) => {
|
||||
let stub = functor_stub(atom!("call"), arity + 1);
|
||||
let err = self.instantiation_error();
|
||||
let instantiation_error = self.error_form(err, stub);
|
||||
|
||||
self.throw_exception(instantiation_error);
|
||||
return None;
|
||||
return Err(self.error_form(err, stub));
|
||||
}
|
||||
_ => {
|
||||
let stub = functor_stub(atom!("call"), arity + 1);
|
||||
let err = self.type_error(ValidType::Callable, addr);
|
||||
let type_error = self.error_form(err, stub);
|
||||
|
||||
self.throw_exception(type_error);
|
||||
return None;
|
||||
return Err(self.error_form(err, stub));
|
||||
}
|
||||
);
|
||||
|
||||
Some((name, arity + narity - 1))
|
||||
Ok((name, arity + narity - 1))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -2233,45 +2182,6 @@ impl MachineState {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn compare_numbers(&mut self, cmp: CompareNumberQT, n1: Number, n2: Number) {
|
||||
let ordering = n1.cmp(&n2);
|
||||
|
||||
self.fail = match cmp {
|
||||
CompareNumberQT::GreaterThan if ordering == Ordering::Greater => false,
|
||||
CompareNumberQT::GreaterThanOrEqual if ordering != Ordering::Less => false,
|
||||
CompareNumberQT::LessThan if ordering == Ordering::Less => false,
|
||||
CompareNumberQT::LessThanOrEqual if ordering != Ordering::Greater => false,
|
||||
CompareNumberQT::NotEqual if ordering != Ordering::Equal => false,
|
||||
CompareNumberQT::Equal if ordering == Ordering::Equal => false,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
self.p += 1;
|
||||
}
|
||||
|
||||
pub fn compare_term(&mut self, qt: CompareTermQT) {
|
||||
let a1 = self.registers[1];
|
||||
let a2 = self.registers[2];
|
||||
|
||||
match compare_term_test!(self, a1, a2) {
|
||||
Some(Ordering::Greater) => match qt {
|
||||
CompareTermQT::GreaterThan | CompareTermQT::GreaterThanOrEqual => {}
|
||||
_ => self.fail = true,
|
||||
},
|
||||
Some(Ordering::Equal) => match qt {
|
||||
CompareTermQT::GreaterThanOrEqual | CompareTermQT::LessThanOrEqual => {}
|
||||
_ => self.fail = true,
|
||||
},
|
||||
Some(Ordering::Less) => match qt {
|
||||
CompareTermQT::LessThan | CompareTermQT::LessThanOrEqual => {}
|
||||
_ => self.fail = true,
|
||||
},
|
||||
None => {
|
||||
self.fail = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns true on failure, false on success.
|
||||
pub fn eq_test(&mut self, h1: HeapCellValue, h2: HeapCellValue) -> bool {
|
||||
if h1 == h2 {
|
||||
@@ -2652,12 +2562,14 @@ impl MachineState {
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn setup_built_in_call(&mut self, ct: BuiltInClauseType) {
|
||||
self.num_of_args = ct.arity();
|
||||
self.b0 = self.b;
|
||||
|
||||
self.p = CodePtr::BuiltInClause(ct, self.p.local());
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn deallocate(&mut self) {
|
||||
let e = self.e;
|
||||
|
||||
@@ -227,7 +227,7 @@ impl Machine {
|
||||
let mut wam = Machine {
|
||||
machine_st,
|
||||
indices: IndexStore::new(),
|
||||
code_repo: CodeRepo::new(),
|
||||
code: Code::new(),
|
||||
user_input,
|
||||
user_output,
|
||||
user_error,
|
||||
@@ -239,6 +239,8 @@ impl Machine {
|
||||
lib_path.pop();
|
||||
lib_path.push("lib");
|
||||
|
||||
wam.add_impls_to_indices();
|
||||
|
||||
bootstrapping_compile(
|
||||
Stream::from_static_string(
|
||||
LIBRARIES.borrow()["ops_and_meta_predicates"],
|
||||
@@ -262,7 +264,7 @@ impl Machine {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if let Some(builtins) = wam.indices.modules.get(&atom!("builtins")) {
|
||||
if let Some(ref mut builtins) = wam.indices.modules.get_mut(&atom!("builtins")) {
|
||||
load_module(
|
||||
&mut wam.indices.code_dir,
|
||||
&mut wam.indices.op_dir,
|
||||
@@ -270,6 +272,8 @@ impl Machine {
|
||||
&CompilationTarget::User,
|
||||
builtins,
|
||||
);
|
||||
|
||||
import_builtin_impls(&wam.indices.code_dir, builtins);
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
use crate::atom_table::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::iterators::*;
|
||||
use crate::machine::loader::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
@@ -207,34 +207,6 @@ fn setup_use_module_decl(mut terms: Vec<Term>) -> Result<ModuleSource, Compilati
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fn setup_double_quotes(mut terms: Vec<Box<Term>>) -> Result<DoubleQuotes, CompilationError> {
|
||||
let dbl_quotes = *terms.pop().unwrap();
|
||||
|
||||
match terms[0].as_ref() {
|
||||
Term::Literal(_, Literal::Atom(ref name, _))
|
||||
if name.as_str() == "double_quotes" => {
|
||||
match dbl_quotes {
|
||||
Term::Literal(_, Literal::Atom(name, _)) => {
|
||||
match name.as_str() {
|
||||
"atom" => Ok(DoubleQuotes::Atom),
|
||||
"chars" => Ok(DoubleQuotes::Chars),
|
||||
"codes" => Ok(DoubleQuotes::Codes),
|
||||
_ => Err(CompilationError::InvalidDoubleQuotesDecl),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidDoubleQuotesDecl)
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
Err(CompilationError::InvalidDoubleQuotesDecl)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
type UseModuleExport = (ModuleSource, IndexSet<ModuleExport>);
|
||||
|
||||
fn setup_qualified_import(
|
||||
@@ -735,7 +707,7 @@ impl Preprocessor {
|
||||
},
|
||||
Term::Var(..) => Ok(QueryTerm::Clause(
|
||||
Cell::default(),
|
||||
ClauseType::CallN,
|
||||
ClauseType::CallN(1),
|
||||
vec![term],
|
||||
false,
|
||||
)),
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::types::*;
|
||||
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::raw_block::*;
|
||||
use crate::types::*;
|
||||
|
||||
use std::mem;
|
||||
use std::ops::{Index, IndexMut};
|
||||
@@ -47,8 +45,7 @@ pub(crate) struct FramePrelude {
|
||||
pub(crate) struct AndFramePrelude {
|
||||
pub(crate) univ_prelude: FramePrelude,
|
||||
pub(crate) e: usize,
|
||||
pub(crate) cp: LocalCodePtr,
|
||||
pub(crate) interrupt_cp: LocalCodePtr, // TODO: get rid of it!
|
||||
pub(crate) cp: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -118,9 +115,9 @@ impl IndexMut<usize> for Stack {
|
||||
pub(crate) struct OrFramePrelude {
|
||||
pub(crate) univ_prelude: FramePrelude,
|
||||
pub(crate) e: usize,
|
||||
pub(crate) cp: LocalCodePtr,
|
||||
pub(crate) cp: usize,
|
||||
pub(crate) b: usize,
|
||||
pub(crate) bp: LocalCodePtr,
|
||||
pub(crate) bp: usize,
|
||||
pub(crate) boip: u32,
|
||||
pub(crate) biip: u32,
|
||||
pub(crate) tr: usize,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user