cache ball terms before unifying in handle_ball/3 (#1608)
This commit is contained in:
@@ -4125,14 +4125,6 @@ impl Machine {
|
||||
self.clean_up_block();
|
||||
self.machine_st.p = self.machine_st.cp;
|
||||
}
|
||||
&Instruction::CallEraseBall(_) => {
|
||||
self.erase_ball();
|
||||
self.machine_st.p += 1;
|
||||
}
|
||||
&Instruction::ExecuteEraseBall(_) => {
|
||||
self.erase_ball();
|
||||
self.machine_st.p = self.machine_st.cp;
|
||||
}
|
||||
&Instruction::CallFail(_) | &Instruction::ExecuteFail(_) => {
|
||||
self.machine_st.backtrack();
|
||||
}
|
||||
@@ -4284,6 +4276,30 @@ impl Machine {
|
||||
self.set_ball();
|
||||
self.machine_st.p = self.machine_st.cp;
|
||||
}
|
||||
&Instruction::CallPushBallStack(_) => {
|
||||
self.push_ball_stack();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecutePushBallStack(_) => {
|
||||
self.push_ball_stack();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallPopBallStack(_) => {
|
||||
self.pop_ball_stack();
|
||||
self.machine_st.p += 1;
|
||||
}
|
||||
&Instruction::ExecutePopBallStack(_) => {
|
||||
self.pop_ball_stack();
|
||||
self.machine_st.p = self.machine_st.cp;
|
||||
}
|
||||
&Instruction::CallPopFromBallStack(_) => {
|
||||
self.pop_from_ball_stack();
|
||||
self.machine_st.p += 1;
|
||||
}
|
||||
&Instruction::ExecutePopFromBallStack(_) => {
|
||||
self.pop_from_ball_stack();
|
||||
self.machine_st.p = self.machine_st.cp;
|
||||
}
|
||||
&Instruction::CallSetCutPointByDefault(r, _) => {
|
||||
self.set_cut_point_by_default(r);
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
@@ -4970,11 +4986,11 @@ impl Machine {
|
||||
}
|
||||
&Instruction::CallPredicateDefined(_) => {
|
||||
self.machine_st.fail = !self.predicate_defined();
|
||||
self.machine_st.p += 1;
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecutePredicateDefined(_) => {
|
||||
self.machine_st.fail = !self.predicate_defined();
|
||||
self.machine_st.p = self.machine_st.cp;
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallStripModule(_) => {
|
||||
let (module_loc, qualified_goal) = self.machine_st.strip_module(
|
||||
|
||||
@@ -75,6 +75,7 @@ pub struct MachineState {
|
||||
pub(super) hb: usize,
|
||||
pub(super) block: usize, // an offset into the OR stack.
|
||||
pub(super) ball: Ball,
|
||||
pub(super) ball_stack: Vec<Ball>, // save current ball before jumping via, e.g., verify_attr interrupt.
|
||||
pub(super) lifted_heap: Heap,
|
||||
pub(super) interms: Vec<Number>, // intermediate numbers.
|
||||
// locations of cleaners, cut points, the previous block. for setup_call_cleanup.
|
||||
@@ -113,6 +114,7 @@ impl fmt::Debug for MachineState {
|
||||
.field("hb", &self.hb)
|
||||
.field("block", &self.block)
|
||||
.field("ball", &self.ball)
|
||||
.field("ball_stack", &self.ball_stack)
|
||||
.field("lifted_heap", &self.lifted_heap)
|
||||
.field("interms", &self.interms)
|
||||
.field("flags", &self.flags)
|
||||
|
||||
@@ -47,6 +47,7 @@ impl MachineState {
|
||||
hb: 0,
|
||||
block: 0,
|
||||
ball: Ball::new(),
|
||||
ball_stack: vec![],
|
||||
lifted_heap: Heap::new(),
|
||||
interms: vec![Number::default();256],
|
||||
cont_pts: Vec::with_capacity(256),
|
||||
|
||||
@@ -4804,11 +4804,6 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn erase_ball(&mut self) {
|
||||
self.machine_st.ball.reset();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn get_ball(&mut self) {
|
||||
let addr = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]));
|
||||
@@ -4828,6 +4823,29 @@ impl Machine {
|
||||
};
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_ball_stack(&mut self) {
|
||||
if self.machine_st.ball.stub.len() > 0 {
|
||||
self.machine_st.ball_stack.push(
|
||||
mem::replace(&mut self.machine_st.ball, Ball::new())
|
||||
);
|
||||
} else {
|
||||
self.machine_st.fail = true;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn pop_ball_stack(&mut self) {
|
||||
self.machine_st.ball_stack.pop();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn pop_from_ball_stack(&mut self) {
|
||||
if let Some(ball) = self.machine_st.ball_stack.pop() {
|
||||
self.machine_st.ball = ball;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn get_current_block(&mut self) {
|
||||
let n = Fixnum::build_with(i64::try_from(self.machine_st.block).unwrap());
|
||||
|
||||
Reference in New Issue
Block a user