fix '$get_clause_p' whose old implementation was broken by the introduction
of lookahead indexing
This commit is contained in:
@@ -925,8 +925,8 @@ impl Machine {
|
|||||||
|
|
||||||
self.machine_st.hb = self.machine_st.heap.len();
|
self.machine_st.hb = self.machine_st.heap.len();
|
||||||
|
|
||||||
self.machine_st.oip = 0;
|
// self.machine_st.oip = 0;
|
||||||
self.machine_st.iip = 0;
|
// self.machine_st.iip = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.machine_st.p += offset;
|
self.machine_st.p += offset;
|
||||||
@@ -1010,8 +1010,8 @@ impl Machine {
|
|||||||
|
|
||||||
self.machine_st.heap.truncate(target_h);
|
self.machine_st.heap.truncate(target_h);
|
||||||
|
|
||||||
self.machine_st.oip = 0;
|
// self.machine_st.oip = 0;
|
||||||
self.machine_st.iip = 0;
|
// self.machine_st.iip = 0;
|
||||||
} else {
|
} else {
|
||||||
self.trust_epilogue(offset);
|
self.trust_epilogue(offset);
|
||||||
}
|
}
|
||||||
@@ -1059,8 +1059,13 @@ impl Machine {
|
|||||||
self.machine_st.stack.truncate(b);
|
self.machine_st.stack.truncate(b);
|
||||||
self.machine_st.heap.truncate(target_h);
|
self.machine_st.heap.truncate(target_h);
|
||||||
|
|
||||||
self.machine_st.oip = 0;
|
// these registers don't need to be reset here and MUST NOT be
|
||||||
self.machine_st.iip = 0;
|
// (nor in indexed_try to trust_epilogue)! oip could be reset
|
||||||
|
// without any adverse effects but iip is needed by
|
||||||
|
// get_clause_p to find the last executed clause/2 clause.
|
||||||
|
|
||||||
|
// self.machine_st.oip = 0;
|
||||||
|
// self.machine_st.iip = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|||||||
@@ -1171,112 +1171,73 @@ impl Machine {
|
|||||||
.get_predicate_skeleton(&compilation_target, &key)
|
.get_predicate_skeleton(&compilation_target, &key)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if self.machine_st.b > self.machine_st.e {
|
let module_name = match compilation_target {
|
||||||
let or_frame = self.machine_st.stack.index_or_frame(self.machine_st.b);
|
CompilationTarget::User => atom!("builtins"),
|
||||||
let bp = or_frame.prelude.bp;
|
CompilationTarget::Module(target) => target,
|
||||||
|
};
|
||||||
|
|
||||||
match &self.code[bp] {
|
let bp = self
|
||||||
Instruction::IndexingCode(ref indexing_code) => {
|
.indices
|
||||||
match &indexing_code[or_frame.prelude.boip as usize] {
|
.get_predicate_code_index(atom!("$clause"), 2, module_name)
|
||||||
IndexingLine::IndexedChoice(ref indexed_choice) => {
|
.and_then(|idx| idx.local())
|
||||||
let p = or_frame.prelude.biip as usize - 1;
|
.unwrap();
|
||||||
|
|
||||||
match &indexed_choice[p] {
|
let p = self.machine_st.iip as usize;
|
||||||
&IndexedChoiceInstruction::Try(offset)
|
|
||||||
| &IndexedChoiceInstruction::Retry(offset)
|
macro_rules! extract_ptr {
|
||||||
| &IndexedChoiceInstruction::DefaultRetry(offset) => {
|
($ptr: expr) => {
|
||||||
let clause_clause_loc = skeleton.core.clause_clause_locs[p];
|
match $ptr {
|
||||||
(clause_clause_loc, bp + offset)
|
IndexingCodePtr::External(p) => {
|
||||||
}
|
return (
|
||||||
&IndexedChoiceInstruction::Trust(_)
|
skeleton.core.clause_clause_locs.back().cloned().unwrap(),
|
||||||
| &IndexedChoiceInstruction::DefaultTrust(_) => {
|
bp + p,
|
||||||
unreachable!()
|
)
|
||||||
}
|
}
|
||||||
}
|
IndexingCodePtr::Internal(boip) => boip,
|
||||||
}
|
_ => unreachable!(),
|
||||||
_ => {
|
}
|
||||||
unreachable!()
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
match &self.code[bp] {
|
||||||
|
Instruction::IndexingCode(ref indexing_code) => {
|
||||||
|
let indexing_code_ptr = match &indexing_code[0] {
|
||||||
|
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, c, _, s)) => {
|
||||||
|
if key.1 > 0 {
|
||||||
|
s
|
||||||
|
} else {
|
||||||
|
c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
_ => {
|
||||||
_ => unreachable!(),
|
unreachable!()
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let module_name = match compilation_target {
|
|
||||||
CompilationTarget::User => atom!("builtins"),
|
|
||||||
CompilationTarget::Module(target) => target,
|
|
||||||
};
|
|
||||||
|
|
||||||
let bp = self
|
|
||||||
.indices
|
|
||||||
.get_predicate_code_index(atom!("$clause"), 2, module_name)
|
|
||||||
.and_then(|idx| idx.local())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
macro_rules! extract_ptr {
|
|
||||||
($ptr: expr) => {
|
|
||||||
match $ptr {
|
|
||||||
IndexingCodePtr::External(p) => {
|
|
||||||
return (
|
|
||||||
skeleton.core.clause_clause_locs.back().cloned().unwrap(),
|
|
||||||
bp + p,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
IndexingCodePtr::Internal(boip) => boip,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
match &self.code[bp] {
|
let boip = extract_ptr!(indexing_code_ptr);
|
||||||
Instruction::IndexingCode(ref indexing_code) => {
|
|
||||||
let indexing_code_ptr = match &indexing_code[0] {
|
|
||||||
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
|
||||||
_,
|
|
||||||
_,
|
|
||||||
c,
|
|
||||||
_,
|
|
||||||
s,
|
|
||||||
)) => {
|
|
||||||
if key.1 > 0 {
|
|
||||||
s
|
|
||||||
} else {
|
|
||||||
c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let boip = extract_ptr!(indexing_code_ptr);
|
let boip = match &indexing_code[boip] {
|
||||||
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref hm)) => {
|
||||||
let boip = match &indexing_code[boip] {
|
boip + extract_ptr!(hm.get(&key).cloned().unwrap())
|
||||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref hm)) => {
|
|
||||||
boip + extract_ptr!(hm.get(&key).cloned().unwrap())
|
|
||||||
}
|
|
||||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref hm)) => {
|
|
||||||
boip + extract_ptr!(hm.get(&Literal::Atom(key.0)).cloned().unwrap())
|
|
||||||
}
|
|
||||||
_ => boip,
|
|
||||||
};
|
|
||||||
|
|
||||||
match &indexing_code[boip] {
|
|
||||||
IndexingLine::IndexedChoice(indexed_choice) => {
|
|
||||||
return (
|
|
||||||
skeleton.core.clause_clause_locs.back().cloned().unwrap(),
|
|
||||||
bp + indexed_choice.back().unwrap().offset(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
}
|
||||||
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref hm)) => {
|
||||||
|
boip + extract_ptr!(hm.get(&Literal::Atom(key.0)).cloned().unwrap())
|
||||||
|
}
|
||||||
|
_ => boip,
|
||||||
|
};
|
||||||
|
|
||||||
|
match &indexing_code[boip] {
|
||||||
|
IndexingLine::IndexedChoice(indexed_choice) => {
|
||||||
|
return (
|
||||||
|
skeleton.core.clause_clause_locs[p],
|
||||||
|
bp + indexed_choice[p].offset(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
_ => {
|
}
|
||||||
return (
|
_ => {
|
||||||
skeleton.core.clause_clause_locs.back().cloned().unwrap(),
|
return (skeleton.core.clause_clause_locs[p], bp);
|
||||||
bp,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user