trim get_structure and put_structure arities when last arg is an index ptr (#1536)
This commit is contained in:
@@ -263,6 +263,27 @@ impl DebrayAllocator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the final argument of the structure is a Literal::Index,
|
||||||
|
// decrement the arity of the PutStructure instruction by 1.
|
||||||
|
fn trim_structure_by_last_arg(instr: &mut Instruction, last_arg: &Term) {
|
||||||
|
match instr {
|
||||||
|
Instruction::PutStructure(_, ref mut arity, _) |
|
||||||
|
Instruction::GetStructure(_, ref mut arity, _) => {
|
||||||
|
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
|
||||||
|
// it is acceptable if arity == 0 is the result of
|
||||||
|
// this decrement. call/N will have to read the index
|
||||||
|
// constant for '$call_inline' to succeed. to find it,
|
||||||
|
// it must know the heap location of the index.
|
||||||
|
// self.store must stop before reading the atom into a
|
||||||
|
// register.
|
||||||
|
|
||||||
|
*arity -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'b> CodeGenerator<'b> {
|
impl<'b> CodeGenerator<'b> {
|
||||||
pub(crate) fn new(atom_tbl: &'b mut AtomTable, settings: CodeGenSettings) -> Self {
|
pub(crate) fn new(atom_tbl: &'b mut AtomTable, settings: CodeGenSettings) -> Self {
|
||||||
CodeGenerator {
|
CodeGenerator {
|
||||||
@@ -375,7 +396,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
|
|
||||||
if let Some(instr) = target.last_mut() {
|
if let Some(instr) = target.last_mut() {
|
||||||
if let Some(term) = terms.last() {
|
if let Some(term) = terms.last() {
|
||||||
Target::trim_structure_by_last_arg(instr, term);
|
trim_structure_by_last_arg(instr, term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,6 @@ pub(crate) trait CompilationTarget<'a> {
|
|||||||
fn subterm_to_value(r: RegType) -> Instruction;
|
fn subterm_to_value(r: RegType) -> Instruction;
|
||||||
|
|
||||||
fn clause_arg_to_instr(r: RegType) -> Instruction;
|
fn clause_arg_to_instr(r: RegType) -> Instruction;
|
||||||
|
|
||||||
fn trim_structure_by_last_arg(instr: &mut Instruction, last_arg: &Term);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompilationTarget<'a> for FactInstruction {
|
impl<'a> CompilationTarget<'a> for FactInstruction {
|
||||||
@@ -108,10 +106,6 @@ impl<'a> CompilationTarget<'a> for FactInstruction {
|
|||||||
fn clause_arg_to_instr(val: RegType) -> Instruction {
|
fn clause_arg_to_instr(val: RegType) -> Instruction {
|
||||||
Instruction::UnifyVariable(val)
|
Instruction::UnifyVariable(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trim_structure_by_last_arg(_instr: &mut Instruction, _last_arg: &Term) {
|
|
||||||
// a no-op for facts.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompilationTarget<'a> for QueryInstruction {
|
impl<'a> CompilationTarget<'a> for QueryInstruction {
|
||||||
@@ -182,21 +176,4 @@ impl<'a> CompilationTarget<'a> for QueryInstruction {
|
|||||||
fn clause_arg_to_instr(val: RegType) -> Instruction {
|
fn clause_arg_to_instr(val: RegType) -> Instruction {
|
||||||
Instruction::SetValue(val)
|
Instruction::SetValue(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the final argument of the structure is a Literal::Index,
|
|
||||||
// decrement the arity of the PutStructure instruction by 1.
|
|
||||||
fn trim_structure_by_last_arg(instr: &mut Instruction, last_arg: &Term) {
|
|
||||||
if let Instruction::PutStructure(_, ref mut arity, _) = instr {
|
|
||||||
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
|
|
||||||
// it is acceptable if arity == 0 is the result of
|
|
||||||
// this decrement. call/N will have to read the index
|
|
||||||
// constant for '$call_inline' to succeed. to find it,
|
|
||||||
// it must know the heap location of the index.
|
|
||||||
// self.store must stop before reading the atom into a
|
|
||||||
// register.
|
|
||||||
|
|
||||||
*arity -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user