flatten the instruction dispatch loop

This commit is contained in:
Mark Thom
2021-12-19 18:57:57 -07:00
parent 3db86f1e25
commit 955e1799c8
52 changed files with 14247 additions and 10021 deletions

View File

@@ -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),

View File

@@ -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> {

View File

@@ -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() }
}
}

View File

@@ -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();

View File

@@ -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

View File

@@ -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);

View File

@@ -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)
}
}
}
*/

View File

@@ -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,
}
};

View File

@@ -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;

View File

@@ -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();

View File

@@ -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>;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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,
)),

View File

@@ -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