From: Mark Thom Date: Wed, 26 Nov 2025 07:17:22 +0000 (-0800) Subject: revise InstallVerifyAttrs to remove need for predicate scanning (#3175) X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=4bd16b8a2e6c618440b61968b3740a76754991e0;p=scryer-prolog.git revise InstallVerifyAttrs to remove need for predicate scanning (#3175) --- diff --git a/build/instructions_template.rs b/build/instructions_template.rs index 674892d3..29f3d715 100644 --- a/build/instructions_template.rs +++ b/build/instructions_template.rs @@ -834,12 +834,9 @@ enum InstructionTemplate { // break from loop instruction. #[strum_discriminants(strum(props(Arity = "0", Name = "break_from_dispatch")))] BreakFromDispatchLoop, - // swap the verify attr interrupt instruction with the next control instruction. - #[strum_discriminants(strum(props(Arity = "0", Name = "install_verify_attr")))] - InstallVerifyAttr, - // call verify_attrs. - #[strum_discriminants(strum(props(Arity = "1", Name = "verify_attr_interrupt")))] - VerifyAttrInterrupt(usize), + // run verify_attr, eventually. + #[strum_discriminants(strum(props(Arity = "0", Name = "run_verify_attr")))] + RunVerifyAttr, // procedures CallClause(ClauseType, usize, usize, bool, bool), // ClauseType, // arity, @@ -1168,33 +1165,6 @@ fn generate_instruction_preface() -> TokenStream { pub type CodeDeque = VecDeque; impl Instruction { - #[inline] - pub fn registers(&self) -> Vec { - match *self { - Instruction::GetConstant(_, _, r) => vec![r], - Instruction::GetList(_, r) => vec![r], - Instruction::GetPartialString(_, _, r) => vec![r], - Instruction::GetStructure(_, _, _, r) => vec![r], - Instruction::GetVariable(r, t) => vec![r, temp_v!(t)], - Instruction::GetValue(r, t) => vec![r, temp_v!(t)], - Instruction::UnifyLocalValue(r) => vec![r], - Instruction::UnifyVariable(r) => vec![r], - Instruction::PutConstant(_, _, r) => vec![r], - Instruction::PutList(_, r) => vec![r], - Instruction::PutPartialString(_, _, r) => vec![r], - Instruction::PutStructure(_, _, r) => vec![r], - Instruction::PutValue(r, t) => vec![r, temp_v!(t)], - Instruction::PutVariable(r, t) => vec![r, temp_v!(t)], - Instruction::SetLocalValue(r) => vec![r], - Instruction::SetVariable(r) => vec![r], - Instruction::SetValue(r) => vec![r], - Instruction::GetLevel(r) => vec![r], - Instruction::GetPrevLevel(r) => vec![r], - Instruction::GetCutPoint(r) => vec![r], - _ => vec![], - } - } - #[inline] pub fn to_indexing_line_mut(&mut self) -> Option<&mut Vec> { match self { @@ -1211,38 +1181,6 @@ fn generate_instruction_preface() -> TokenStream { } } - #[inline] - pub fn is_head_instr(&self) -> bool { - matches!(self, - Instruction::Deallocate | - Instruction::GetConstant(..) | - Instruction::GetList(..) | - Instruction::GetPartialString(..) | - Instruction::GetStructure(..) | - Instruction::GetValue(..) | - Instruction::UnifyConstant(..) | - Instruction::UnifyLocalValue(..) | - Instruction::UnifyVariable(..) | - Instruction::UnifyValue(..) | - Instruction::UnifyVoid(..) | - Instruction::GetVariable(..) | - Instruction::PutConstant(..) | - Instruction::PutList(..) | - Instruction::PutPartialString(..) | - Instruction::PutStructure(..) | - Instruction::PutUnsafeValue(..) | - Instruction::PutValue(..) | - Instruction::PutVariable(..) | - Instruction::SetConstant(..) | - Instruction::SetLocalValue(..) | - Instruction::SetVariable(..) | - Instruction::SetValue(..) | - Instruction::SetVoid(..) | - Instruction::GetLevel(..) | - Instruction::GetPrevLevel(..) | - Instruction::GetCutPoint(..)) - } - pub fn enqueue_functors( &self, arena: &mut Arena, @@ -1278,11 +1216,8 @@ fn generate_instruction_preface() -> TokenStream { fn to_functor(&self, arena: &mut Arena) -> MachineStub { match self { - &Instruction::InstallVerifyAttr => { - functor!(atom!("install_verify_attr")) - } - &Instruction::VerifyAttrInterrupt(arity) => { - functor!(atom!("verify_attr_interrupt"), [fixnum(arity)]) + &Instruction::RunVerifyAttr => { + functor!(atom!("run_verify_attr")) } &Instruction::DynamicElse(birth, death, next_or_fail) => { match (death, next_or_fail) { diff --git a/src/machine/attributed_variables.rs b/src/machine/attributed_variables.rs index 4aaf45ee..2cfdf600 100644 --- a/src/machine/attributed_variables.rs +++ b/src/machine/attributed_variables.rs @@ -41,13 +41,13 @@ impl MachineState { pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: HeapCellValue) { if self.attr_var_init.bindings.is_empty() { // save self.p and self.cp and ensure that the next - // instruction is InstallVerifyAttrInterrupt. + // instruction is RunVerifyAttrInterrupt. self.attr_var_init.p = self.p; self.attr_var_init.cp = self.cp; - self.p = INSTALL_VERIFY_ATTR_INTERRUPT - 1; - self.cp = INSTALL_VERIFY_ATTR_INTERRUPT; + self.p = VERIFY_ATTR_INTERRUPT_LOC - 1; + self.cp = VERIFY_ATTR_INTERRUPT_LOC; } debug_assert_eq!(self.heap[h].get_tag(), HeapCellValueTag::AttrVar); diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index fb1c5d12..a7a46d0e 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -12,8 +12,8 @@ use fxhash::FxBuildHasher; macro_rules! step_or_fail { ($self:expr, $step_e:expr) => { - if $self.machine_st.fail { - $self.machine_st.backtrack(); + if $self.fail { + $self.backtrack(); } else { $step_e; } @@ -21,7 +21,7 @@ macro_rules! step_or_fail { } macro_rules! try_or_throw { - ($s:expr, $e:expr) => {{ + ($s:expr, $e:expr, $control:expr) => {{ match $e { Ok(val) => val, Err(msg) => { @@ -30,17 +30,17 @@ macro_rules! try_or_throw { } $s.backtrack(); - continue; + $control; } } }}; } macro_rules! backtrack_on_resource_error { - ($machine_st:expr, $val:expr) => { + ($machine_st:expr, $val:expr, $control_expr:expr) => { step_or_resource_error!($machine_st, $val, { $machine_st.backtrack(); - continue; + $control_expr; }) }; } @@ -62,17 +62,17 @@ macro_rules! try_or_throw_gen { let e = msg_fn($s); $s.throw_exception(e); $s.backtrack(); - continue; + return; } } }}; } macro_rules! push_cell { - ($machine_st:expr, $cell:expr) => {{ + ($machine_st:expr, $cell:expr, $control_expr:expr) => {{ step_or_resource_error!($machine_st, $machine_st.heap.push_cell($cell), { $machine_st.backtrack(); - continue; + $control_expr; }) }}; } @@ -194,7 +194,6 @@ impl MachineState { ); let target_addr = self.registers[2]; - unify_fn!(*self, target_addr, heap_addr); Ok(()) } @@ -296,818 +295,1523 @@ impl MachineState { } ) } -} -impl Machine { - pub(super) fn find_living_dynamic_else(&self, mut p: usize) -> Option<(usize, usize)> { - loop { - match self.code[p] { - Instruction::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; - } - } - Instruction::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; - } - } - Instruction::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; - } - } - Instruction::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; - } - } - Instruction::RevJmpBy(i) => { - p -= i; - } - _ => { - unreachable!(); + fn check_for_interrupt(&mut self) { + let interrupted = INTERRUPT.load(std::sync::atomic::Ordering::Relaxed); + + match INTERRUPT.compare_exchange( + interrupted, + false, + std::sync::atomic::Ordering::Relaxed, + std::sync::atomic::Ordering::Relaxed, + ) { + Ok(interruption) => { + if interruption { + self.throw_interrupt_exception(); + self.backtrack(); + + // We have extracted controll over the Tokio runtime to the calling context for enabling library use case + // (see https://github.com/mthom/scryer-prolog/pull/1880) + // So we only have access to a runtime handle in here and can't shut it down. + // Since I'm not aware of the consequences of deactivating this new code which came in while PR 1880 + // was not merged, I'm only deactivating it for now. + + //#[cfg(not(target_arch = "wasm32"))] + //let runtime = tokio::runtime::Runtime::new().unwrap(); + //#[cfg(target_arch = "wasm32")] + //let runtime = tokio::runtime::Builder::new_current_thread() + // .enable_all() + // .build() + // .unwrap(); + + //let old_runtime = tokio::runtime::Handle::current(); + //old_runtime.shutdown_background(); } } + Err(_) => unreachable!(), } } - pub(super) fn find_living_dynamic( - &self, - oi: u32, - mut ii: u32, - ) -> Option<(usize, u32, u32, bool)> { - let p = self.machine_st.p; + #[inline(always)] + fn add_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let stub_gen = || functor_stub(atom!("is"), 2); - let indexed_choice_instrs = match &self.code[p] { - Instruction::IndexingCode(ref indexing_code) => match &indexing_code[oi as usize] { - IndexingLine::DynamicIndexedChoice(ref indexed_choice_instrs) => { - indexed_choice_instrs - } - _ => unreachable!(), - }, - _ => unreachable!(), - }; + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); - loop { - match &indexed_choice_instrs.get(ii as usize) { - Some(&offset) => match &self.code[p + offset - 1] { - &Instruction::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, - } - } + let value = try_or_throw_gen!( + self, + try_numeric_result!(add(n1, n2, &mut self.arena), stub_gen) + ); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; } #[inline(always)] - fn execute_switch_on_term(&mut self) { - #[inline(always)] - fn dynamic_external_of_clause_is_valid(machine: &mut Machine, p: usize) -> bool { - if let Instruction::DynamicInternalElse(..) = machine.code[p] { - machine.machine_st.dynamic_mode = FirstOrNext::First; - return true; - } + fn sub_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let stub_gen = || functor_stub(atom!("is"), 2); - if let Instruction::DynamicInternalElse(birth, death, _) = machine.code[p - 1] { - return birth < machine.machine_st.cc - && Death::Finite(machine.machine_st.cc) <= death; - } + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); - true - } + let value = try_or_throw_gen!( + self, + try_numeric_result!(sub(n1, n2, &mut self.arena), stub_gen) + ); - let indexing_lines = self.code[self.machine_st.p].to_indexing_line_mut().unwrap(); + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } - let mut index = 0; - let addr = match &indexing_lines[0] { - &IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(arg, ..)) => self - .machine_st - .store(self.machine_st.deref(self.machine_st.registers[arg])), - _ => { - unreachable!() - } - }; + #[inline(always)] + fn mul_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let stub_gen = || functor_stub(atom!("is"), 2); - loop { - match &indexing_lines[index] { - &IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, v, c, l, s)) => { - let offset = self - .machine_st - .select_switch_on_term_index(addr, v, c, l, s); + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); - match offset { - IndexingCodePtr::Fail => { - self.machine_st.fail = true; - break; - } - IndexingCodePtr::DynamicExternal(o) => { - // either points directly to a - // DynamicInternalElse, or just ahead of - // one. Or neither! - let p = self.machine_st.p; + let value = try_or_throw_gen!( + self, + try_numeric_result!(mul(n1, n2, &mut self.arena), stub_gen) + ); - if !dynamic_external_of_clause_is_valid(self, p + o) { - self.machine_st.fail = true; - } else { - self.machine_st.p += o; - } + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } - break; - } - IndexingCodePtr::External(o) => { - self.machine_st.p += o; - break; - } - IndexingCodePtr::Internal(o) => { - index += o; - } - } - } - IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(hm)) => { - // let lit = self.machine_st.constant_to_literal(addr); + #[inline(always)] + fn max_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); - let offset = match hm.get(&addr) { - Some(offset) => *offset, - _ => IndexingCodePtr::Fail, - }; + let value = try_or_throw_gen!(self, max(n1, n2)); - match offset { - IndexingCodePtr::Fail => { - self.machine_st.fail = true; - break; - } - IndexingCodePtr::DynamicExternal(o) => { - // either points directly to a - // DynamicInternalElse, or just ahead of - // one. Or neither! - let p = self.machine_st.p; + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } - if !dynamic_external_of_clause_is_valid(self, p + o) { - self.machine_st.fail = true; - } else { - self.machine_st.p += o; - } + #[inline(always)] + fn min_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); - break; - } - IndexingCodePtr::External(o) => { - self.machine_st.p += o; - break; - } - IndexingCodePtr::Internal(o) => { - index += o; - } - } - } - IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(hm)) => { - let offset = self.machine_st.select_switch_on_structure_index(addr, hm); + let value = try_or_throw_gen!(self, min(n1, n2)); - match offset { - IndexingCodePtr::Fail => { - self.machine_st.fail = true; - break; - } - IndexingCodePtr::DynamicExternal(o) => { - let p = self.machine_st.p; + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } - if !dynamic_external_of_clause_is_valid(self, p + o) { - self.machine_st.fail = true; - } else { - self.machine_st.p += o; - } + #[inline(always)] + fn int_pow_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); - break; - } - IndexingCodePtr::External(o) => { - self.machine_st.p += o; - break; - } - IndexingCodePtr::Internal(o) => { - index += o; - } - } - } - &IndexingLine::IndexedChoice(_) => { - self.machine_st.oip = index as u32; - self.machine_st.iip = 0; + let value = try_or_throw_gen!(self, int_pow(n1, n2, &mut self.arena)); - break; - } - &IndexingLine::DynamicIndexedChoice(_) => { - self.machine_st.dynamic_mode = FirstOrNext::First; + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } - self.machine_st.oip = index as u32; - self.machine_st.iip = 0; + #[inline(always)] + fn gcd_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); - break; - } - } - } + let value = try_or_throw_gen!(self, gcd(n1, n2, &mut self.arena)); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; } #[inline(always)] - pub(super) fn dispatch_loop(&mut self) -> std::process::ExitCode { - 'outer: loop { - for _ in 0..INSTRUCTIONS_PER_INTERRUPT_POLL { - match &self.code[self.machine_st.p] { - &Instruction::BreakFromDispatchLoop => { - break 'outer; - } - &Instruction::InstallVerifyAttr => { - self.machine_st.p = self.machine_st.attr_var_init.p; + fn pow_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); - if self.code[self.machine_st.p].is_execute() { - self.machine_st.p = self.machine_st.attr_var_init.cp; - } else { - self.machine_st.p += 1; - self.machine_st.cp = self.machine_st.attr_var_init.cp; - } + let value = try_or_throw_gen!(self, pow(n1, n2, atom!("**"))); - let p = self.machine_st.p; + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } - // Find the boundaries of the current predicate - self.indices.code_dir.sort_by(|_, a, _, b| { - let a = self.machine_st.arena.code_index_tbl.get_entry((*a).into()); - let b = self.machine_st.arena.code_index_tbl.get_entry((*b).into()); + #[inline(always)] + fn rdiv_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let stub_gen = || functor_stub(atom!("(rdiv)"), 2); - a.cmp(&b) - }); + let r1 = try_or_throw!(self, self.get_rational(a1, stub_gen), return); + let r2 = try_or_throw!(self, self.get_rational(a2, stub_gen), return); - let predicate_idx = self - .indices - .code_dir - .binary_search_by_key(&p, |_, x| -> usize { - self.machine_st - .arena - .code_index_tbl - .get_entry((*x).into()) - .p() as usize - }) - .unwrap_or_else(|x| x - 1); - - let current_pred_start = self - .indices - .code_dir - .get_index(predicate_idx) - .map(|idx| { - self.machine_st - .arena - .code_index_tbl - .get_entry((*idx.1).into()) - .p() as usize - }) - .unwrap(); + let value = Number::Rational(arena_alloc!( + try_or_throw_gen!(self, rdiv(r1, r2)), + &mut self.arena + )); - debug_assert!(current_pred_start <= p); + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } - let current_pred_end = self - .indices - .code_dir - .get_index(predicate_idx + 1) - .map(|idx| { - self.machine_st - .arena - .code_index_tbl - .get_entry((*idx.1).into()) - .p() as usize - }) - .unwrap_or(self.code.len()); - - debug_assert!(current_pred_end >= p); - debug_assert!(current_pred_end <= self.code.len()); - - // Find point to insert the interrupt - let p_interrupt = p + self.code[p..current_pred_end] - .iter() - .position(|x| !x.is_head_instr()) - .unwrap(); + #[inline(always)] + fn int_floor_div_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); - // Scan registers of all instructions to find out how many to save - let arity = self.code[current_pred_start..current_pred_end] - .iter() - .flat_map(Instruction::registers) - .flat_map(|r| match r { - RegType::Temp(t) => Some(t), - _ => None, - }) - .max() - .unwrap_or(0); - - let instr = std::mem::replace( - &mut self.code[p_interrupt], - Instruction::VerifyAttrInterrupt(arity), - ); + let value = try_or_throw_gen!(self, int_floor_div(n1, n2, &mut self.arena)); - self.code[VERIFY_ATTR_INTERRUPT_LOC] = instr; - self.machine_st.attr_var_init.cp = p_interrupt; - } - &Instruction::VerifyAttrInterrupt(arity) => { - self.run_verify_attr_interrupt(arity); - } - &Instruction::Add(ref a1, ref a2, t) => { - let stub_gen = || functor_stub(atom!("is"), 2); + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); + #[inline(always)] + fn idiv_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); - let value = try_or_throw_gen!( - &mut self.machine_st, - try_numeric_result!(add(n1, n2, &mut self.machine_st.arena), stub_gen) - ); + let value = try_or_throw_gen!(self, idiv(n1, n2, &mut self.arena)); - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; - } - &Instruction::Sub(ref a1, ref a2, t) => { - let stub_gen = || functor_stub(atom!("is"), 2); + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); + #[inline(always)] + fn abs_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = abs(n1, &mut self.arena); + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn sign_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n = try_or_throw!(self, self.get_number(a1), return); + let value = n.sign(); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn neg_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let value = neg(n1, &mut self.arena); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn bitwise_complement_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let value = try_or_throw_gen!(self, bitwise_complement(n1, &mut self.arena)); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn div_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); + let value = try_or_throw_gen!(self, div(n1, n2)); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn shr_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); + + let value = try_or_throw_gen!(self, shr(n1, n2, &mut self.arena)); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn shl_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); + + let value = try_or_throw_gen!(self, shl(n1, n2, &mut self.arena)); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn xor_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); + + let value = try_or_throw_gen!(self, xor(n1, n2, &mut self.arena)); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn and_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); + + let value = try_or_throw_gen!(self, and(n1, n2, &mut self.arena)); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn or_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); + + let value = try_or_throw_gen!(self, or(n1, n2, &mut self.arena)); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn mod_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); + + let value = try_or_throw_gen!(self, modulus(n1, n2, &mut self.arena)); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn rem_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); + + let value = try_or_throw_gen!(self, remainder(n1, n2, &mut self.arena)); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn cos_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!(self, cos(n1)))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn sin_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!(self, sin(n1)))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn tan_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!(self, tan(n1)))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn sqrt_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!(self, sqrt(n1)))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn log_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!(self, log(n1)))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn exp_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!(self, exp(n1)))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn acos_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!(self, acos(n1)))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn asin_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!(self, asin(n1)))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn atan_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!(self, atan(n1)))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn atan2_instr(&mut self, a1: &ArithmeticTerm, a2: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + let n2 = try_or_throw!(self, self.get_number(a2), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!(self, atan2(n1, n2)))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn float_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!(self, float(n1)))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn truncate_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = truncate(n1, &mut self.arena); + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn round_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = try_or_throw_gen!(self, round(n1, &mut self.arena)); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn ceiling_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = ceiling(n1, &mut self.arena); + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn floor_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = floor(n1, &mut self.arena); + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn float_fractional_part_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!( + self, + float_fractional_part(n1) + ))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn float_integer_part_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + + let value = Number::Float(OrderedFloat(try_or_throw_gen!( + self, + float_integer_part(n1) + ))); + + self.registers[t] = HeapCellValue::from((value, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn plus_instr(&mut self, a1: &ArithmeticTerm, t: usize) { + let n1 = try_or_throw!(self, self.get_number(a1), return); + self.registers[t] = HeapCellValue::from((n1, &mut self.arena)); + self.p += 1; + } + + #[inline(always)] + fn get_level_instr(&mut self, r: RegType) { + let b0 = self.b0; + self[r] = fixnum_as_cell!( + /* FIXME this is not safe */ + unsafe { Fixnum::build_with_unchecked(b0 as i64) }.as_cutpoint() + ); + self.p += 1; + } + + #[inline(always)] + fn get_prev_level_instr(&mut self, r: RegType) { + let prev_b = self.stack.index_or_frame(self.b).prelude.b; + + self[r] = fixnum_as_cell!( + /* FIXME this is not safe */ + unsafe { Fixnum::build_with_unchecked(prev_b as i64) }.as_cutpoint() + ); + self.p += 1; + } + + #[inline(always)] + fn get_cut_point_instr(&mut self, r: RegType) { + self[r] = fixnum_as_cell!( + /* FIXME this is not safe */ + unsafe { Fixnum::build_with_unchecked(self.b as i64) }.as_cutpoint() + ); + self.p += 1; + } + + #[inline(always)] + fn get_constant_instr(&mut self, c: HeapCellValue, r: RegType) { + unify!(self, self[r], c); + step_or_fail!(self, self.p += 1); + } + + #[inline(always)] + fn get_list_instr(&mut self, r: RegType) { + let deref_v = self.deref(self[r]); + let store_v = self.store(deref_v); + + read_heap_cell!(store_v, + (HeapCellValueTag::PStrLoc, h) => { + self.s = HeapPtr::PStr(h); + self.s_offset = 0; + self.mode = MachineMode::Read; + } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + if name == atom!(".") && arity == 2 { + self.s = HeapPtr::HeapCell(s+1); + self.s_offset = 0; + self.mode = MachineMode::Read; + } else { + self.backtrack(); + return; + } + } + (HeapCellValueTag::Lis, l) => { + self.s = HeapPtr::HeapCell(l); + self.s_offset = 0; + self.mode = MachineMode::Read; + } + (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => { + let h = self.heap.cell_len(); + push_cell!(self, list_loc_as_cell!(h+1), return); + self.bind(store_v.as_var().unwrap(), heap_loc_as_cell!(h)); + self.mode = MachineMode::Write; + } + _ => { + self.backtrack(); + return; + } + ); + + self.p += 1; + } + + #[inline(always)] + fn get_partial_string_instr(&mut self, string: &String, r: RegType) { + self.heap[0] = self[r]; + + let mut h = 0; + let mut string_cursor = string.as_str(); + + if self.heap[0].is_stack_var() { + let cell = self.store(self.deref(self.heap[0])); + + if let Some(r) = cell.as_var() { + let target_cell = backtrack_on_resource_error!( + self, + self.heap.allocate_pstr(string_cursor), + return + ); + + self.bind(r, target_cell); + self.mode = MachineMode::Write; + + debug_assert!(!self.fail); + self.p += 1; + + return; + } + + self.heap[0] = cell; + } + + while let Some(c) = string_cursor.chars().next() { + read_heap_cell!(self.heap[h], + (HeapCellValueTag::PStrLoc, pstr_loc) => { + let heap_slice = &self.heap.as_slice()[pstr_loc ..]; + + match compare_pstr_slices(heap_slice, string_cursor.as_bytes()) { + PStrSegmentCmpResult::Continue(v1, v2) => { + // for v2, the value of a TailIndex mustn't ever be read + // since string does not lie in the heap. + match (v1, v2) { + (PStrContinuable::TailIndex(tail_idx), PStrContinuable::TailIndex(_)) => { + self.s = HeapPtr::HeapCell(tail_idx + cell_index!(pstr_loc)); + self.s_offset = 0; + self.mode = MachineMode::Read; + + break; + } + (PStrContinuable::TailIndex(tail_idx), PStrContinuable::PStrOffset(pos)) => { + h = tail_idx + cell_index!(pstr_loc); + string_cursor = &string_cursor[pos ..]; + } + (PStrContinuable::PStrOffset(pos), PStrContinuable::TailIndex(_)) => { + self.s = HeapPtr::PStr(pstr_loc); + self.s_offset = pos; + self.mode = MachineMode::Read; + + break; + } + _ => unreachable!(), + } + } + _ => { + self.fail = true; + break; + } + } + } + (HeapCellValueTag::Lis, l) => { + let cell = self.store(self.deref(self.heap[l])); + + if let Some(d) = cell.as_char() { + if c != d { + self.fail = true; + break; + } + } else if let Some(r) = cell.as_var() { + self.bind(r, char_as_cell!(c)); + } else { + self.fail = true; + } + + if self.fail { + break; + } else { + h = l+1; + string_cursor = &string_cursor[c.len_utf8() ..]; + + if string_cursor.is_empty() { + self.s = HeapPtr::HeapCell(h); + self.s_offset = 0; + self.mode = MachineMode::Read; + } + } + } + (HeapCellValueTag::Str, s) => { + let cell = self.store(self.deref(self.heap[s+1])); + + if let Some(d) = cell.as_char() { + if c != d { + self.fail = true; + break; + } + } else if let Some(r) = cell.as_var() { + self.bind(r, char_as_cell!(c)); + } else { + self.fail = true; + } + + if self.fail { + break; + } + + h = s+2; + string_cursor = &string_cursor[c.len_utf8() ..]; + + if string_cursor.is_empty() { + self.s = HeapPtr::HeapCell(h); + self.s_offset = 0; + self.mode = MachineMode::Read; + } + } + (HeapCellValueTag::AttrVar | HeapCellValueTag::Var, v) => { + if h == v { + let target_cell = backtrack_on_resource_error!( + self, + self.heap.allocate_pstr(string_cursor), + return + ); + + self.bind( + self.heap[h].as_var().unwrap(), + target_cell, + ); + + self.mode = MachineMode::Write; + break; + } else { + h = v; + } + } + _ => { + self.fail = true; + break; + } + ); + } + + step_or_fail!(self, self.p += 1); + } + + #[inline(always)] + fn get_structure_instr(&mut self, name: Atom, arity: usize, r: RegType) { + let deref_v = self.deref(self[r]); + let store_v = self.store(deref_v); + + read_heap_cell!(store_v, + (HeapCellValueTag::Str, a) => { + read_heap_cell!(self.heap[a], + (HeapCellValueTag::Atom, (result_name, result_arity)) => { + if arity == result_arity && name == result_name { + self.s = HeapPtr::HeapCell(a + 1); + self.s_offset = 0; + self.mode = MachineMode::Read; + } else { + self.backtrack(); + return; + } + } + _ => { + unreachable!(); + } + ); + } + (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => { + let h = self.heap.cell_len(); + + push_cell!(self, str_loc_as_cell!(h+1), return); + push_cell!(self, atom_as_cell!(name, arity), return); + + self.bind(store_v.as_var().unwrap(), heap_loc_as_cell!(h)); + self.mode = MachineMode::Write; + } + _ => { + self.backtrack(); + return; + } + ); + + self.p += 1; + } + + #[inline(always)] + fn get_variable_instr(&mut self, norm: RegType, arg: usize) { + self[norm] = self.registers[arg]; + self.p += 1; + } + + #[inline(always)] + fn get_value_instr(&mut self, norm: RegType, arg: usize) { + let norm_addr = self[norm]; + let reg_addr = self.registers[arg]; + + unify_fn!(&mut *self, norm_addr, reg_addr); + + if self.fail { + self.backtrack(); + return; + } + + self.p += 1; + } + + #[inline(always)] + fn unify_constant_instr(&mut self, v: HeapCellValue) { + match self.mode { + MachineMode::Read => { + let (addr, s_offset_incr) = self.read_s(); + unify!(self, addr, v); + + if self.fail { + self.backtrack(); + return; + } else { + self.s_offset += s_offset_incr; + } + } + MachineMode::Write => { + push_cell!(self, v, return); + } + } + + self.p += 1; + } + + #[inline(always)] + fn unify_local_value_instr(&mut self, r: RegType) { + match self.mode { + MachineMode::Read => { + let reg_addr = self[r]; + let (value, s_offset_incr) = self.read_s(); + + unify_fn!(&mut *self, reg_addr, value); + + if self.fail { + self.backtrack(); + return; + } else { + self.s_offset += s_offset_incr; + } + } + MachineMode::Write => { + let value = self.store(self.deref(self[r])); + let h = self.heap.cell_len(); + + read_heap_cell!(value, + (HeapCellValueTag::Var | HeapCellValueTag::AttrVar, hc) => { + let value = self.heap[hc]; + push_cell!(self, value, return); + self.s_offset += 1; + } + _ => { + push_cell!(self, heap_loc_as_cell!(h), return); + (self.bind_fn)(self, Ref::heap_cell(h), value); + } + ); + } + } + + self.p += 1; + } + + #[inline(always)] + fn unify_variable_instr(&mut self, r: RegType) { + match self.mode { + MachineMode::Read => { + let (value, s_offset_incr) = self.read_s(); + self[r] = value; + self.s_offset += s_offset_incr; + } + MachineMode::Write => { + let h = self.heap.cell_len(); + push_cell!(self, heap_loc_as_cell!(h), return); + self[r] = heap_loc_as_cell!(h); + } + } + + self.p += 1; + } + + #[inline(always)] + fn unify_value_instr(&mut self, r: RegType) { + match self.mode { + MachineMode::Read => { + let reg_addr = self[r]; + let (value, s_offset_incr) = self.read_s(); + + unify_fn!(&mut *self, reg_addr, value); + + if self.fail { + self.backtrack(); + return; + } else { + self.s_offset += s_offset_incr; + } + } + MachineMode::Write => { + let h = self.heap.cell_len(); + push_cell!(self, heap_loc_as_cell!(h), return); + + let addr = self.store(self[r]); + (self.bind_fn)(self, Ref::heap_cell(h), addr); + + // the former code of this match arm was: + + // let addr = self.store(self[reg]); + // push_cell!(self, HeapCellValue::Addr(addr)); + + // the old code didn't perform the occurs + // check when enabled and so it was changed to + // the above, which is only slightly less + // efficient when the occurs_check is disabled. + } + } + + self.p += 1; + } + + #[inline(always)] + fn unify_void_instr(&mut self, n: usize) { + match self.mode { + MachineMode::Read => match &self.s { + HeapPtr::HeapCell(_) => self.s_offset += n, + &HeapPtr::PStr(pstr_loc) => { + debug_assert!(n <= 2); + let mut char_iter = self.heap.char_iter(pstr_loc); + + // this only matters in the case that n == 1, but the case + // analysis isn't worth doing since the effect is benign if n == + // 2 + self.s_offset += char_iter.next().unwrap().len_utf8(); + } + }, + MachineMode::Write => { + let h = self.heap.cell_len(); + + for i in h..h + n { + push_cell!(self, heap_loc_as_cell!(i), return); + } + } + } + + self.p += 1; + } + + #[inline(always)] + fn put_constant_instr(&mut self, cell: HeapCellValue, r: RegType) { + self[r] = cell; + self.p += 1; + } + + #[inline(always)] + fn put_list_instr(&mut self, r: RegType) { + self[r] = list_loc_as_cell!(self.heap.cell_len()); + self.p += 1; + } + + #[inline(always)] + fn put_partial_string_instr(&mut self, string: &str, r: RegType) { + self[r] = backtrack_on_resource_error!(self, self.heap.allocate_pstr(string), return); + + self.p += 1; + } + + #[inline(always)] + fn put_structure_instr(&mut self, name: Atom, arity: usize, r: RegType) { + let h = self.heap.cell_len(); + + push_cell!(self, atom_as_cell!(name, arity), return); + self[r] = str_loc_as_cell!(h); + + self.p += 1; + } + + #[inline(always)] + fn put_unsafe_value_instr(&mut self, perm_slot: usize, arg: usize) { + let s = stack_loc!(AndFrame, self.e, perm_slot); + let addr = self.store(self.deref(stack_loc_as_cell!(s))); + + if addr.is_protected(self.e) { + self.registers[arg] = addr; + } else { + let h = self.heap.cell_len(); + push_cell!(self, heap_loc_as_cell!(h), return); + + (self.bind_fn)(self, Ref::heap_cell(h), addr); + self.registers[arg] = heap_loc_as_cell!(h); + } + + self.p += 1; + } + + #[inline(always)] + fn put_value_instr(&mut self, norm: RegType, arg: usize) { + self.registers[arg] = self[norm]; + self.p += 1; + } + + #[inline(always)] + fn put_variable_instr(&mut self, norm: RegType, arg: usize) { + match norm { + RegType::Perm(n) => { + self[norm] = stack_loc_as_cell!(AndFrame, self.e, n); + self.registers[arg] = self[norm]; + } + RegType::Temp(_) => { + let h = self.heap.cell_len(); + push_cell!(self, heap_loc_as_cell!(h), return); - let value = try_or_throw_gen!( - &mut self.machine_st, - try_numeric_result!(sub(n1, n2, &mut self.machine_st.arena), stub_gen) - ); + self[norm] = heap_loc_as_cell!(h); + self.registers[arg] = heap_loc_as_cell!(h); + } + } - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; - } - &Instruction::Mul(ref a1, ref a2, t) => { - let stub_gen = || functor_stub(atom!("is"), 2); + self.p += 1; + } - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); + #[inline(always)] + fn set_constant_instr(&mut self, c: HeapCellValue) { + push_cell!(self, c, return); + self.p += 1; + } - let value = try_or_throw_gen!( - &mut self.machine_st, - try_numeric_result!(mul(n1, n2, &mut self.machine_st.arena), stub_gen) - ); + #[inline(always)] + fn set_local_value_instr(&mut self, r: RegType) { + let addr = self.deref(self[r]); + let stored_v = self.store(addr); + + if stored_v.is_stack_var() { + let h = self.heap.cell_len(); + push_cell!(self, heap_loc_as_cell!(h), return); + (self.bind_fn)(self, Ref::heap_cell(h), stored_v); + } else { + push_cell!(self, stored_v, return); + } - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; - } - &Instruction::Max(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); + self.p += 1; + } - let value = try_or_throw_gen!(&mut self.machine_st, max(n1, n2)); + #[inline(always)] + fn set_variable_instr(&mut self, r: RegType) { + let h = self.heap.cell_len(); - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; - } - &Instruction::Min(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); + push_cell!(self, heap_loc_as_cell!(h), return); + self[r] = heap_loc_as_cell!(h); - let value = try_or_throw_gen!(&mut self.machine_st, min(n1, n2)); + self.p += 1; + } - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; - } - &Instruction::IntPow(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); - let value = try_or_throw_gen!( - &mut self.machine_st, - int_pow(n1, n2, &mut self.machine_st.arena) - ); + #[inline(always)] + fn set_value_instr(&mut self, r: RegType) { + let heap_val = self.store(self[r]); + push_cell!(self, heap_val, return); + self.p += 1; + } - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + #[inline(always)] + fn set_void_instr(&mut self, n: usize) { + let h = self.heap.cell_len(); + + for i in h..h + n { + push_cell!(self, heap_loc_as_cell!(i), return); + } + + self.p += 1; + } +} + +impl Machine { + pub(super) fn find_living_dynamic_else(&self, mut p: usize) -> Option<(usize, usize)> { + loop { + match self.code[p] { + Instruction::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; + } + } + Instruction::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; + } + } + Instruction::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; } - &Instruction::Gcd(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); + } + Instruction::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; + } + } + Instruction::RevJmpBy(i) => { + p -= i; + } + _ => { + unreachable!(); + } + } + } + } - let value = try_or_throw_gen!( - &mut self.machine_st, - gcd(n1, n2, &mut self.machine_st.arena) - ); + pub(super) fn find_living_dynamic( + &self, + oi: u32, + mut ii: u32, + ) -> Option<(usize, u32, u32, bool)> { + let p = self.machine_st.p; - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + let indexed_choice_instrs = match &self.code[p] { + Instruction::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[p + offset - 1] { + &Instruction::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; + } } - &Instruction::Pow(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); + _ => unreachable!(), + }, + None => return None, + } + } + } - let value = - try_or_throw_gen!(&mut self.machine_st, pow(n1, n2, atom!("**"))); - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); + #[inline(always)] + fn execute_switch_on_term(&mut self) { + #[inline(always)] + fn dynamic_external_of_clause_is_valid(machine: &mut Machine, p: usize) -> bool { + if let Instruction::DynamicInternalElse(..) = machine.code[p] { + machine.machine_st.dynamic_mode = FirstOrNext::First; + return true; + } - self.machine_st.p += 1; + if let Instruction::DynamicInternalElse(birth, death, _) = machine.code[p - 1] { + return birth < machine.machine_st.cc + && Death::Finite(machine.machine_st.cc) <= death; + } + + true + } + + let indexing_lines = self.code[self.machine_st.p].to_indexing_line_mut().unwrap(); + + let mut index = 0; + let addr = match &indexing_lines[0] { + &IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(arg, ..)) => self + .machine_st + .store(self.machine_st.deref(self.machine_st.registers[arg])), + _ => { + unreachable!() + } + }; + + loop { + match &indexing_lines[index] { + &IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, v, c, l, s)) => { + let offset = self + .machine_st + .select_switch_on_term_index(addr, v, c, l, s); + + match offset { + IndexingCodePtr::Fail => { + self.machine_st.fail = true; + break; + } + IndexingCodePtr::DynamicExternal(o) => { + // either points directly to a + // DynamicInternalElse, or just ahead of + // one. Or neither! + let p = self.machine_st.p; + + if !dynamic_external_of_clause_is_valid(self, p + o) { + self.machine_st.fail = true; + } else { + self.machine_st.p += o; + } + + break; + } + IndexingCodePtr::External(o) => { + self.machine_st.p += o; + break; + } + IndexingCodePtr::Internal(o) => { + index += o; + } } - &Instruction::RDiv(ref a1, ref a2, t) => { - let stub_gen = || functor_stub(atom!("(rdiv)"), 2); + } + IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(hm)) => { + // let lit = self.machine_st.constant_to_literal(addr); - let r1 = try_or_throw!( - self.machine_st, - self.machine_st.get_rational(a1, stub_gen) - ); - let r2 = try_or_throw!( - self.machine_st, - self.machine_st.get_rational(a2, stub_gen) - ); + let offset = match hm.get(&addr) { + Some(offset) => *offset, + _ => IndexingCodePtr::Fail, + }; + + match offset { + IndexingCodePtr::Fail => { + self.machine_st.fail = true; + break; + } + IndexingCodePtr::DynamicExternal(o) => { + // either points directly to a + // DynamicInternalElse, or just ahead of + // one. Or neither! + let p = self.machine_st.p; - let value = Number::Rational(arena_alloc!( - try_or_throw_gen!(&mut self.machine_st, rdiv(r1, r2)), - &mut self.machine_st.arena - )); + if !dynamic_external_of_clause_is_valid(self, p + o) { + self.machine_st.fail = true; + } else { + self.machine_st.p += o; + } - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + break; + } + IndexingCodePtr::External(o) => { + self.machine_st.p += o; + break; + } + IndexingCodePtr::Internal(o) => { + index += o; + } } - &Instruction::IntFloorDiv(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); + } + IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(hm)) => { + let offset = self.machine_st.select_switch_on_structure_index(addr, hm); - let value = try_or_throw_gen!( - &mut self.machine_st, - int_floor_div(n1, n2, &mut self.machine_st.arena) - ); + match offset { + IndexingCodePtr::Fail => { + self.machine_st.fail = true; + break; + } + IndexingCodePtr::DynamicExternal(o) => { + let p = self.machine_st.p; - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + if !dynamic_external_of_clause_is_valid(self, p + o) { + self.machine_st.fail = true; + } else { + self.machine_st.p += o; + } + + break; + } + IndexingCodePtr::External(o) => { + self.machine_st.p += o; + break; + } + IndexingCodePtr::Internal(o) => { + index += o; + } } - &Instruction::IDiv(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); + } + &IndexingLine::IndexedChoice(_) => { + self.machine_st.oip = index as u32; + self.machine_st.iip = 0; - let value = try_or_throw_gen!( - &mut self.machine_st, - idiv(n1, n2, &mut self.machine_st.arena) - ); + break; + } + &IndexingLine::DynamicIndexedChoice(_) => { + self.machine_st.dynamic_mode = FirstOrNext::First; + + self.machine_st.oip = index as u32; + self.machine_st.iip = 0; - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; - } - &Instruction::Abs(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); + break; + } + } + } + } - let value = abs(n1, &mut self.machine_st.arena); - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + fn verify_attr_dispatch_loop(&mut self) -> Option { + 'outer: loop { + for _ in 0..INSTRUCTIONS_PER_INTERRUPT_POLL { + match &self.code[self.machine_st.p] { + &Instruction::BreakFromDispatchLoop => { + break 'outer; } - &Instruction::Sign(ref a1, t) => { - let n = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let value = n.sign(); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::Add(ref a1, ref a2, t) => self.machine_st.add_instr(a1, a2, t), + &Instruction::Sub(ref a1, ref a2, t) => self.machine_st.sub_instr(a1, a2, t), + &Instruction::Mul(ref a1, ref a2, t) => self.machine_st.mul_instr(a1, a2, t), + &Instruction::Max(ref a1, ref a2, t) => self.machine_st.max_instr(a1, a2, t), + &Instruction::Min(ref a1, ref a2, t) => self.machine_st.min_instr(a1, a2, t), + &Instruction::IntPow(ref a1, ref a2, t) => { + self.machine_st.int_pow_instr(a1, a2, t) } - &Instruction::Neg(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = neg(n1, &mut self.machine_st.arena); - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::Gcd(ref a1, ref a2, t) => self.machine_st.gcd_instr(a1, a2, t), + &Instruction::Pow(ref a1, ref a2, t) => self.machine_st.pow_instr(a1, a2, t), + &Instruction::RDiv(ref a1, ref a2, t) => self.machine_st.rdiv_instr(a1, a2, t), + &Instruction::IntFloorDiv(ref a1, ref a2, t) => { + self.machine_st.int_floor_div_instr(a1, a2, t) } + &Instruction::IDiv(ref a1, ref a2, t) => self.machine_st.idiv_instr(a1, a2, t), + &Instruction::Abs(ref a1, t) => self.machine_st.abs_instr(a1, t), + &Instruction::Sign(ref a1, t) => self.machine_st.sign_instr(a1, t), + &Instruction::Neg(ref a1, t) => self.machine_st.neg_instr(a1, t), &Instruction::BitwiseComplement(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = try_or_throw_gen!( - &mut self.machine_st, - bitwise_complement(n1, &mut self.machine_st.arena) - ); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + self.machine_st.bitwise_complement_instr(a1, t) + } + &Instruction::Div(ref a1, ref a2, t) => self.machine_st.div_instr(a1, a2, t), + &Instruction::Shr(ref a1, ref a2, t) => self.machine_st.shr_instr(a1, a2, t), + &Instruction::Shl(ref a1, ref a2, t) => self.machine_st.shl_instr(a1, a2, t), + &Instruction::Xor(ref a1, ref a2, t) => self.machine_st.xor_instr(a1, a2, t), + &Instruction::And(ref a1, ref a2, t) => self.machine_st.and_instr(a1, a2, t), + &Instruction::Or(ref a1, ref a2, t) => self.machine_st.or_instr(a1, a2, t), + &Instruction::Mod(ref a1, ref a2, t) => self.machine_st.mod_instr(a1, a2, t), + &Instruction::Rem(ref a1, ref a2, t) => self.machine_st.rem_instr(a1, a2, t), + &Instruction::Cos(ref a1, t) => self.machine_st.cos_instr(a1, t), + &Instruction::Sin(ref a1, t) => self.machine_st.sin_instr(a1, t), + &Instruction::Tan(ref a1, t) => self.machine_st.tan_instr(a1, t), + &Instruction::Sqrt(ref a1, t) => self.machine_st.sqrt_instr(a1, t), + &Instruction::Log(ref a1, t) => self.machine_st.log_instr(a1, t), + &Instruction::Exp(ref a1, t) => self.machine_st.exp_instr(a1, t), + &Instruction::ACos(ref a1, t) => self.machine_st.acos_instr(a1, t), + &Instruction::ASin(ref a1, t) => self.machine_st.asin_instr(a1, t), + &Instruction::ATan(ref a1, t) => self.machine_st.atan_instr(a1, t), + &Instruction::ATan2(ref a1, ref a2, t) => { + self.machine_st.atan2_instr(a1, a2, t) } - &Instruction::Div(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); - - let value = try_or_throw_gen!(&mut self.machine_st, div(n1, n2)); - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::Float(ref a1, t) => self.machine_st.float_instr(a1, t), + &Instruction::Truncate(ref a1, t) => self.machine_st.truncate_instr(a1, t), + &Instruction::Round(ref a1, t) => self.machine_st.round_instr(a1, t), + &Instruction::Ceiling(ref a1, t) => self.machine_st.ceiling_instr(a1, t), + &Instruction::Floor(ref a1, t) => self.machine_st.floor_instr(a1, t), + &Instruction::FloatFractionalPart(ref a1, t) => { + self.machine_st.float_fractional_part_instr(a1, t) } - &Instruction::Shr(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); - - let value = try_or_throw_gen!( - &mut self.machine_st, - shr(n1, n2, &mut self.machine_st.arena) - ); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::FloatIntegerPart(ref a1, t) => { + self.machine_st.float_integer_part_instr(a1, t) } - &Instruction::Shl(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); - - let value = try_or_throw_gen!( - &mut self.machine_st, - shl(n1, n2, &mut self.machine_st.arena) - ); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::Plus(ref a1, t) => self.machine_st.plus_instr(a1, t), + &Instruction::GetLevel(r) => self.machine_st.get_level_instr(r), + &Instruction::GetPrevLevel(r) => self.machine_st.get_prev_level_instr(r), + &Instruction::GetCutPoint(r) => self.machine_st.get_cut_point_instr(r), + &Instruction::Deallocate => self.machine_st.deallocate(), + &Instruction::JmpByCall(offset) => { + self.machine_st.p += offset; } - &Instruction::Xor(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); - - let value = try_or_throw_gen!( - &mut self.machine_st, - xor(n1, n2, &mut self.machine_st.arena) - ); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::RevJmpBy(offset) => { + self.machine_st.p -= offset; } - &Instruction::And(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); - - let value = try_or_throw_gen!( - &mut self.machine_st, - and(n1, n2, &mut self.machine_st.arena) - ); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::GetConstant(_, c, reg) => { + self.machine_st.get_constant_instr(c, reg) } - &Instruction::Or(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); - - let value = try_or_throw_gen!( - &mut self.machine_st, - or(n1, n2, &mut self.machine_st.arena) - ); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::GetList(_, reg) => self.machine_st.get_list_instr(reg), + &Instruction::GetPartialString(_, ref string, reg) => { + self.machine_st.get_partial_string_instr(string, reg) } - &Instruction::Mod(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); - - let value = try_or_throw_gen!( - &mut self.machine_st, - modulus(n1, n2, &mut self.machine_st.arena) - ); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::GetStructure(_lvl, name, arity, reg) => { + self.machine_st.get_structure_instr(name, arity, reg) } - &Instruction::Rem(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); - - let value = try_or_throw_gen!( - &mut self.machine_st, - remainder(n1, n2, &mut self.machine_st.arena) - ); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::GetVariable(norm, arg) => { + self.machine_st.get_variable_instr(norm, arg) } - &Instruction::Cos(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - cos(n1) - ))); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::GetValue(norm, arg) => self.machine_st.get_value_instr(norm, arg), + &Instruction::UnifyConstant(v) => self.machine_st.unify_constant_instr(v), + &Instruction::UnifyLocalValue(reg) => { + self.machine_st.unify_local_value_instr(reg) } - &Instruction::Sin(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - sin(n1) - ))); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::UnifyVariable(reg) => self.machine_st.unify_variable_instr(reg), + &Instruction::UnifyValue(reg) => self.machine_st.unify_value_instr(reg), + &Instruction::UnifyVoid(n) => self.machine_st.unify_void_instr(n), + &Instruction::PutConstant(_, cell, reg) => { + self.machine_st.put_constant_instr(cell, reg) } - &Instruction::Tan(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - tan(n1) - ))); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::PutList(_, reg) => self.machine_st.put_list_instr(reg), + &Instruction::PutPartialString(_, ref string, reg) => { + self.machine_st.put_partial_string_instr(string, reg) } - &Instruction::Sqrt(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - sqrt(n1) - ))); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::PutStructure(name, arity, reg) => { + self.machine_st.put_structure_instr(name, arity, reg) } - &Instruction::Log(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - log(n1) - ))); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::PutUnsafeValue(perm_slot, arg) => { + self.machine_st.put_unsafe_value_instr(perm_slot, arg) } - &Instruction::Exp(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - exp(n1) - ))); + &Instruction::PutValue(norm, arg) => self.machine_st.put_value_instr(norm, arg), + &Instruction::PutVariable(norm, arg) => { + self.machine_st.put_variable_instr(norm, arg) + } + &Instruction::SetConstant(c) => self.machine_st.set_constant_instr(c), + &Instruction::SetLocalValue(reg) => self.machine_st.set_local_value_instr(reg), + &Instruction::SetVariable(reg) => self.machine_st.set_variable_instr(reg), + &Instruction::SetValue(reg) => self.machine_st.set_value_instr(reg), + &Instruction::SetVoid(n) => self.machine_st.set_void_instr(n), + _ => return None, + } + } - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; - } - &Instruction::ACos(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); + self.machine_st.check_for_interrupt(); + } - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - acos(n1) - ))); + Some(std::process::ExitCode::SUCCESS) + } - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + pub(super) fn dispatch_loop(&mut self) -> std::process::ExitCode { + 'outer: loop { + for _ in 0..INSTRUCTIONS_PER_INTERRUPT_POLL { + match &self.code[self.machine_st.p] { + &Instruction::BreakFromDispatchLoop => { + break 'outer; } - &Instruction::ASin(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); + &Instruction::RunVerifyAttr => { + self.machine_st.p = self.machine_st.attr_var_init.p; - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - asin(n1) - ))); + if self.code[self.machine_st.p].is_execute() { + self.machine_st.p = self.machine_st.attr_var_init.cp; + } else { + self.machine_st.p += 1; + self.machine_st.cp = self.machine_st.attr_var_init.cp; + } - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; - } - &Instruction::ATan(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); + if let Some(exit_code) = self.verify_attr_dispatch_loop() { + return exit_code; + } - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - atan(n1) - ))); + if self.machine_st.fail { + continue; + } - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + self.machine_st.attr_var_init.cp = self.machine_st.p; + let (_, arity) = self.code[self.machine_st.p].to_name_and_arity(); + self.run_verify_attr_interrupt(arity); + } + &Instruction::Add(ref a1, ref a2, t) => self.machine_st.add_instr(a1, a2, t), + &Instruction::Sub(ref a1, ref a2, t) => self.machine_st.sub_instr(a1, a2, t), + &Instruction::Mul(ref a1, ref a2, t) => self.machine_st.mul_instr(a1, a2, t), + &Instruction::Max(ref a1, ref a2, t) => self.machine_st.max_instr(a1, a2, t), + &Instruction::Min(ref a1, ref a2, t) => self.machine_st.min_instr(a1, a2, t), + &Instruction::IntPow(ref a1, ref a2, t) => { + self.machine_st.int_pow_instr(a1, a2, t) + } + &Instruction::Gcd(ref a1, ref a2, t) => self.machine_st.gcd_instr(a1, a2, t), + &Instruction::Pow(ref a1, ref a2, t) => self.machine_st.pow_instr(a1, a2, t), + &Instruction::RDiv(ref a1, ref a2, t) => self.machine_st.rdiv_instr(a1, a2, t), + &Instruction::IntFloorDiv(ref a1, ref a2, t) => { + self.machine_st.int_floor_div_instr(a1, a2, t) } + &Instruction::IDiv(ref a1, ref a2, t) => self.machine_st.idiv_instr(a1, a2, t), + &Instruction::Abs(ref a1, t) => self.machine_st.abs_instr(a1, t), + &Instruction::Sign(ref a1, t) => self.machine_st.sign_instr(a1, t), + &Instruction::Neg(ref a1, t) => self.machine_st.neg_instr(a1, t), + &Instruction::BitwiseComplement(ref a1, t) => { + self.machine_st.bitwise_complement_instr(a1, t) + } + &Instruction::Div(ref a1, ref a2, t) => self.machine_st.div_instr(a1, a2, t), + &Instruction::Shr(ref a1, ref a2, t) => self.machine_st.shr_instr(a1, a2, t), + &Instruction::Shl(ref a1, ref a2, t) => self.machine_st.shl_instr(a1, a2, t), + &Instruction::Xor(ref a1, ref a2, t) => self.machine_st.xor_instr(a1, a2, t), + &Instruction::And(ref a1, ref a2, t) => self.machine_st.and_instr(a1, a2, t), + &Instruction::Or(ref a1, ref a2, t) => self.machine_st.or_instr(a1, a2, t), + &Instruction::Mod(ref a1, ref a2, t) => self.machine_st.mod_instr(a1, a2, t), + &Instruction::Rem(ref a1, ref a2, t) => self.machine_st.rem_instr(a1, a2, t), + &Instruction::Cos(ref a1, t) => self.machine_st.cos_instr(a1, t), + &Instruction::Sin(ref a1, t) => self.machine_st.sin_instr(a1, t), + &Instruction::Tan(ref a1, t) => self.machine_st.tan_instr(a1, t), + &Instruction::Sqrt(ref a1, t) => self.machine_st.sqrt_instr(a1, t), + &Instruction::Log(ref a1, t) => self.machine_st.log_instr(a1, t), + &Instruction::Exp(ref a1, t) => self.machine_st.exp_instr(a1, t), + &Instruction::ACos(ref a1, t) => self.machine_st.acos_instr(a1, t), + &Instruction::ASin(ref a1, t) => self.machine_st.asin_instr(a1, t), + &Instruction::ATan(ref a1, t) => self.machine_st.atan_instr(a1, t), &Instruction::ATan2(ref a1, ref a2, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2)); - - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - atan2(n1, n2) - ))); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + self.machine_st.atan2_instr(a1, a2, t) } - &Instruction::Float(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - float(n1) - ))); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::Float(ref a1, t) => self.machine_st.float_instr(a1, t), + &Instruction::Truncate(ref a1, t) => self.machine_st.truncate_instr(a1, t), + &Instruction::Round(ref a1, t) => self.machine_st.round_instr(a1, t), + &Instruction::Ceiling(ref a1, t) => self.machine_st.ceiling_instr(a1, t), + &Instruction::Floor(ref a1, t) => self.machine_st.floor_instr(a1, t), + &Instruction::FloatFractionalPart(ref a1, t) => { + self.machine_st.float_fractional_part_instr(a1, t) } - &Instruction::Truncate(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = truncate(n1, &mut self.machine_st.arena); - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::FloatIntegerPart(ref a1, t) => { + self.machine_st.float_integer_part_instr(a1, t) } - &Instruction::Round(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = try_or_throw_gen!( - &mut self.machine_st, - round(n1, &mut self.machine_st.arena) - ); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::Plus(ref a1, t) => self.machine_st.plus_instr(a1, t), + &Instruction::GetLevel(r) => self.machine_st.get_level_instr(r), + &Instruction::GetPrevLevel(r) => self.machine_st.get_prev_level_instr(r), + &Instruction::GetCutPoint(r) => self.machine_st.get_cut_point_instr(r), + &Instruction::Deallocate => self.machine_st.deallocate(), + &Instruction::GetConstant(_, c, reg) => { + self.machine_st.get_constant_instr(c, reg) } - &Instruction::Ceiling(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = ceiling(n1, &mut self.machine_st.arena); - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::GetList(_, reg) => self.machine_st.get_list_instr(reg), + &Instruction::GetPartialString(_, ref string, reg) => { + self.machine_st.get_partial_string_instr(string, reg) } - &Instruction::Floor(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = floor(n1, &mut self.machine_st.arena); - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::GetStructure(_lvl, name, arity, reg) => { + self.machine_st.get_structure_instr(name, arity, reg) } - &Instruction::FloatFractionalPart(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - float_fractional_part(n1) - ))); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::GetVariable(norm, arg) => { + self.machine_st.get_variable_instr(norm, arg) } - &Instruction::FloatIntegerPart(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - let value = Number::Float(OrderedFloat(try_or_throw_gen!( - &mut self.machine_st, - float_integer_part(n1) - ))); - - self.machine_st.registers[t] = - HeapCellValue::from((value, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::GetValue(norm, arg) => self.machine_st.get_value_instr(norm, arg), + &Instruction::UnifyConstant(v) => self.machine_st.unify_constant_instr(v), + &Instruction::UnifyLocalValue(reg) => { + self.machine_st.unify_local_value_instr(reg) } - &Instruction::Plus(ref a1, t) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); - - self.machine_st.registers[t] = - HeapCellValue::from((n1, &mut self.machine_st.arena)); - self.machine_st.p += 1; + &Instruction::UnifyVariable(reg) => self.machine_st.unify_variable_instr(reg), + &Instruction::UnifyValue(reg) => self.machine_st.unify_value_instr(reg), + &Instruction::UnifyVoid(n) => self.machine_st.unify_void_instr(n), + &Instruction::PutConstant(_, cell, reg) => { + self.machine_st.put_constant_instr(cell, reg) + } + &Instruction::PutList(_, reg) => self.machine_st.put_list_instr(reg), + &Instruction::PutPartialString(_, ref string, reg) => { + self.machine_st.put_partial_string_instr(string, reg) + } + &Instruction::PutStructure(name, arity, reg) => { + self.machine_st.put_structure_instr(name, arity, reg) + } + &Instruction::PutUnsafeValue(perm_slot, arg) => { + self.machine_st.put_unsafe_value_instr(perm_slot, arg) } + &Instruction::PutValue(norm, arg) => self.machine_st.put_value_instr(norm, arg), + &Instruction::PutVariable(norm, arg) => { + self.machine_st.put_variable_instr(norm, arg) + } + &Instruction::SetConstant(c) => self.machine_st.set_constant_instr(c), + &Instruction::SetLocalValue(reg) => self.machine_st.set_local_value_instr(reg), + &Instruction::SetVariable(reg) => self.machine_st.set_variable_instr(reg), + &Instruction::SetValue(reg) => self.machine_st.set_value_instr(reg), + &Instruction::SetVoid(n) => self.machine_st.set_void_instr(n), &Instruction::DynamicElse(..) => { if let FirstOrNext::First = self.machine_st.dynamic_mode { self.machine_st.cc = self.machine_st.global_clock; @@ -1292,37 +1996,6 @@ impl Machine { self.machine_st.neck_cut(); self.machine_st.p += 1; } - &Instruction::GetLevel(r) => { - let b0 = self.machine_st.b0; - - self.machine_st[r] = fixnum_as_cell!( - /* FIXME this is not safe */ - unsafe { Fixnum::build_with_unchecked(b0 as i64) }.as_cutpoint() - ); - self.machine_st.p += 1; - } - &Instruction::GetPrevLevel(r) => { - let prev_b = self - .machine_st - .stack - .index_or_frame(self.machine_st.b) - .prelude - .b; - - self.machine_st[r] = fixnum_as_cell!( - /* FIXME this is not safe */ - unsafe { Fixnum::build_with_unchecked(prev_b as i64) }.as_cutpoint() - ); - self.machine_st.p += 1; - } - &Instruction::GetCutPoint(r) => { - self.machine_st[r] = - fixnum_as_cell!(/* FIXME this is not safe */ unsafe { - Fixnum::build_with_unchecked(self.machine_st.b as i64) - } - .as_cutpoint()); - self.machine_st.p += 1; - } &Instruction::Cut(r) => { let value = self.machine_st[r]; self.machine_st.cut_body(value); @@ -1385,20 +2058,20 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } &Instruction::DefaultCallArg => { - try_or_throw!(self.machine_st, self.machine_st.try_arg()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.machine_st.try_arg(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::DefaultExecuteArg => { - try_or_throw!(self.machine_st, self.machine_st.try_arg()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.machine_st.try_arg(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::DefaultCallCompare => { - try_or_throw!(self.machine_st, self.machine_st.compare()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.machine_st.compare(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::DefaultExecuteCompare => { - try_or_throw!(self.machine_st, self.machine_st.compare()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.machine_st.compare(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::DefaultCallTermGreaterThan => { let a1 = self.machine_st.registers[1]; @@ -1496,7 +2169,7 @@ impl Machine { } &Instruction::DefaultCallCopyTerm => { self.machine_st.copy_term(AttrVarPolicy::DeepCopy); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::DefaultExecuteCopyTerm => { self.machine_st.copy_term(AttrVarPolicy::DeepCopy); @@ -1542,12 +2215,11 @@ impl Machine { } } &Instruction::DefaultCallFunctor => { - try_or_throw!(self.machine_st, self.machine_st.try_functor()); - - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.machine_st.try_functor(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::DefaultExecuteFunctor => { - try_or_throw!(self.machine_st, self.machine_st.try_functor()); + try_or_throw!(self.machine_st, self.machine_st.try_functor(), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1576,24 +2248,26 @@ impl Machine { } } &Instruction::DefaultCallSort => { - try_or_throw!(self.machine_st, self.machine_st.sort()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.machine_st.sort(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::DefaultExecuteSort => { - try_or_throw!(self.machine_st, self.machine_st.sort()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.machine_st.sort(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::DefaultCallKeySort => { try_or_throw!( self.machine_st, - self.machine_st.keysort(VarComparison::Distinct) + self.machine_st.keysort(VarComparison::Distinct), + continue ); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::DefaultExecuteKeySort => { try_or_throw!( self.machine_st, - self.machine_st.keysort(VarComparison::Distinct) + self.machine_st.keysort(VarComparison::Distinct), + continue ); if self.machine_st.fail { @@ -1603,20 +2277,20 @@ impl Machine { } } &Instruction::DefaultCallIs(r, at) => { - try_or_throw!(self.machine_st, self.machine_st.is(r, at)); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.machine_st.is(r, at), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::DefaultExecuteIs(r, at) => { - try_or_throw!(self.machine_st, self.machine_st.is(r, at)); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.machine_st.is(r, at), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } Instruction::DefaultCallGetNumber(at) => { - try_or_throw!(self.machine_st, self.machine_st.get_number(at)); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.machine_st.get_number(at), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } Instruction::DefaultExecuteGetNumber(at) => { - try_or_throw!(self.machine_st, self.machine_st.get_number(at)); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.machine_st.get_number(at), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallAcyclicTerm => { let addr = self.deref_register(1); @@ -1649,7 +2323,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } &Instruction::CallArg => { - try_or_throw!(self.machine_st, self.machine_st.try_arg()); + try_or_throw!(self.machine_st, self.machine_st.try_arg(), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1659,7 +2333,7 @@ impl Machine { } } &Instruction::ExecuteArg => { - try_or_throw!(self.machine_st, self.machine_st.try_arg()); + try_or_throw!(self.machine_st, self.machine_st.try_arg(), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1669,7 +2343,7 @@ impl Machine { } } &Instruction::CallCompare => { - try_or_throw!(self.machine_st, self.machine_st.compare()); + try_or_throw!(self.machine_st, self.machine_st.compare(), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1679,7 +2353,7 @@ impl Machine { } } &Instruction::ExecuteCompare => { - try_or_throw!(self.machine_st, self.machine_st.compare()); + try_or_throw!(self.machine_st, self.machine_st.compare(), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1849,7 +2523,7 @@ impl Machine { } } &Instruction::CallFunctor => { - try_or_throw!(self.machine_st, self.machine_st.try_functor()); + try_or_throw!(self.machine_st, self.machine_st.try_functor(), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1859,7 +2533,7 @@ impl Machine { } } &Instruction::ExecuteFunctor => { - try_or_throw!(self.machine_st, self.machine_st.try_functor()); + try_or_throw!(self.machine_st, self.machine_st.try_functor(), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1891,7 +2565,7 @@ impl Machine { } } &Instruction::CallSort => { - try_or_throw!(self.machine_st, self.machine_st.sort()); + try_or_throw!(self.machine_st, self.machine_st.sort(), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1901,7 +2575,7 @@ impl Machine { } } &Instruction::ExecuteSort => { - try_or_throw!(self.machine_st, self.machine_st.sort()); + try_or_throw!(self.machine_st, self.machine_st.sort(), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1913,7 +2587,8 @@ impl Machine { &Instruction::CallKeySort => { try_or_throw!( self.machine_st, - self.machine_st.keysort(VarComparison::Distinct) + self.machine_st.keysort(VarComparison::Distinct), + continue ); if self.machine_st.fail { @@ -1926,7 +2601,8 @@ impl Machine { &Instruction::ExecuteKeySort => { try_or_throw!( self.machine_st, - self.machine_st.keysort(VarComparison::Distinct) + self.machine_st.keysort(VarComparison::Distinct), + continue ); if self.machine_st.fail { @@ -1939,7 +2615,8 @@ impl Machine { &Instruction::CallKeySortWithConstantVarOrdering => { try_or_throw!( self.machine_st, - self.machine_st.keysort(VarComparison::Indistinct) + self.machine_st.keysort(VarComparison::Indistinct), + continue ); if self.machine_st.fail { @@ -1952,7 +2629,8 @@ impl Machine { &Instruction::ExecuteKeySortWithConstantVarOrdering => { try_or_throw!( self.machine_st, - self.machine_st.keysort(VarComparison::Indistinct) + self.machine_st.keysort(VarComparison::Indistinct), + continue ); if self.machine_st.fail { @@ -1963,7 +2641,7 @@ impl Machine { } } &Instruction::CallIs(r, at) => { - try_or_throw!(self.machine_st, self.machine_st.is(r, at)); + try_or_throw!(self.machine_st, self.machine_st.is(r, at), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1973,7 +2651,7 @@ impl Machine { } } &Instruction::ExecuteIs(r, at) => { - try_or_throw!(self.machine_st, self.machine_st.is(r, at)); + try_or_throw!(self.machine_st, self.machine_st.is(r, at), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1983,7 +2661,7 @@ impl Machine { } } Instruction::CallGetNumber(at) => { - try_or_throw!(self.machine_st, self.machine_st.get_number(at)); + try_or_throw!(self.machine_st, self.machine_st.get_number(at), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -1993,7 +2671,7 @@ impl Machine { } } Instruction::ExecuteGetNumber(at) => { - try_or_throw!(self.machine_st, self.machine_st.get_number(at)); + try_or_throw!(self.machine_st, self.machine_st.get_number(at), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -2011,7 +2689,7 @@ impl Machine { self.machine_st.registers[arity] = pred; - try_or_throw!(self.machine_st, self.call_n(atom!("user"), arity)); + try_or_throw!(self.machine_st, self.call_n(atom!("user"), arity), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -2028,7 +2706,11 @@ impl Machine { self.machine_st.registers[arity] = pred; - try_or_throw!(self.machine_st, self.execute_n(atom!("user"), arity)); + try_or_throw!( + self.machine_st, + self.execute_n(atom!("user"), arity), + continue + ); if self.machine_st.fail { self.machine_st.backtrack(); @@ -2045,7 +2727,7 @@ impl Machine { self.machine_st.registers[arity] = pred; - try_or_throw!(self.machine_st, self.call_n(atom!("user"), arity)); + try_or_throw!(self.machine_st, self.call_n(atom!("user"), arity), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -2060,15 +2742,27 @@ impl Machine { self.machine_st.registers[arity] = pred; - try_or_throw!(self.machine_st, self.execute_n(atom!("user"), arity)); + try_or_throw!( + self.machine_st, + self.execute_n(atom!("user"), arity), + continue + ); if self.machine_st.fail { self.machine_st.backtrack(); } } Instruction::CallNumberLessThanOrEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Less | Ordering::Equal => { @@ -2081,8 +2775,16 @@ impl Machine { } } Instruction::ExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Less | Ordering::Equal => { @@ -2095,8 +2797,16 @@ impl Machine { } } Instruction::CallNumberEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Equal => { @@ -2109,8 +2819,16 @@ impl Machine { } } Instruction::ExecuteNumberEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Equal => { @@ -2123,8 +2841,16 @@ impl Machine { } } Instruction::CallNumberNotEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Equal => { @@ -2137,8 +2863,16 @@ impl Machine { } } Instruction::ExecuteNumberNotEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Equal => { @@ -2151,8 +2885,16 @@ impl Machine { } } Instruction::CallNumberGreaterThanOrEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Greater | Ordering::Equal => { @@ -2165,8 +2907,16 @@ impl Machine { } } Instruction::ExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Greater | Ordering::Equal => { @@ -2179,8 +2929,16 @@ impl Machine { } } Instruction::CallNumberGreaterThan(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Greater => { @@ -2193,8 +2951,16 @@ impl Machine { } } Instruction::ExecuteNumberGreaterThan(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Greater => { @@ -2207,8 +2973,16 @@ impl Machine { } } Instruction::CallNumberLessThan(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Less => { @@ -2221,8 +2995,16 @@ impl Machine { } } Instruction::ExecuteNumberLessThan(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Less => { @@ -2235,8 +3017,16 @@ impl Machine { } } Instruction::DefaultCallNumberLessThanOrEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Less | Ordering::Equal => { @@ -2248,8 +3038,16 @@ impl Machine { } } Instruction::DefaultExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Less | Ordering::Equal => { @@ -2261,8 +3059,16 @@ impl Machine { } } Instruction::DefaultCallNumberNotEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Equal => { @@ -2274,8 +3080,16 @@ impl Machine { } } Instruction::DefaultExecuteNumberNotEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Equal => { @@ -2287,8 +3101,16 @@ impl Machine { } } Instruction::DefaultCallNumberEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Equal => { @@ -2300,8 +3122,16 @@ impl Machine { } } Instruction::DefaultExecuteNumberEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Equal => { @@ -2313,8 +3143,16 @@ impl Machine { } } Instruction::DefaultCallNumberGreaterThanOrEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Greater | Ordering::Equal => { @@ -2326,8 +3164,16 @@ impl Machine { } } Instruction::DefaultExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Greater | Ordering::Equal => { @@ -2339,8 +3185,16 @@ impl Machine { } } Instruction::DefaultCallNumberGreaterThan(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Greater => { @@ -2352,8 +3206,16 @@ impl Machine { } } Instruction::DefaultExecuteNumberGreaterThan(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Greater => { @@ -2365,8 +3227,16 @@ impl Machine { } } Instruction::DefaultCallNumberLessThan(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Less => { @@ -2378,8 +3248,16 @@ impl Machine { } } Instruction::DefaultExecuteNumberLessThan(ref at_1, ref at_2) => { - let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); - let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); + let n1 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_1), + continue + ); + let n2 = try_or_throw!( + self.machine_st, + self.machine_st.get_number(at_2), + continue + ); match n1.cmp(&n2) { Ordering::Less => { @@ -2704,533 +3582,145 @@ impl Machine { Ok(Number::Float(_)) => { self.machine_st.p += 1; } - _ => { - self.machine_st.backtrack(); - } - } - } - &Instruction::ExecuteIsFloat(r) => { - let d = self - .machine_st - .store(self.machine_st.deref(self.machine_st[r])); - - match Number::try_from((d, &self.machine_st.arena.f64_tbl)) { - Ok(Number::Float(_)) => { - self.machine_st.p = self.machine_st.cp; - } - _ => { - self.machine_st.backtrack(); - } - } - } - &Instruction::CallIsNonVar(r) => { - let d = self - .machine_st - .store(self.machine_st.deref(self.machine_st[r])); - - match d.get_tag() { - HeapCellValueTag::AttrVar - | HeapCellValueTag::Var - | HeapCellValueTag::StackVar => { - self.machine_st.backtrack(); - } - _ => { - self.machine_st.p += 1; - } - } - } - &Instruction::ExecuteIsNonVar(r) => { - let d = self - .machine_st - .store(self.machine_st.deref(self.machine_st[r])); - - match d.get_tag() { - HeapCellValueTag::AttrVar - | HeapCellValueTag::Var - | HeapCellValueTag::StackVar => { - self.machine_st.backtrack(); - } - _ => { - self.machine_st.p = self.machine_st.cp; - } - } - } - &Instruction::CallIsVar(r) => { - let d = self - .machine_st - .store(self.machine_st.deref(self.machine_st[r])); - - match d.get_tag() { - HeapCellValueTag::AttrVar - | HeapCellValueTag::Var - | HeapCellValueTag::StackVar => { - self.machine_st.p += 1; - } - _ => { - self.machine_st.backtrack(); - } - } - } - &Instruction::ExecuteIsVar(r) => { - let d = self - .machine_st - .store(self.machine_st.deref(self.machine_st[r])); - - match d.get_tag() { - HeapCellValueTag::AttrVar - | HeapCellValueTag::Var - | HeapCellValueTag::StackVar => { - self.machine_st.p = self.machine_st.cp; - } - _ => { - self.machine_st.backtrack(); - } - } - } - &Instruction::CallNamed(arity, name, idx) => { - let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into()); - - try_or_throw!(self.machine_st, self.try_call(name, arity, idx)); - - if self.machine_st.fail { - self.machine_st.backtrack(); - } else { - increment_call_count!(self.machine_st); - } - } - &Instruction::ExecuteNamed(arity, name, idx) => { - let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into()); - - try_or_throw!(self.machine_st, self.try_execute(name, arity, idx)); - - if self.machine_st.fail { - self.machine_st.backtrack(); - } else { - increment_call_count!(self.machine_st); - } - } - &Instruction::DefaultCallNamed(arity, name, idx) => { - let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into()); - - try_or_throw!(self.machine_st, self.try_call(name, arity, idx)); - - if self.machine_st.fail { - self.machine_st.backtrack(); - } - } - &Instruction::DefaultExecuteNamed(arity, name, idx) => { - let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into()); - - try_or_throw!(self.machine_st, self.try_execute(name, arity, idx)); - - if self.machine_st.fail { - self.machine_st.backtrack(); - } - } - &Instruction::Deallocate => self.machine_st.deallocate(), - &Instruction::JmpByCall(offset) => { - self.machine_st.p += offset; - } - &Instruction::RevJmpBy(offset) => { - self.machine_st.p -= offset; - } - &Instruction::Proceed => { - self.machine_st.p = self.machine_st.cp; - } - &Instruction::GetConstant(_, c, reg) => { - unify!(self.machine_st, self.machine_st[reg], c); - step_or_fail!(self, self.machine_st.p += 1); - } - &Instruction::GetList(_, reg) => { - let deref_v = self.machine_st.deref(self.machine_st[reg]); - let store_v = self.machine_st.store(deref_v); - - read_heap_cell!(store_v, - (HeapCellValueTag::PStrLoc, h) => { - self.machine_st.s = HeapPtr::PStr(h); - self.machine_st.s_offset = 0; - self.machine_st.mode = MachineMode::Read; - } - (HeapCellValueTag::Str, s) => { - let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) - .get_name_and_arity(); - - if name == atom!(".") && arity == 2 { - self.machine_st.s = HeapPtr::HeapCell(s+1); - self.machine_st.s_offset = 0; - self.machine_st.mode = MachineMode::Read; - } else { - self.machine_st.backtrack(); - continue; - } - } - (HeapCellValueTag::Lis, l) => { - self.machine_st.s = HeapPtr::HeapCell(l); - self.machine_st.s_offset = 0; - self.machine_st.mode = MachineMode::Read; - } - (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => { - let h = self.machine_st.heap.cell_len(); - - push_cell!(self.machine_st, list_loc_as_cell!(h+1)); - self.machine_st.bind(store_v.as_var().unwrap(), heap_loc_as_cell!(h)); - - self.machine_st.mode = MachineMode::Write; - } - _ => { - self.machine_st.backtrack(); - continue; - } - ); - - self.machine_st.p += 1; - } - &Instruction::GetPartialString(_, ref string, reg) => { - self.machine_st.heap[0] = self.machine_st[reg]; - - let mut h = 0; - let mut string_cursor = string.as_str(); - - if self.machine_st.heap[0].is_stack_var() { - let cell = self - .machine_st - .store(self.machine_st.deref(self.machine_st.heap[0])); - - if let Some(r) = cell.as_var() { - let target_cell = backtrack_on_resource_error!( - self.machine_st, - self.machine_st.heap.allocate_pstr(string_cursor) - ); - - self.machine_st.bind(r, target_cell); - self.machine_st.mode = MachineMode::Write; - - debug_assert!(!self.machine_st.fail); - self.machine_st.p += 1; - - continue; - } - - self.machine_st.heap[0] = cell; - } - - while let Some(c) = string_cursor.chars().next() { - read_heap_cell!(self.machine_st.heap[h], - (HeapCellValueTag::PStrLoc, pstr_loc) => { - let heap_slice = &self.machine_st.heap.as_slice()[pstr_loc ..]; - - match compare_pstr_slices(heap_slice, string_cursor.as_bytes()) { - PStrSegmentCmpResult::Continue(v1, v2) => { - // for v2, the value of a TailIndex mustn't ever be read - // since string does not lie in the heap. - match (v1, v2) { - (PStrContinuable::TailIndex(tail_idx), PStrContinuable::TailIndex(_)) => { - self.machine_st.s = HeapPtr::HeapCell(tail_idx + cell_index!(pstr_loc)); - self.machine_st.s_offset = 0; - self.machine_st.mode = MachineMode::Read; - - break; - } - (PStrContinuable::TailIndex(tail_idx), PStrContinuable::PStrOffset(pos)) => { - h = tail_idx + cell_index!(pstr_loc); - string_cursor = &string_cursor[pos ..]; - } - (PStrContinuable::PStrOffset(pos), PStrContinuable::TailIndex(_)) => { - self.machine_st.s = HeapPtr::PStr(pstr_loc); - self.machine_st.s_offset = pos; - self.machine_st.mode = MachineMode::Read; - - break; - } - _ => unreachable!(), - } - } - _ => { - self.machine_st.fail = true; - break; - } - } - } - (HeapCellValueTag::Lis, l) => { - let cell = self.machine_st.store(self.machine_st.deref(self.machine_st.heap[l])); - - if let Some(d) = cell.as_char() { - if c != d { - self.machine_st.fail = true; - break; - } - } else if let Some(r) = cell.as_var() { - self.machine_st.bind(r, char_as_cell!(c)); - } else { - self.machine_st.fail = true; - } - - if self.machine_st.fail { - break; - } else { - h = l+1; - string_cursor = &string_cursor[c.len_utf8() ..]; - - if string_cursor.is_empty() { - self.machine_st.s = HeapPtr::HeapCell(h); - self.machine_st.s_offset = 0; - self.machine_st.mode = MachineMode::Read; - } - } - } - (HeapCellValueTag::Str, s) => { - let cell = self.machine_st.store(self.machine_st.deref(self.machine_st.heap[s+1])); - - if let Some(d) = cell.as_char() { - if c != d { - self.machine_st.fail = true; - break; - } - } else if let Some(r) = cell.as_var() { - self.machine_st.bind(r, char_as_cell!(c)); - } else { - self.machine_st.fail = true; - } - - if self.machine_st.fail { - break; - } - - h = s+2; - string_cursor = &string_cursor[c.len_utf8() ..]; - - if string_cursor.is_empty() { - self.machine_st.s = HeapPtr::HeapCell(h); - self.machine_st.s_offset = 0; - self.machine_st.mode = MachineMode::Read; - } - } - (HeapCellValueTag::AttrVar | HeapCellValueTag::Var, v) => { - if h == v { - let target_cell = backtrack_on_resource_error!( - self.machine_st, - self.machine_st.heap.allocate_pstr(string_cursor) - ); - - self.machine_st.bind( - self.machine_st.heap[h].as_var().unwrap(), - target_cell, - ); - - self.machine_st.mode = MachineMode::Write; - break; - } else { - h = v; - } - } - _ => { - self.machine_st.fail = true; - break; - } - ); - } - - step_or_fail!(self, self.machine_st.p += 1); - } - &Instruction::GetStructure(_lvl, name, arity, reg) => { - let deref_v = self.machine_st.deref(self.machine_st[reg]); - let store_v = self.machine_st.store(deref_v); - - read_heap_cell!(store_v, - (HeapCellValueTag::Str, a) => { - read_heap_cell!(self.machine_st.heap[a], - (HeapCellValueTag::Atom, (result_name, result_arity)) => { - if arity == result_arity && name == result_name { - self.machine_st.s = HeapPtr::HeapCell(a + 1); - self.machine_st.s_offset = 0; - self.machine_st.mode = MachineMode::Read; - } else { - self.machine_st.backtrack(); - continue; - } - } - _ => { - unreachable!(); - } - ); - } - (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => { - let h = self.machine_st.heap.cell_len(); - - push_cell!(self.machine_st, str_loc_as_cell!(h+1)); - push_cell!(self.machine_st, atom_as_cell!(name, arity)); + _ => { + self.machine_st.backtrack(); + } + } + } + &Instruction::ExecuteIsFloat(r) => { + let d = self + .machine_st + .store(self.machine_st.deref(self.machine_st[r])); - self.machine_st.bind(store_v.as_var().unwrap(), heap_loc_as_cell!(h)); - self.machine_st.mode = MachineMode::Write; + match Number::try_from((d, &self.machine_st.arena.f64_tbl)) { + Ok(Number::Float(_)) => { + self.machine_st.p = self.machine_st.cp; } _ => { self.machine_st.backtrack(); - continue; } - ); - - self.machine_st.p += 1; - } - &Instruction::GetVariable(norm, arg) => { - self.machine_st[norm] = self.machine_st.registers[arg]; - self.machine_st.p += 1; + } } - &Instruction::GetValue(norm, arg) => { - let norm_addr = self.machine_st[norm]; - let reg_addr = self.machine_st.registers[arg]; - - unify_fn!(&mut self.machine_st, norm_addr, reg_addr); + &Instruction::CallIsNonVar(r) => { + let d = self + .machine_st + .store(self.machine_st.deref(self.machine_st[r])); - if self.machine_st.fail { - self.machine_st.backtrack(); - continue; + match d.get_tag() { + HeapCellValueTag::AttrVar + | HeapCellValueTag::Var + | HeapCellValueTag::StackVar => { + self.machine_st.backtrack(); + } + _ => { + self.machine_st.p += 1; + } } - - self.machine_st.p += 1; } - &Instruction::UnifyConstant(v) => { - match self.machine_st.mode { - MachineMode::Read => { - let (addr, s_offset_incr) = self.machine_st.read_s(); - unify!(&mut self.machine_st, addr, v); + &Instruction::ExecuteIsNonVar(r) => { + let d = self + .machine_st + .store(self.machine_st.deref(self.machine_st[r])); - if self.machine_st.fail { - self.machine_st.backtrack(); - continue; - } else { - self.machine_st.s_offset += s_offset_incr; - } + match d.get_tag() { + HeapCellValueTag::AttrVar + | HeapCellValueTag::Var + | HeapCellValueTag::StackVar => { + self.machine_st.backtrack(); } - MachineMode::Write => { - push_cell!(self.machine_st, v); + _ => { + self.machine_st.p = self.machine_st.cp; } } - - self.machine_st.p += 1; } - &Instruction::UnifyLocalValue(reg) => { - match self.machine_st.mode { - MachineMode::Read => { - let reg_addr = self.machine_st[reg]; - let (value, s_offset_incr) = self.machine_st.read_s(); - - unify_fn!(&mut self.machine_st, reg_addr, value); + &Instruction::CallIsVar(r) => { + let d = self + .machine_st + .store(self.machine_st.deref(self.machine_st[r])); - if self.machine_st.fail { - self.machine_st.backtrack(); - continue; - } else { - self.machine_st.s_offset += s_offset_incr; - } + match d.get_tag() { + HeapCellValueTag::AttrVar + | HeapCellValueTag::Var + | HeapCellValueTag::StackVar => { + self.machine_st.p += 1; } - MachineMode::Write => { - let value = self - .machine_st - .store(self.machine_st.deref(self.machine_st[reg])); - let h = self.machine_st.heap.cell_len(); - - read_heap_cell!(value, - (HeapCellValueTag::Var | HeapCellValueTag::AttrVar, hc) => { - let value = self.machine_st.heap[hc]; - - push_cell!(self.machine_st, value); - self.machine_st.s_offset += 1; - } - _ => { - push_cell!(self.machine_st, heap_loc_as_cell!(h)); - (self.machine_st.bind_fn)( - &mut self.machine_st, - Ref::heap_cell(h), - value, - ); - } - ); + _ => { + self.machine_st.backtrack(); } } - - self.machine_st.p += 1; } - &Instruction::UnifyVariable(reg) => { - match self.machine_st.mode { - MachineMode::Read => { - let (value, s_offset_incr) = self.machine_st.read_s(); - self.machine_st[reg] = value; - self.machine_st.s_offset += s_offset_incr; + &Instruction::ExecuteIsVar(r) => { + let d = self + .machine_st + .store(self.machine_st.deref(self.machine_st[r])); + + match d.get_tag() { + HeapCellValueTag::AttrVar + | HeapCellValueTag::Var + | HeapCellValueTag::StackVar => { + self.machine_st.p = self.machine_st.cp; } - MachineMode::Write => { - let h = self.machine_st.heap.cell_len(); - push_cell!(self.machine_st, heap_loc_as_cell!(h)); - self.machine_st[reg] = heap_loc_as_cell!(h); + _ => { + self.machine_st.backtrack(); } } - - self.machine_st.p += 1; } - &Instruction::UnifyValue(reg) => { - match self.machine_st.mode { - MachineMode::Read => { - let reg_addr = self.machine_st[reg]; - let (value, s_offset_incr) = self.machine_st.read_s(); + &Instruction::CallNamed(arity, name, idx) => { + let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into()); - unify_fn!(&mut self.machine_st, reg_addr, value); + try_or_throw!(self.machine_st, self.try_call(name, arity, idx), continue); - if self.machine_st.fail { - self.machine_st.backtrack(); - continue; - } else { - self.machine_st.s_offset += s_offset_incr; - } - } - MachineMode::Write => { - let h = self.machine_st.heap.cell_len(); - push_cell!(self.machine_st, heap_loc_as_cell!(h)); + if self.machine_st.fail { + self.machine_st.backtrack(); + } else { + increment_call_count!(self.machine_st); + } + } + &Instruction::ExecuteNamed(arity, name, idx) => { + let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into()); - let addr = self.machine_st.store(self.machine_st[reg]); - (self.machine_st.bind_fn)( - &mut self.machine_st, - Ref::heap_cell(h), - addr, - ); + try_or_throw!( + self.machine_st, + self.try_execute(name, arity, idx), + continue + ); - // the former code of this match arm was: + if self.machine_st.fail { + self.machine_st.backtrack(); + } else { + increment_call_count!(self.machine_st); + } + } + &Instruction::DefaultCallNamed(arity, name, idx) => { + let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into()); - // let addr = self.machine_st.store(self.machine_st[reg]); - // push_cell!(self.machine_st, HeapCellValue::Addr(addr)); + try_or_throw!(self.machine_st, self.try_call(name, arity, idx), continue); - // the old code didn't perform the occurs - // check when enabled and so it was changed to - // the above, which is only slightly less - // efficient when the occurs_check is disabled. - } + if self.machine_st.fail { + self.machine_st.backtrack(); } - - self.machine_st.p += 1; } - &Instruction::UnifyVoid(n) => { - match self.machine_st.mode { - MachineMode::Read => match &self.machine_st.s { - HeapPtr::HeapCell(_) => self.machine_st.s_offset += n, - &HeapPtr::PStr(pstr_loc) => { - debug_assert!(n <= 2); - let mut char_iter = self.machine_st.heap.char_iter(pstr_loc); - - // this only matters in the case that n == 1, but the case - // analysis isn't worth doing since the effect is benign if n == - // 2 - self.machine_st.s_offset += - char_iter.next().unwrap().len_utf8(); - } - }, - MachineMode::Write => { - let h = self.machine_st.heap.cell_len(); + &Instruction::DefaultExecuteNamed(arity, name, idx) => { + let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into()); - for i in h..h + n { - push_cell!(self.machine_st, heap_loc_as_cell!(i)); - } - } - } + try_or_throw!( + self.machine_st, + self.try_execute(name, arity, idx), + continue + ); - self.machine_st.p += 1; + if self.machine_st.fail { + self.machine_st.backtrack(); + } + } + &Instruction::JmpByCall(offset) => { + self.machine_st.p += offset; + } + &Instruction::RevJmpBy(offset) => { + self.machine_st.p -= offset; + } + &Instruction::Proceed => { + self.machine_st.p = self.machine_st.cp; } Instruction::IndexingCode(ref indexing_lines) => { match &indexing_lines[self.machine_st.oip as usize] { @@ -3362,123 +3852,10 @@ impl Machine { } } } - &Instruction::PutConstant(_, cell, reg) => { - self.machine_st[reg] = cell; - self.machine_st.p += 1; - } - &Instruction::PutList(_, reg) => { - self.machine_st[reg] = list_loc_as_cell!(self.machine_st.heap.cell_len()); - self.machine_st.p += 1; - } - &Instruction::PutPartialString(_, ref string, reg) => { - self.machine_st[reg] = backtrack_on_resource_error!( - self.machine_st, - self.machine_st.heap.allocate_pstr(string) - ); - - self.machine_st.p += 1; - } - &Instruction::PutStructure(name, arity, reg) => { - let h = self.machine_st.heap.cell_len(); - - push_cell!(self.machine_st, atom_as_cell!(name, arity)); - self.machine_st[reg] = str_loc_as_cell!(h); - - self.machine_st.p += 1; - } - &Instruction::PutUnsafeValue(perm_slot, arg) => { - let s = stack_loc!(AndFrame, self.machine_st.e, perm_slot); - let addr = self - .machine_st - .store(self.machine_st.deref(stack_loc_as_cell!(s))); - - if addr.is_protected(self.machine_st.e) { - self.machine_st.registers[arg] = addr; - } else { - let h = self.machine_st.heap.cell_len(); - - push_cell!(self.machine_st, heap_loc_as_cell!(h)); - (self.machine_st.bind_fn)( - &mut self.machine_st, - Ref::heap_cell(h), - addr, - ); - - self.machine_st.registers[arg] = heap_loc_as_cell!(h); - } - - self.machine_st.p += 1; - } - &Instruction::PutValue(norm, arg) => { - self.machine_st.registers[arg] = self.machine_st[norm]; - self.machine_st.p += 1; - } - &Instruction::PutVariable(norm, arg) => { - match norm { - RegType::Perm(n) => { - self.machine_st[norm] = - stack_loc_as_cell!(AndFrame, self.machine_st.e, n); - self.machine_st.registers[arg] = self.machine_st[norm]; - } - RegType::Temp(_) => { - let h = self.machine_st.heap.cell_len(); - push_cell!(self.machine_st, heap_loc_as_cell!(h)); - - self.machine_st[norm] = heap_loc_as_cell!(h); - self.machine_st.registers[arg] = heap_loc_as_cell!(h); - } - }; - - self.machine_st.p += 1; - } - &Instruction::SetConstant(c) => { - push_cell!(self.machine_st, c); - self.machine_st.p += 1; - } - &Instruction::SetLocalValue(reg) => { - let addr = self.machine_st.deref(self.machine_st[reg]); - let stored_v = self.machine_st.store(addr); - - if stored_v.is_stack_var() { - let h = self.machine_st.heap.cell_len(); - push_cell!(self.machine_st, heap_loc_as_cell!(h)); - (self.machine_st.bind_fn)( - &mut self.machine_st, - Ref::heap_cell(h), - stored_v, - ); - } else { - push_cell!(self.machine_st, stored_v); - } - - self.machine_st.p += 1; - } - &Instruction::SetVariable(reg) => { - let h = self.machine_st.heap.cell_len(); - - push_cell!(self.machine_st, heap_loc_as_cell!(h)); - self.machine_st[reg] = heap_loc_as_cell!(h); - - self.machine_st.p += 1; - } - &Instruction::SetValue(reg) => { - let heap_val = self.machine_st.store(self.machine_st[reg]); - push_cell!(self.machine_st, heap_val); - self.machine_st.p += 1; - } - &Instruction::SetVoid(n) => { - let h = self.machine_st.heap.cell_len(); - - for i in h..h + n { - push_cell!(self.machine_st, heap_loc_as_cell!(i)); - } - - self.machine_st.p += 1; - } // &Instruction::CallAtomChars => { self.atom_chars(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteAtomChars => { self.atom_chars(); @@ -3490,7 +3867,7 @@ impl Machine { } } &Instruction::CallAtomCodes => { - try_or_throw!(self.machine_st, self.atom_codes()); + try_or_throw!(self.machine_st, self.atom_codes(), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -3499,7 +3876,7 @@ impl Machine { } } &Instruction::ExecuteAtomCodes => { - try_or_throw!(self.machine_st, self.atom_codes()); + try_or_throw!(self.machine_st, self.atom_codes(), continue); if self.machine_st.fail { self.machine_st.backtrack(); @@ -3509,241 +3886,246 @@ impl Machine { } &Instruction::CallAtomLength => { self.atom_length(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteAtomLength => { self.atom_length(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallBindFromRegister => { self.bind_from_register(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteBindFromRegister => { self.bind_from_register(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallContinuation => { - try_or_throw!(self.machine_st, self.call_continuation(false)); + try_or_throw!(self.machine_st, self.call_continuation(false), continue); } &Instruction::ExecuteContinuation => { - try_or_throw!(self.machine_st, self.call_continuation(true)); + try_or_throw!(self.machine_st, self.call_continuation(true), continue); } &Instruction::CallCharCode => { - try_or_throw!(self.machine_st, self.char_code()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.char_code(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCharCode => { - try_or_throw!(self.machine_st, self.char_code()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.char_code(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCharType => { self.char_type(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCharType => { self.char_type(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCharsToNumber => { - try_or_throw!(self.machine_st, self.chars_to_number()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.chars_to_number(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCharsToNumber => { - try_or_throw!(self.machine_st, self.chars_to_number()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.chars_to_number(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCodesToNumber => { - try_or_throw!(self.machine_st, self.codes_to_number()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.codes_to_number(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCodesToNumber => { - try_or_throw!(self.machine_st, self.codes_to_number()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.codes_to_number(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCopyTermWithoutAttrVars => { self.copy_term_without_attr_vars(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCopyTermWithoutAttrVars => { self.copy_term_without_attr_vars(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCheckCutPoint => { self.check_cut_point(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCheckCutPoint => { self.check_cut_point(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallClose => { - try_or_throw!(self.machine_st, self.close()); + try_or_throw!(self.machine_st, self.close(), continue); self.machine_st.p += 1; } &Instruction::ExecuteClose => { - try_or_throw!(self.machine_st, self.close()); + try_or_throw!(self.machine_st, self.close(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallCopyToLiftedHeap => { self.copy_to_lifted_heap(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCopyToLiftedHeap => { self.copy_to_lifted_heap(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCreatePartialString => { self.create_partial_string(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCreatePartialString => { self.create_partial_string(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCurrentHostname => { self.current_hostname(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCurrentHostname => { self.current_hostname(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCurrentInput => { - try_or_throw!(self.machine_st, self.current_input()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.current_input(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCurrentInput => { - try_or_throw!(self.machine_st, self.current_input()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.current_input(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCurrentOutput => { - try_or_throw!(self.machine_st, self.current_output()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.current_output(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCurrentOutput => { - try_or_throw!(self.machine_st, self.current_output()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.current_output(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDirectoryFiles => { - try_or_throw!(self.machine_st, self.directory_files()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.directory_files(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteDirectoryFiles => { - try_or_throw!(self.machine_st, self.directory_files()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.directory_files(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallFileSize => { self.file_size(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteFileSize => { self.file_size(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallFileExists => { self.file_exists(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteFileExists => { self.file_exists(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDirectoryExists => { self.directory_exists(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteDirectoryExists => { self.directory_exists(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDirectorySeparator => { self.directory_separator(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteDirectorySeparator => { self.directory_separator(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallMakeDirectory => { self.make_directory(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteMakeDirectory => { self.make_directory(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallMakeDirectoryPath => { self.make_directory_path(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteMakeDirectoryPath => { self.make_directory_path(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDeleteFile => { self.delete_file(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteDeleteFile => { self.delete_file(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallRenameFile => { self.rename_file(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteRenameFile => { self.rename_file(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallFileCopy => { self.file_copy(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteFileCopy => { self.file_copy(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallWorkingDirectory => { - try_or_throw!(self.machine_st, self.working_directory()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.working_directory(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteWorkingDirectory => { - try_or_throw!(self.machine_st, self.working_directory()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.working_directory(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDeleteDirectory => { self.delete_directory(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteDeleteDirectory => { self.delete_directory(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPathCanonical => { - try_or_throw!(self.machine_st, self.path_canonical()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.path_canonical(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePathCanonical => { - try_or_throw!(self.machine_st, self.path_canonical()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.path_canonical(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallFileTime => { self.file_time(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteFileTime => { self.file_time(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDynamicModuleResolution(arity) => { let (module_name, key) = try_or_throw!( self.machine_st, - self.dynamic_module_resolution(arity - 2) + self.dynamic_module_resolution(arity - 2), + continue ); - try_or_throw!(self.machine_st, self.call_clause(module_name, key)); + try_or_throw!( + self.machine_st, + self.call_clause(module_name, key), + continue + ); if self.machine_st.fail { self.machine_st.backtrack(); @@ -3752,10 +4134,15 @@ impl Machine { &Instruction::ExecuteDynamicModuleResolution(arity) => { let (module_name, key) = try_or_throw!( self.machine_st, - self.dynamic_module_resolution(arity - 2) + self.dynamic_module_resolution(arity - 2), + continue ); - try_or_throw!(self.machine_st, self.execute_clause(module_name, key)); + try_or_throw!( + self.machine_st, + self.execute_clause(module_name, key), + continue + ); if self.machine_st.fail { self.machine_st.backtrack(); @@ -3763,384 +4150,384 @@ impl Machine { } &Instruction::CallFetchGlobalVar => { self.fetch_global_var(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteFetchGlobalVar => { self.fetch_global_var(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallFirstStream => { self.first_stream(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteFirstStream => { self.first_stream(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallFlushOutput => { - try_or_throw!(self.machine_st, self.flush_output()); + try_or_throw!(self.machine_st, self.flush_output(), continue); self.machine_st.p += 1; } &Instruction::ExecuteFlushOutput => { - try_or_throw!(self.machine_st, self.flush_output()); + try_or_throw!(self.machine_st, self.flush_output(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallGetByte => { - try_or_throw!(self.machine_st, self.get_byte()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.get_byte(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetByte => { - try_or_throw!(self.machine_st, self.get_byte()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.get_byte(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetChar => { - try_or_throw!(self.machine_st, self.get_char()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.get_char(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetChar => { - try_or_throw!(self.machine_st, self.get_char()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.get_char(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetNChars => { - try_or_throw!(self.machine_st, self.get_n_chars()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.get_n_chars(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetNChars => { - try_or_throw!(self.machine_st, self.get_n_chars()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.get_n_chars(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetCode => { - try_or_throw!(self.machine_st, self.get_code()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.get_code(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetCode => { - try_or_throw!(self.machine_st, self.get_code()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.get_code(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetSingleChar => { - try_or_throw!(self.machine_st, self.get_single_char()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.get_single_char(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetSingleChar => { - try_or_throw!(self.machine_st, self.get_single_char()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.get_single_char(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallTruncateIfNoLiftedHeapGrowthDiff => { self.truncate_if_no_lifted_heap_growth_diff(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteTruncateIfNoLiftedHeapGrowthDiff => { self.truncate_if_no_lifted_heap_growth_diff(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallTruncateIfNoLiftedHeapGrowth => { self.truncate_if_no_lifted_heap_growth(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteTruncateIfNoLiftedHeapGrowth => { self.truncate_if_no_lifted_heap_growth(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetAttributedVariableList => { self.get_attributed_variable_list(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetAttributedVariableList => { self.get_attributed_variable_list(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetAttrVarQueueDelimiter => { self.get_attr_var_queue_delimiter(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetAttrVarQueueDelimiter => { self.get_attr_var_queue_delimiter(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetAttrVarQueueBeyond => { self.get_attr_var_queue_beyond(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetAttrVarQueueBeyond => { self.get_attr_var_queue_beyond(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetBValue => { self.get_b_value(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetBValue => { self.get_b_value(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetContinuationChunk => { self.get_continuation_chunk(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetContinuationChunk => { self.get_continuation_chunk(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLookupDBRef => { self.lookup_db_ref(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLookupDBRef => { self.lookup_db_ref(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetNextOpDBRef => { self.get_next_op_db_ref(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetNextOpDBRef => { self.get_next_op_db_ref(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallIsPartialString => { self.is_partial_string(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteIsPartialString => { self.is_partial_string(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallHalt | &Instruction::ExecuteHalt => { return self.halt(); } &Instruction::CallGetLiftedHeapFromOffset => { self.get_lifted_heap_from_offset(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetLiftedHeapFromOffset => { self.get_lifted_heap_from_offset(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetLiftedHeapFromOffsetDiff => { self.get_lifted_heap_from_offset_diff(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetLiftedHeapFromOffsetDiff => { self.get_lifted_heap_from_offset_diff(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetSCCCleaner => { self.get_scc_cleaner(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetSCCCleaner => { self.get_scc_cleaner(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallHeadIsDynamic => { self.head_is_dynamic(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteHeadIsDynamic => { self.head_is_dynamic(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInstallSCCCleaner => { self.install_scc_cleaner(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteInstallSCCCleaner => { self.install_scc_cleaner(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInstallInferenceCounter => { - try_or_throw!(self.machine_st, self.install_inference_counter()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.install_inference_counter(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteInstallInferenceCounter => { - try_or_throw!(self.machine_st, self.install_inference_counter()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.install_inference_counter(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInferenceCount => { let global_count = self.machine_st.cwil.global_count.clone(); self.inference_count(self.machine_st.registers[1], global_count); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteInferenceCount => { let global_count = self.machine_st.cwil.global_count.clone(); self.inference_count(self.machine_st.registers[1], global_count); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLiftedHeapLength => { self.lifted_heap_length(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLiftedHeapLength => { self.lifted_heap_length(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLoadLibraryAsStream => { - try_or_throw!(self.machine_st, self.load_library_as_stream()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.load_library_as_stream(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLoadLibraryAsStream => { - try_or_throw!(self.machine_st, self.load_library_as_stream()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.load_library_as_stream(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallModuleExists => { self.module_exists(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteModuleExists => { self.module_exists(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallNextEP => { self.next_ep(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteNextEP => { self.next_ep(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallNoSuchPredicate => { - try_or_throw!(self.machine_st, self.no_such_predicate()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.no_such_predicate(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteNoSuchPredicate => { - try_or_throw!(self.machine_st, self.no_such_predicate()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.no_such_predicate(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallNumberToChars => { self.number_to_chars(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteNumberToChars => { self.number_to_chars(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallNumberToCodes => { self.number_to_codes(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteNumberToCodes => { self.number_to_codes(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallOpDeclaration => { - try_or_throw!(self.machine_st, self.op_declaration()); + try_or_throw!(self.machine_st, self.op_declaration(), continue); self.machine_st.p += 1; } &Instruction::ExecuteOpDeclaration => { - try_or_throw!(self.machine_st, self.op_declaration()); + try_or_throw!(self.machine_st, self.op_declaration(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallOpen => { - try_or_throw!(self.machine_st, self.open()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.open(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteOpen => { - try_or_throw!(self.machine_st, self.open()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.open(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSetStreamOptions => { - try_or_throw!(self.machine_st, self.set_stream_options()); + try_or_throw!(self.machine_st, self.set_stream_options(), continue); self.machine_st.p += 1; } &Instruction::ExecuteSetStreamOptions => { - try_or_throw!(self.machine_st, self.set_stream_options()); + try_or_throw!(self.machine_st, self.set_stream_options(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallNextStream => { self.next_stream(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteNextStream => { self.next_stream(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPartialStringTail => { self.partial_string_tail(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePartialStringTail => { self.partial_string_tail(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPeekByte => { - try_or_throw!(self.machine_st, self.peek_byte()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.peek_byte(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePeekByte => { - try_or_throw!(self.machine_st, self.peek_byte()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.peek_byte(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPeekChar => { - try_or_throw!(self.machine_st, self.peek_char()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.peek_char(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePeekChar => { - try_or_throw!(self.machine_st, self.peek_char()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.peek_char(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPeekCode => { - try_or_throw!(self.machine_st, self.peek_code()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.peek_code(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePeekCode => { - try_or_throw!(self.machine_st, self.peek_code()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.peek_code(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPointsToContinuationResetMarker => { self.points_to_continuation_reset_marker(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePointsToContinuationResetMarker => { self.points_to_continuation_reset_marker(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPutByte => { - try_or_throw!(self.machine_st, self.put_byte()); + try_or_throw!(self.machine_st, self.put_byte(), continue); self.machine_st.p += 1; } &Instruction::ExecutePutByte => { - try_or_throw!(self.machine_st, self.put_byte()); + try_or_throw!(self.machine_st, self.put_byte(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallPutChar => { - try_or_throw!(self.machine_st, self.put_char()); + try_or_throw!(self.machine_st, self.put_char(), continue); self.machine_st.p += 1; } &Instruction::ExecutePutChar => { - try_or_throw!(self.machine_st, self.put_char()); + try_or_throw!(self.machine_st, self.put_char(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallPutChars => { - try_or_throw!(self.machine_st, self.put_chars()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.put_chars(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePutChars => { - try_or_throw!(self.machine_st, self.put_chars()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.put_chars(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPutCode => { - try_or_throw!(self.machine_st, self.put_code()); + try_or_throw!(self.machine_st, self.put_code(), continue); self.machine_st.p += 1; } &Instruction::ExecutePutCode => { - try_or_throw!(self.machine_st, self.put_code()); + try_or_throw!(self.machine_st, self.put_code(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallReadQueryTerm => { - try_or_throw!(self.machine_st, self.read_query_term()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.read_query_term(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteReadQueryTerm => { - try_or_throw!(self.machine_st, self.read_query_term()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.read_query_term(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallReadTerm => { - try_or_throw!(self.machine_st, self.read_term()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.read_term(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteReadTerm => { - try_or_throw!(self.machine_st, self.read_term()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.read_term(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallRedoAttrVarBinding => { self.redo_attr_var_binding(); @@ -4160,11 +4547,11 @@ impl Machine { } &Instruction::CallRemoveInferenceCounter => { self.remove_inference_counter(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteRemoveInferenceCounter => { self.remove_inference_counter(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallResetContinuationMarker => { self.reset_continuation_marker(); @@ -4184,14 +4571,14 @@ impl Machine { } &Instruction::CallSetCutPoint(r) => { if !self.set_cut_point(r) { - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } } &Instruction::ExecuteSetCutPoint(r) => { let cp = self.machine_st.cp; if !self.set_cut_point(r) { - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } else { // run_cleaners in set_cut_point calls call_by_index. // replace the effect of call_by_index with that @@ -4201,19 +4588,19 @@ impl Machine { } } &Instruction::CallSetInput => { - try_or_throw!(self.machine_st, self.set_input()); + try_or_throw!(self.machine_st, self.set_input(), continue); self.machine_st.p += 1; } &Instruction::ExecuteSetInput => { - try_or_throw!(self.machine_st, self.set_input()); + try_or_throw!(self.machine_st, self.set_input(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallSetOutput => { - try_or_throw!(self.machine_st, self.set_output()); + try_or_throw!(self.machine_st, self.set_output(), continue); self.machine_st.p += 1; } &Instruction::ExecuteSetOutput => { - try_or_throw!(self.machine_st, self.set_output()); + try_or_throw!(self.machine_st, self.set_output(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallStoreBacktrackableGlobalVar => { @@ -4233,28 +4620,28 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } &Instruction::CallStreamProperty => { - try_or_throw!(self.machine_st, self.stream_property()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.stream_property(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteStreamProperty => { - try_or_throw!(self.machine_st, self.stream_property()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.stream_property(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSetStreamPosition => { - try_or_throw!(self.machine_st, self.set_stream_position()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.set_stream_position(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteSetStreamPosition => { - try_or_throw!(self.machine_st, self.set_stream_position()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.set_stream_position(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInferenceLevel => { self.inference_level(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteInferenceLevel => { self.inference_level(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCleanUpBlock => { self.clean_up_block(); @@ -4269,245 +4656,245 @@ impl Machine { } &Instruction::CallGetBall => { self.get_ball(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetBall => { self.get_ball(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetCurrentBlock => { self.get_current_block(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetCurrentBlock => { self.get_current_block(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetCurrentSCCBlock => { self.get_current_scc_block(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetCurrentSCCBlock => { self.get_current_scc_block(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetCutPoint => { self.get_cut_point(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetCutPoint => { self.get_cut_point(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetDoubleQuotes => { self.get_double_quotes(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetDoubleQuotes => { self.get_double_quotes(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetUnknown => { self.get_unknown(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetUnknown => { self.get_unknown(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInstallNewBlock => { self.machine_st .install_new_block(self.machine_st.registers[1]); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteInstallNewBlock => { self.machine_st .install_new_block(self.machine_st.registers[1]); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallRandomInteger => { self.random_integer(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteRandomInteger => { self.random_integer(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallMaybe => { self.maybe(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteMaybe => { self.maybe(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCpuNow => { self.cpu_now(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCpuNow => { self.cpu_now(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDeterministicLengthRundown => { - try_or_throw!(self.machine_st, self.det_length_rundown()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.det_length_rundown(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteDeterministicLengthRundown => { - try_or_throw!(self.machine_st, self.det_length_rundown()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.det_length_rundown(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallHttpOpen => { #[cfg(feature = "http")] - try_or_throw!(self.machine_st, self.http_open()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.http_open(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteHttpOpen => { #[cfg(feature = "http")] - try_or_throw!(self.machine_st, self.http_open()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.http_open(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallHttpListen => { #[cfg(feature = "http")] - try_or_throw!(self.machine_st, self.http_listen()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.http_listen(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteHttpListen => { #[cfg(feature = "http")] - try_or_throw!(self.machine_st, self.http_listen()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.http_listen(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallHttpAccept => { #[cfg(feature = "http")] - try_or_throw!(self.machine_st, self.http_accept()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.http_accept(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteHttpAccept => { #[cfg(feature = "http")] - try_or_throw!(self.machine_st, self.http_accept()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.http_accept(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallHttpAnswer => { #[cfg(feature = "http")] - try_or_throw!(self.machine_st, self.http_answer()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.http_answer(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteHttpAnswer => { #[cfg(feature = "http")] - try_or_throw!(self.machine_st, self.http_answer()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.http_answer(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLoadForeignLib => { - try_or_throw!(self.machine_st, self.load_foreign_lib()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.load_foreign_lib(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLoadForeignLib => { - try_or_throw!(self.machine_st, self.load_foreign_lib()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.load_foreign_lib(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallForeignCall => { - try_or_throw!(self.machine_st, self.foreign_call()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.foreign_call(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteForeignCall => { - try_or_throw!(self.machine_st, self.foreign_call()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.foreign_call(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDefineForeignStruct => { - try_or_throw!(self.machine_st, self.define_foreign_struct()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.define_foreign_struct(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteDefineForeignStruct => { - try_or_throw!(self.machine_st, self.define_foreign_struct()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.define_foreign_struct(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallFfiAllocate => { - try_or_throw!(self.machine_st, self.ffi_allocate()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.ffi_allocate(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteFfiAllocate => { - try_or_throw!(self.machine_st, self.ffi_allocate()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.ffi_allocate(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallFfiReadPtr => { - try_or_throw!(self.machine_st, self.ffi_read_ptr()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.ffi_read_ptr(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteFfiReadPtr => { - try_or_throw!(self.machine_st, self.ffi_read_ptr()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.ffi_read_ptr(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallFfiDeallocate => { - try_or_throw!(self.machine_st, self.ffi_deallocate()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.ffi_deallocate(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteFfiDeallocate => { - try_or_throw!(self.machine_st, self.ffi_deallocate()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.ffi_deallocate(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallJsEval => { - try_or_throw!(self.machine_st, self.js_eval()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.js_eval(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteJsEval => { - try_or_throw!(self.machine_st, self.js_eval()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.js_eval(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallArgv => { - try_or_throw!(self.machine_st, self.argv()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.argv(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteArgv => { - try_or_throw!(self.machine_st, self.argv()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.argv(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCurrentTime => { self.current_time(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCurrentTime => { self.current_time(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallQuotedToken => { self.quoted_token(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteQuotedToken => { self.quoted_token(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallReadFromChars => { - try_or_throw!(self.machine_st, self.read_from_chars()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.read_from_chars(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteReadFromChars => { - try_or_throw!(self.machine_st, self.read_from_chars()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.read_from_chars(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallReadTermFromChars => { - try_or_throw!(self.machine_st, self.read_term_from_chars()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.read_term_from_chars(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteReadTermFromChars => { - try_or_throw!(self.machine_st, self.read_term_from_chars()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.read_term_from_chars(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallResetBlock => { self.reset_block(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteResetBlock => { self.reset_block(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallResetSCCBlock => { self.reset_scc_block(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteResetSCCBlock => { self.reset_scc_block(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallReturnFromVerifyAttr | &Instruction::ExecuteReturnFromVerifyAttr => { @@ -4515,19 +4902,19 @@ impl Machine { } &Instruction::CallSetBall => { self.set_ball(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteSetBall => { self.set_ball(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPushBallStack => { self.push_ball_stack(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePushBallStack => { self.push_ball_stack(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPopBallStack => { self.pop_ball_stack(); @@ -4547,43 +4934,43 @@ impl Machine { } &Instruction::CallSetCutPointByDefault(r) => { self.set_cut_point_by_default(r); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteSetCutPointByDefault(r) => { self.set_cut_point_by_default(r); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSetDoubleQuotes => { self.set_double_quotes(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteSetDoubleQuotes => { self.set_double_quotes(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSetUnknown => { self.set_unknown(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteSetUnknown => { self.set_unknown(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSetSeed => { self.set_seed(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteSetSeed => { self.set_seed(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSkipMaxList => { - try_or_throw!(self.machine_st, self.machine_st.skip_max_list()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.machine_st.skip_max_list(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteSkipMaxList => { - try_or_throw!(self.machine_st, self.machine_st.skip_max_list()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.machine_st.skip_max_list(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSleep => { self.sleep(); @@ -4594,56 +4981,56 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } &Instruction::CallSocketClientOpen => { - try_or_throw!(self.machine_st, self.socket_client_open()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.socket_client_open(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteSocketClientOpen => { - try_or_throw!(self.machine_st, self.socket_client_open()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.socket_client_open(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSocketServerOpen => { - try_or_throw!(self.machine_st, self.socket_server_open()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.socket_server_open(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteSocketServerOpen => { - try_or_throw!(self.machine_st, self.socket_server_open()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.socket_server_open(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSocketServerAccept => { - try_or_throw!(self.machine_st, self.socket_server_accept()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.socket_server_accept(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteSocketServerAccept => { - try_or_throw!(self.machine_st, self.socket_server_accept()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.socket_server_accept(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSocketServerClose => { - try_or_throw!(self.machine_st, self.socket_server_close()); + try_or_throw!(self.machine_st, self.socket_server_close(), continue); self.machine_st.p += 1; } &Instruction::ExecuteSocketServerClose => { - try_or_throw!(self.machine_st, self.socket_server_close()); + try_or_throw!(self.machine_st, self.socket_server_close(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallTLSAcceptClient => { #[cfg(feature = "tls")] - try_or_throw!(self.machine_st, self.tls_accept_client()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.tls_accept_client(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteTLSAcceptClient => { #[cfg(feature = "tls")] - try_or_throw!(self.machine_st, self.tls_accept_client()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.tls_accept_client(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallTLSClientConnect => { #[cfg(feature = "tls")] - try_or_throw!(self.machine_st, self.tls_client_connect()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.tls_client_connect(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteTLSClientConnect => { #[cfg(feature = "tls")] - try_or_throw!(self.machine_st, self.tls_client_connect()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.tls_client_connect(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSucceed => { self.machine_st.p += 1; @@ -4653,27 +5040,27 @@ impl Machine { } &Instruction::CallTermAttributedVariables => { self.term_attributed_variables(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteTermAttributedVariables => { self.term_attributed_variables(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallTermVariables => { self.term_variables(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteTermVariables => { self.term_variables(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallTermVariablesUnderMaxDepth => { self.term_variables_under_max_depth(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteTermVariablesUnderMaxDepth => { self.term_variables_under_max_depth(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallTruncateLiftedHeapTo => { self.truncate_lifted_heap_to(); @@ -4685,11 +5072,11 @@ impl Machine { } &Instruction::CallUnifyWithOccursCheck => { self.unify_with_occurs_check(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteUnifyWithOccursCheck => { self.unify_with_occurs_check(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallUnwindEnvironments => { if !self.unwind_environments() { @@ -4706,12 +5093,12 @@ impl Machine { self.machine_st.backtrack(); } &Instruction::CallWAMInstructions => { - try_or_throw!(self.machine_st, self.wam_instructions()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.wam_instructions(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteWAMInstructions => { - try_or_throw!(self.machine_st, self.wam_instructions()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.wam_instructions(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInlinedInstructions => { self.inlined_instructions(); @@ -4722,256 +5109,256 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } &Instruction::CallWriteTerm => { - try_or_throw!(self.machine_st, self.write_term()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.write_term(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteWriteTerm => { - try_or_throw!(self.machine_st, self.write_term()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.write_term(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallWriteTermToChars => { - try_or_throw!(self.machine_st, self.write_term_to_chars()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.write_term_to_chars(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteWriteTermToChars => { - try_or_throw!(self.machine_st, self.write_term_to_chars()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.write_term_to_chars(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallScryerPrologVersion => { self.scryer_prolog_version(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteScryerPrologVersion => { self.scryer_prolog_version(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCryptoRandomByte => { self.crypto_random_byte(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCryptoRandomByte => { self.crypto_random_byte(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCryptoDataHash => { self.crypto_data_hash(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCryptoDataHash => { self.crypto_data_hash(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCryptoHMAC => { self.crypto_hmac(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCryptoHMAC => { self.crypto_hmac(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCryptoDataHKDF => { self.crypto_data_hkdf(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCryptoDataHKDF => { self.crypto_data_hkdf(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCryptoPasswordHash => { self.crypto_password_hash(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCryptoPasswordHash => { self.crypto_password_hash(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } #[cfg(feature = "crypto-full")] &Instruction::CallCryptoDataEncrypt => { self.crypto_data_encrypt(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } #[cfg(feature = "crypto-full")] &Instruction::ExecuteCryptoDataEncrypt => { self.crypto_data_encrypt(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } #[cfg(feature = "crypto-full")] &Instruction::CallCryptoDataDecrypt => { self.crypto_data_decrypt(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } #[cfg(feature = "crypto-full")] &Instruction::ExecuteCryptoDataDecrypt => { self.crypto_data_decrypt(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallBeta => { self.beta(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteBeta => { self.beta(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallBetaI => { self.betai(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteBetaI => { self.betai(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInvBetaI => { self.invbetai(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteInvBetaI => { self.invbetai(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGamma => { self.gamma(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGamma => { self.gamma(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLnGamma => { self.ln_gamma(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLnGamma => { self.ln_gamma(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGammP => { self.gammp(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGammP => { self.gammp(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInvGammP => { self.invgammp(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteInvGammP => { self.invgammp(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGammQ => { self.gammq(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGammQ => { self.gammq(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallErf => { self.erf(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteErf => { self.erf(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallErfc => { self.erfc(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteErfc => { self.erfc(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInvErf => { self.inverf(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteInvErf => { self.inverf(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInvErfc => { self.inverfc(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteInvErfc => { self.inverfc(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCryptoCurveScalarMult => { self.crypto_curve_scalar_mult(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCryptoCurveScalarMult => { self.crypto_curve_scalar_mult(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallEd25519SignRaw => { self.ed25519_sign_raw(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteEd25519SignRaw => { self.ed25519_sign_raw(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallEd25519VerifyRaw => { self.ed25519_verify_raw(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteEd25519VerifyRaw => { self.ed25519_verify_raw(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallEd25519SeedToPublicKey => { self.ed25519_seed_to_public_key(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteEd25519SeedToPublicKey => { self.ed25519_seed_to_public_key(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCurve25519ScalarMult => { self.curve25519_scalar_mult(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCurve25519ScalarMult => { self.curve25519_scalar_mult(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallFirstNonOctet => { self.first_non_octet(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteFirstNonOctet => { self.first_non_octet(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLoadHTML => { - backtrack_on_resource_error!(self.machine_st, self.load_html()); - step_or_fail!(self, self.machine_st.p += 1); + backtrack_on_resource_error!(self.machine_st, self.load_html(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLoadHTML => { - backtrack_on_resource_error!(self.machine_st, self.load_html()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + backtrack_on_resource_error!(self.machine_st, self.load_html(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLoadXML => { - backtrack_on_resource_error!(self.machine_st, self.load_xml()); - step_or_fail!(self, self.machine_st.p += 1); + backtrack_on_resource_error!(self.machine_st, self.load_xml(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLoadXML => { - backtrack_on_resource_error!(self.machine_st, self.load_xml()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + backtrack_on_resource_error!(self.machine_st, self.load_xml(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallGetEnv => { self.get_env(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetEnv => { self.get_env(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSetEnv => { self.set_env(); @@ -4991,83 +5378,83 @@ impl Machine { } &Instruction::CallShell => { self.shell(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteShell => { self.shell(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallProcessCreate => { - try_or_throw!(self.machine_st, self.process_create()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.process_create(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteProcessCreate => { - try_or_throw!(self.machine_st, self.process_create()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.process_create(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallProcessId => { - try_or_throw!(self.machine_st, self.process_id()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.process_id(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteProcessId => { - try_or_throw!(self.machine_st, self.process_id()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.process_id(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallProcessWait => { - try_or_throw!(self.machine_st, self.process_wait()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.process_wait(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteProcessWait => { - try_or_throw!(self.machine_st, self.process_wait()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.process_wait(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallProcessKill => { - try_or_throw!(self.machine_st, self.process_kill()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.process_kill(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteProcessKill => { - try_or_throw!(self.machine_st, self.process_kill()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.process_kill(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallProcessRelease => { - try_or_throw!(self.machine_st, self.process_release()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.process_release(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteProcessRelease => { - try_or_throw!(self.machine_st, self.process_release()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.process_release(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPid => { self.pid(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePid => { self.pid(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCharsBase64 => { - try_or_throw!(self.machine_st, self.chars_base64()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.chars_base64(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCharsBase64 => { - try_or_throw!(self.machine_st, self.chars_base64()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.chars_base64(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDevourWhitespace => { - try_or_throw!(self.machine_st, self.devour_whitespace()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.devour_whitespace(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteDevourWhitespace => { - try_or_throw!(self.machine_st, self.devour_whitespace()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.devour_whitespace(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallIsSTOEnabled => { self.is_sto_enabled(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteIsSTOEnabled => { self.is_sto_enabled(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallSetSTOAsUnify => { self.set_sto_as_unify(); @@ -5095,11 +5482,11 @@ impl Machine { } &Instruction::CallHomeDirectory => { self.home_directory(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteHomeDirectory => { self.home_directory(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDebugHook => { self.debug_hook(); @@ -5111,139 +5498,155 @@ impl Machine { } &Instruction::CallPopCount => { self.pop_count(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePopCount => { self.pop_count(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallAddDiscontiguousPredicate => { - try_or_throw!(self.machine_st, self.add_discontiguous_predicate()); + try_or_throw!( + self.machine_st, + self.add_discontiguous_predicate(), + continue + ); self.machine_st.p += 1; } &Instruction::ExecuteAddDiscontiguousPredicate => { - try_or_throw!(self.machine_st, self.add_discontiguous_predicate()); + try_or_throw!( + self.machine_st, + self.add_discontiguous_predicate(), + continue + ); self.machine_st.p = self.machine_st.cp; } &Instruction::CallAddDynamicPredicate => { - try_or_throw!(self.machine_st, self.add_dynamic_predicate()); + try_or_throw!(self.machine_st, self.add_dynamic_predicate(), continue); self.machine_st.p += 1; } &Instruction::ExecuteAddDynamicPredicate => { - try_or_throw!(self.machine_st, self.add_dynamic_predicate()); + try_or_throw!(self.machine_st, self.add_dynamic_predicate(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallAddMultifilePredicate => { - try_or_throw!(self.machine_st, self.add_multifile_predicate()); + try_or_throw!(self.machine_st, self.add_multifile_predicate(), continue); self.machine_st.p += 1; } &Instruction::ExecuteAddMultifilePredicate => { - try_or_throw!(self.machine_st, self.add_multifile_predicate()); + try_or_throw!(self.machine_st, self.add_multifile_predicate(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallAddGoalExpansionClause => { - try_or_throw!(self.machine_st, self.add_goal_expansion_clause()); + try_or_throw!(self.machine_st, self.add_goal_expansion_clause(), continue); self.machine_st.p += 1; } &Instruction::ExecuteAddGoalExpansionClause => { - try_or_throw!(self.machine_st, self.add_goal_expansion_clause()); + try_or_throw!(self.machine_st, self.add_goal_expansion_clause(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallAddTermExpansionClause => { - try_or_throw!(self.machine_st, self.add_term_expansion_clause()); + try_or_throw!(self.machine_st, self.add_term_expansion_clause(), continue); self.machine_st.p += 1; } &Instruction::ExecuteAddTermExpansionClause => { - try_or_throw!(self.machine_st, self.add_term_expansion_clause()); + try_or_throw!(self.machine_st, self.add_term_expansion_clause(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallAddInSituFilenameModule => { - try_or_throw!(self.machine_st, self.add_in_situ_filename_module()); + try_or_throw!( + self.machine_st, + self.add_in_situ_filename_module(), + continue + ); self.machine_st.p += 1; } &Instruction::ExecuteAddInSituFilenameModule => { - try_or_throw!(self.machine_st, self.add_in_situ_filename_module()); + try_or_throw!( + self.machine_st, + self.add_in_situ_filename_module(), + continue + ); self.machine_st.p = self.machine_st.cp; } &Instruction::CallClauseToEvacuable => { - try_or_throw!(self.machine_st, self.clause_to_evacuable()); + try_or_throw!(self.machine_st, self.clause_to_evacuable(), continue); self.machine_st.p += 1; } &Instruction::ExecuteClauseToEvacuable => { - try_or_throw!(self.machine_st, self.clause_to_evacuable()); + try_or_throw!(self.machine_st, self.clause_to_evacuable(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallScopedClauseToEvacuable => { - try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable()); + try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable(), continue); self.machine_st.p += 1; } &Instruction::ExecuteScopedClauseToEvacuable => { - try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable()); + try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallConcludeLoad => { - try_or_throw!(self.machine_st, self.conclude_load()); + try_or_throw!(self.machine_st, self.conclude_load(), continue); self.machine_st.p += 1; } &Instruction::ExecuteConcludeLoad => { - try_or_throw!(self.machine_st, self.conclude_load()); + try_or_throw!(self.machine_st, self.conclude_load(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallDeclareModule => { - try_or_throw!(self.machine_st, self.declare_module()); + try_or_throw!(self.machine_st, self.declare_module(), continue); self.machine_st.p += 1; } &Instruction::ExecuteDeclareModule => { - try_or_throw!(self.machine_st, self.declare_module()); + try_or_throw!(self.machine_st, self.declare_module(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallLoadCompiledLibrary => { - try_or_throw!(self.machine_st, self.load_compiled_library()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.load_compiled_library(), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLoadCompiledLibrary => { - try_or_throw!(self.machine_st, self.load_compiled_library()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.load_compiled_library(), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLoadContextSource => { self.load_context_source(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLoadContextSource => { self.load_context_source(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLoadContextFile => { self.load_context_file(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLoadContextFile => { self.load_context_file(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLoadContextDirectory => { self.load_context_directory(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLoadContextDirectory => { self.load_context_directory(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLoadContextModule => { self.load_context_module(self.deref_register(1)); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLoadContextModule => { self.load_context_module(self.deref_register(1)); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallLoadContextStream => { self.load_context_stream(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteLoadContextStream => { self.load_context_stream(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPopLoadContext => { self.pop_load_context(); @@ -5262,27 +5665,27 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } &Instruction::CallPushLoadContext => { - try_or_throw!(self.machine_st, self.push_load_context()); + try_or_throw!(self.machine_st, self.push_load_context(), continue); self.machine_st.p += 1; } &Instruction::ExecutePushLoadContext => { - try_or_throw!(self.machine_st, self.push_load_context()); + try_or_throw!(self.machine_st, self.push_load_context(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallPushLoadStatePayload => { self.push_load_state_payload(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePushLoadStatePayload => { self.push_load_state_payload(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallUseModule => { - try_or_throw!(self.machine_st, self.use_module()); + try_or_throw!(self.machine_st, self.use_module(), continue); self.machine_st.p += 1; } &Instruction::ExecuteUseModule => { - try_or_throw!(self.machine_st, self.use_module()); + try_or_throw!(self.machine_st, self.use_module(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallBuiltInProperty => { @@ -5292,7 +5695,7 @@ impl Machine { ); self.machine_st.fail = !self.indices.builtin_property(key); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteBuiltInProperty => { let key = self.machine_st.read_predicate_key( @@ -5301,161 +5704,193 @@ impl Machine { ); self.machine_st.fail = !self.indices.builtin_property(key); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallMetaPredicateProperty => { self.meta_predicate_property(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteMetaPredicateProperty => { self.meta_predicate_property(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallMultifileProperty => { self.multifile_property(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteMultifileProperty => { self.multifile_property(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDiscontiguousProperty => { self.discontiguous_property(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteDiscontiguousProperty => { self.discontiguous_property(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDynamicProperty => { self.dynamic_property(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteDynamicProperty => { self.dynamic_property(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallAbolishClause => { - try_or_throw!(self.machine_st, self.abolish_clause()); + try_or_throw!(self.machine_st, self.abolish_clause(), continue); self.machine_st.p += 1; } &Instruction::ExecuteAbolishClause => { - try_or_throw!(self.machine_st, self.abolish_clause()); + try_or_throw!(self.machine_st, self.abolish_clause(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallAsserta => { try_or_throw!( self.machine_st, - self.compile_assert(AppendOrPrepend::Prepend) + self.compile_assert(AppendOrPrepend::Prepend), + continue ); self.machine_st.p += 1; } &Instruction::ExecuteAsserta => { try_or_throw!( self.machine_st, - self.compile_assert(AppendOrPrepend::Prepend) + self.compile_assert(AppendOrPrepend::Prepend), + continue ); self.machine_st.p = self.machine_st.cp; } &Instruction::CallAssertz => { try_or_throw!( self.machine_st, - self.compile_assert(AppendOrPrepend::Append) + self.compile_assert(AppendOrPrepend::Append), + continue ); self.machine_st.p += 1; } &Instruction::ExecuteAssertz => { try_or_throw!( self.machine_st, - self.compile_assert(AppendOrPrepend::Append) + self.compile_assert(AppendOrPrepend::Append), + continue ); self.machine_st.p = self.machine_st.cp; } &Instruction::CallRetract => { - try_or_throw!(self.machine_st, self.retract_clause()); + try_or_throw!(self.machine_st, self.retract_clause(), continue); self.machine_st.p += 1; } &Instruction::ExecuteRetract => { - try_or_throw!(self.machine_st, self.retract_clause()); + try_or_throw!(self.machine_st, self.retract_clause(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallIsConsistentWithTermQueue => { - try_or_throw!(self.machine_st, self.is_consistent_with_term_queue()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!( + self.machine_st, + self.is_consistent_with_term_queue(), + continue + ); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteIsConsistentWithTermQueue => { - try_or_throw!(self.machine_st, self.is_consistent_with_term_queue()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!( + self.machine_st, + self.is_consistent_with_term_queue(), + continue + ); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::CallFlushTermQueue => { - try_or_throw!(self.machine_st, self.flush_term_queue()); + try_or_throw!(self.machine_st, self.flush_term_queue(), continue); self.machine_st.p += 1; } &Instruction::ExecuteFlushTermQueue => { - try_or_throw!(self.machine_st, self.flush_term_queue()); + try_or_throw!(self.machine_st, self.flush_term_queue(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallRemoveModuleExports => { - try_or_throw!(self.machine_st, self.remove_module_exports()); + try_or_throw!(self.machine_st, self.remove_module_exports(), continue); self.machine_st.p += 1; } &Instruction::ExecuteRemoveModuleExports => { - try_or_throw!(self.machine_st, self.remove_module_exports()); + try_or_throw!(self.machine_st, self.remove_module_exports(), continue); self.machine_st.p = self.machine_st.cp; } &Instruction::CallAddNonCountedBacktracking => { - try_or_throw!(self.machine_st, self.add_non_counted_backtracking()); + try_or_throw!( + self.machine_st, + self.add_non_counted_backtracking(), + continue + ); self.machine_st.p += 1; } &Instruction::ExecuteAddNonCountedBacktracking => { - try_or_throw!(self.machine_st, self.add_non_counted_backtracking()); + try_or_throw!( + self.machine_st, + self.add_non_counted_backtracking(), + continue + ); self.machine_st.p = self.machine_st.cp; } &Instruction::CallPredicateDefined => { self.machine_st.fail = !self.predicate_defined(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePredicateDefined => { self.machine_st.fail = !self.predicate_defined(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallStripModule => { self.strip_module(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteStripModule => { self.strip_module(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPrepareCallClause(arity) => { - try_or_throw!(self.machine_st, self.prepare_call_clause(arity)); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!(self.machine_st, self.prepare_call_clause(arity), continue); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePrepareCallClause(arity) => { - try_or_throw!(self.machine_st, self.prepare_call_clause(arity)); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!(self.machine_st, self.prepare_call_clause(arity), continue); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallCompileInlineOrExpandedGoal => { - try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal()); - step_or_fail!(self, self.machine_st.p += 1); + try_or_throw!( + self.machine_st, + self.compile_inline_or_expanded_goal(), + continue + ); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteCompileInlineOrExpandedGoal => { - try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal()); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + try_or_throw!( + self.machine_st, + self.compile_inline_or_expanded_goal(), + continue + ); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallIsExpandedOrInlined => { self.machine_st.fail = !self.is_expanded_or_inlined(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteIsExpandedOrInlined => { self.machine_st.fail = !self.is_expanded_or_inlined(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallFastCallN(arity) => { let call_at_index = |wam: &mut Machine, name, arity, ptr| wam.try_call(name, arity, ptr); - try_or_throw!(self.machine_st, self.fast_call(arity, call_at_index)); + try_or_throw!( + self.machine_st, + self.fast_call(arity, call_at_index), + continue + ); if self.machine_st.fail { self.machine_st.backtrack(); @@ -5465,7 +5900,11 @@ impl Machine { let call_at_index = |wam: &mut Machine, name, arity, ptr| wam.try_execute(name, arity, ptr); - try_or_throw!(self.machine_st, self.fast_call(arity, call_at_index)); + try_or_throw!( + self.machine_st, + self.fast_call(arity, call_at_index), + continue + ); if self.machine_st.fail { self.machine_st.backtrack(); @@ -5484,14 +5923,15 @@ impl Machine { let str_cell = backtrack_on_resource_error!( &mut self.machine_st, - writer(&mut self.machine_st.heap) + writer(&mut self.machine_st.heap), + continue ); let r = r.as_var().unwrap(); self.machine_st.bind(r, str_cell); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetClauseP => { let module_name = cell_as_atom!(self.deref_register(3)); @@ -5506,14 +5946,13 @@ impl Machine { let str_cell = backtrack_on_resource_error!( &mut self.machine_st, - writer(&mut self.machine_st.heap) + writer(&mut self.machine_st.heap), + continue ); let r = r.as_var().unwrap(); - self.machine_st.bind(r, str_cell); - - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInvokeClauseAtP => { let key_cell = self.machine_st.registers[1]; @@ -5609,27 +6048,27 @@ impl Machine { } &Instruction::CallGetFromAttributedVarList => { self.get_from_attributed_variable_list(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetFromAttributedVarList => { self.get_from_attributed_variable_list(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallPutToAttributedVarList => { self.put_to_attributed_variable_list(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecutePutToAttributedVarList => { self.put_to_attributed_variable_list(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDeleteFromAttributedVarList => { self.delete_from_attributed_variable_list(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteDeleteFromAttributedVarList => { self.delete_from_attributed_variable_list(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallDeleteAllAttributesFromVar => { self.delete_all_attributes_from_var(); @@ -5641,7 +6080,7 @@ impl Machine { } &Instruction::CallUnattributedVar => { self.machine_st.unattributed_var(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteUnattributedVar => { self.machine_st.unattributed_var(); @@ -5649,56 +6088,24 @@ impl Machine { } &Instruction::CallGetDBRefs => { self.get_db_refs(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteGetDBRefs => { self.get_db_refs(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } &Instruction::CallInferenceLimitExceeded => { self.inference_limit_exceeded(); - step_or_fail!(self, self.machine_st.p += 1); + step_or_fail!(self.machine_st, self.machine_st.p += 1); } &Instruction::ExecuteInferenceLimitExceeded => { self.inference_limit_exceeded(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + step_or_fail!(self.machine_st, self.machine_st.p = self.machine_st.cp); } } } - let interrupted = INTERRUPT.load(std::sync::atomic::Ordering::Relaxed); - - match INTERRUPT.compare_exchange( - interrupted, - false, - std::sync::atomic::Ordering::Relaxed, - std::sync::atomic::Ordering::Relaxed, - ) { - Ok(interruption) => { - if interruption { - self.machine_st.throw_interrupt_exception(); - self.machine_st.backtrack(); - - // We have extracted controll over the Tokio runtime to the calling context for enabling library use case - // (see https://github.com/mthom/scryer-prolog/pull/1880) - // So we only have access to a runtime handle in here and can't shut it down. - // Since I'm not aware of the consequences of deactivating this new code which came in while PR 1880 - // was not merged, I'm only deactivating it for now. - - //#[cfg(not(target_arch = "wasm32"))] - //let runtime = tokio::runtime::Runtime::new().unwrap(); - //#[cfg(target_arch = "wasm32")] - //let runtime = tokio::runtime::Builder::new_current_thread() - // .enable_all() - // .build() - // .unwrap(); - - //let old_runtime = tokio::runtime::Handle::current(); - //old_runtime.shutdown_background(); - } - } - Err(_) => unreachable!(), - } + self.machine_st.check_for_interrupt(); } std::process::ExitCode::SUCCESS diff --git a/src/machine/mod.rs b/src/machine/mod.rs index db6dae7e..da41f166 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -141,9 +141,8 @@ mod libraries { } pub static BREAK_FROM_DISPATCH_LOOP_LOC: usize = 0; -pub static INSTALL_VERIFY_ATTR_INTERRUPT: usize = 1; -pub static VERIFY_ATTR_INTERRUPT_LOC: usize = 2; -pub static LIB_QUERY_SUCCESS: usize = 3; +pub static VERIFY_ATTR_INTERRUPT_LOC: usize = 1; +pub static LIB_QUERY_SUCCESS: usize = 2; pub struct MachinePreludeView<'a> { pub indices: &'a mut IndexStore, @@ -414,12 +413,11 @@ impl Machine { } pub(crate) fn add_impls_to_indices(&mut self) { - let impls_offset = self.code.len() + 4; + let impls_offset = self.code.len() + 3; self.code.extend(vec![ Instruction::BreakFromDispatchLoop, - Instruction::InstallVerifyAttr, - Instruction::VerifyAttrInterrupt(0), + Instruction::RunVerifyAttr, Instruction::BreakFromDispatchLoop, // the location of LIB_QUERY_SUCCESS Instruction::ExecuteTermGreaterThan, Instruction::ExecuteTermLessThan, diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 5fc4088b..4294b68c 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -24,7 +24,7 @@ use crate::machine::machine_state::*; use crate::machine::partial_string::*; use crate::machine::stack::*; use crate::machine::streams::*; -use crate::machine::{get_structure_index, Machine, VERIFY_ATTR_INTERRUPT_LOC}; +use crate::machine::{get_structure_index, Machine}; use crate::parser::ast::*; use crate::parser::char_reader::*; use crate::parser::dashu::Integer; @@ -6255,6 +6255,7 @@ impl Machine { self.machine_st.heap[var.get_value() as usize] = value; } + /* #[inline(always)] pub(super) fn restore_instr_at_verify_attr_interrupt(&mut self) { match &self.code[VERIFY_ATTR_INTERRUPT_LOC] { @@ -6269,10 +6270,11 @@ impl Machine { } } } + */ #[inline(always)] pub(crate) fn reset_attr_var_state(&mut self, queue_len: usize) { - self.restore_instr_at_verify_attr_interrupt(); + // self.restore_instr_at_verify_attr_interrupt(); self.machine_st.attr_var_init.reset(queue_len); } @@ -6303,7 +6305,7 @@ impl Machine { #[inline(always)] pub(crate) fn return_from_verify_attr(&mut self) { - self.restore_instr_at_verify_attr_interrupt(); + // self.restore_instr_at_verify_attr_interrupt(); let e = self.machine_st.e; let frame_len = self.machine_st.stack.index_and_frame(e).prelude.num_cells;