From: Mark Date: Thu, 29 Jun 2023 18:14:06 +0000 (-0600) Subject: introduce CutPoint heap tag so that they can be offset by call_continuation/1 X-Git-Tag: v0.9.2~105 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=c36bd4dc07630d511624cacb0fd6a59c59f1d36d;p=scryer-prolog.git introduce CutPoint heap tag so that they can be offset by call_continuation/1 --- diff --git a/src/arithmetic.rs b/src/arithmetic.rs index 0fbd91d5..515dba4b 100644 --- a/src/arithmetic.rs +++ b/src/arithmetic.rs @@ -685,7 +685,7 @@ impl TryFrom for Number { (HeapCellValueTag::F64, n) => { Ok(Number::Float(*n)) } - (HeapCellValueTag::Fixnum, n) => { + (HeapCellValueTag::Fixnum | HeapCellValueTag::CutPoint, n) => { Ok(Number::Fixnum(n)) } _ => { diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index 686ec71b..8029bb70 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -1149,17 +1149,17 @@ impl Machine { &Instruction::GetLevel(r) => { let b0 = self.machine_st.b0; - self.machine_st[r] = fixnum_as_cell!(Fixnum::build_with(b0 as i64)); + self.machine_st[r] = fixnum_as_cell!(Fixnum::as_cutpoint(b0 as i64)); 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!(Fixnum::build_with(prev_b as i64)); + self.machine_st[r] = fixnum_as_cell!(Fixnum::as_cutpoint(prev_b as i64)); self.machine_st.p += 1; } &Instruction::GetCutPoint(r) => { - self.machine_st[r] = fixnum_as_cell!(Fixnum::build_with(self.machine_st.b as i64)); + self.machine_st[r] = fixnum_as_cell!(Fixnum::as_cutpoint(self.machine_st.b as i64)); self.machine_st.p += 1; } &Instruction::Cut(r) => { diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index de034374..29702c4a 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -821,7 +821,7 @@ impl MachineState { let b = self.b; read_heap_cell!(value, - (HeapCellValueTag::Fixnum, b0) => { + (HeapCellValueTag::CutPoint, b0) => { let b0 = b0.get_num() as usize; if b > b0 { diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 7dbaf43b..6a676ae9 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -981,7 +981,7 @@ impl MachineState { self.p = cp + 1; - // adjust cut point to occur after call_continuation. + /* if num_cells > 0 { if let HeapCellValueTag::Fixnum = self.heap[s + 2].get_tag() { and_frame[1] = fixnum_as_cell!(Fixnum::build_with(self.b as i64)); @@ -989,9 +989,15 @@ impl MachineState { and_frame[1] = self.heap[s + 2]; } } + */ - for index in s + 3..s + 2 + num_cells { - and_frame[index - (s + 1)] = self.heap[index]; + for index in s + 2..s + 2 + num_cells { + if let HeapCellValueTag::CutPoint = self.heap[index].get_tag() { + // adjust cut point to occur after call_continuation. + and_frame[index - (s + 1)] = fixnum_as_cell!(Fixnum::as_cutpoint(self.b as i64)); + } else { + and_frame[index - (s + 1)] = self.heap[index]; + } } self.e = e; @@ -5557,13 +5563,13 @@ impl Machine { #[inline(always)] pub(crate) fn get_b_value(&mut self) { - let n = Fixnum::build_with(i64::try_from(self.machine_st.b).unwrap()); + let n = Fixnum::as_cutpoint(i64::try_from(self.machine_st.b).unwrap()); self.machine_st.unify_fixnum(n, self.machine_st.registers[1]); } #[inline(always)] pub(crate) fn get_cut_point(&mut self) { - let n = Fixnum::build_with(i64::try_from(self.machine_st.b0).unwrap()); + let n = Fixnum::as_cutpoint(i64::try_from(self.machine_st.b0).unwrap()); self.machine_st.unify_fixnum(n, self.machine_st.registers[1]); } diff --git a/src/macros.rs b/src/macros.rs index c0c929c8..8a3ede55 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -15,7 +15,7 @@ macro_rules! char_as_cell { macro_rules! fixnum_as_cell { ($n: expr) => { - HeapCellValue::from_bytes($n.into_bytes()) //HeapCellValueTag::Fixnum, $n.get_num() as u64) + HeapCellValue::from_bytes($n.into_bytes()) }; } @@ -378,6 +378,21 @@ macro_rules! read_heap_cell_pat_body { #[allow(unused_braces)] $code }); + ($cell:ident, CutPoint, $value:ident, $code:expr) => ({ + let $value = Fixnum::from_bytes($cell.into_bytes()); + #[allow(unused_braces)] + $code + }); + ($cell:ident, Fixnum | CutPoint, $value:ident, $code:expr) => ({ + let $value = Fixnum::from_bytes($cell.into_bytes()); + #[allow(unused_braces)] + $code + }); + ($cell:ident, CutPoint | Fixnum, $value:ident, $code:expr) => ({ + let $value = Fixnum::from_bytes($cell.into_bytes()); + #[allow(unused_braces)] + $code + }); ($cell:ident, Char, $value:ident, $code:expr) => ({ let $value = unsafe { char::from_u32_unchecked($cell.get_value() as u32) }; #[allow(unused_braces)] diff --git a/src/parser/ast.rs b/src/parser/ast.rs index 283a9dc0..31f1a702 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -493,6 +493,15 @@ impl Fixnum { .with_f(false) } + #[inline] + pub fn as_cutpoint(num: i64) -> Self { + Fixnum::new() + .with_num(u64::from_ne_bytes(num.to_ne_bytes()) & ((1 << 56) - 1)) + .with_tag(HeapCellValueTag::CutPoint as u8) + .with_m(false) + .with_f(false) + } + #[inline] pub fn build_with_checked(num: i64) -> Result { const UPPER_BOUND: i64 = (1 << 55) - 1; diff --git a/src/types.rs b/src/types.rs index a8b66b35..12add4ef 100644 --- a/src/types.rs +++ b/src/types.rs @@ -30,6 +30,7 @@ pub enum HeapCellValueTag { Atom = 0b010111, PStr = 0b011001, CStr = 0b011011, + CutPoint = 0b011111, } #[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] @@ -50,13 +51,15 @@ pub enum HeapCellValueView { Atom = 0b010111, PStr = 0b011001, CStr = 0b011011, + CutPoint = 0b011111, // trail elements. - TrailedHeapVar = 0b011101, - TrailedStackVar = 0b011111, + TrailedHeapVar = 0b101111, + TrailedStackVar = 0b101011, + TrailedAttrVar = 0b100001, TrailedAttrVarListLink = 0b100011, TrailedAttachedValue = 0b100101, TrailedBlackboardEntry = 0b100111, - TrailedBlackboardOffset = 0b101001, + TrailedBlackboardOffset = 0b110011, } #[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] @@ -189,13 +192,13 @@ pub enum TrailRef { #[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] #[bits = 6] pub(crate) enum TrailEntryTag { - TrailedHeapVar = 0b011110, - TrailedStackVar = 0b011111, - TrailedAttrVar = 0b101110, - TrailedAttrVarListLink = 0b100011, - TrailedAttachedValue = 0b101010, - TrailedBlackboardEntry = 0b100110, - TrailedBlackboardOffset = 0b100111, + TrailedHeapVar = 0b101111, + TrailedStackVar = 0b101011, + TrailedAttrVar = 0b100001, + TrailedAttrVarListLink = 0b100011, + TrailedAttachedValue = 0b100101, + TrailedBlackboardEntry = 0b100111, + TrailedBlackboardOffset = 0b110011, } #[bitfield]