Merge pull request #1972 from rujialiu/32-bit-support
32-bit system support #615 #1509 (WIP)
This commit is contained in:
21
src/arena.rs
21
src/arena.rs
@@ -307,12 +307,16 @@ pub trait ArenaAllocated: Sized {
|
|||||||
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated;
|
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated;
|
||||||
|
|
||||||
fn header_offset_from_payload() -> usize {
|
fn header_offset_from_payload() -> usize {
|
||||||
mem::size_of::<*const ArenaHeader>()
|
mem::size_of::<ArenaHeader>()
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn alloc(arena: &mut Arena, value: Self) -> Self::PtrToAllocated {
|
unsafe fn alloc(arena: &mut Arena, value: Self) -> Self::PtrToAllocated {
|
||||||
let size = value.size() + mem::size_of::<AllocSlab>();
|
let size = value.size() + mem::size_of::<AllocSlab>();
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width="32")]
|
||||||
|
let align = mem::align_of::<AllocSlab>() * 2;
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width="64")]
|
||||||
let align = mem::align_of::<AllocSlab>();
|
let align = mem::align_of::<AllocSlab>();
|
||||||
let layout = alloc::Layout::from_size_align_unchecked(size, align);
|
let layout = alloc::Layout::from_size_align_unchecked(size, align);
|
||||||
|
|
||||||
@@ -656,9 +660,12 @@ impl ArenaAllocated for IndexPtr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
struct AllocSlab {
|
struct AllocSlab {
|
||||||
next: *mut AllocSlab,
|
next: *mut AllocSlab,
|
||||||
|
#[cfg(target_pointer_width="32")]
|
||||||
|
_padding: u32,
|
||||||
header: ArenaHeader,
|
header: ArenaHeader,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,6 +834,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn heap_cell_value_const_cast() {
|
fn heap_cell_value_const_cast() {
|
||||||
let mut wam = MockWAM::new();
|
let mut wam = MockWAM::new();
|
||||||
|
#[cfg(target_pointer_width="32")]
|
||||||
|
let const_value = HeapCellValue::from(ConsPtr::build_with(
|
||||||
|
0x0000_0431 as *const _,
|
||||||
|
ConsPtrMaskTag::Cons,
|
||||||
|
));
|
||||||
|
#[cfg(target_pointer_width="64")]
|
||||||
let const_value = HeapCellValue::from(ConsPtr::build_with(
|
let const_value = HeapCellValue::from(ConsPtr::build_with(
|
||||||
0x0000_5555_ff00_0431 as *const _,
|
0x0000_5555_ff00_0431 as *const _,
|
||||||
ConsPtrMaskTag::Cons,
|
ConsPtrMaskTag::Cons,
|
||||||
@@ -834,7 +847,7 @@ mod tests {
|
|||||||
|
|
||||||
match const_value.to_untyped_arena_ptr() {
|
match const_value.to_untyped_arena_ptr() {
|
||||||
Some(arena_ptr) => {
|
Some(arena_ptr) => {
|
||||||
assert_eq!(arena_ptr.into_bytes(), const_value.into_bytes());
|
assert_eq!(arena_ptr.into_bytes(), const_value.to_untyped_arena_ptr_bytes());
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
assert!(false);
|
assert!(false);
|
||||||
@@ -847,7 +860,7 @@ mod tests {
|
|||||||
|
|
||||||
match stream_cell.to_untyped_arena_ptr() {
|
match stream_cell.to_untyped_arena_ptr() {
|
||||||
Some(arena_ptr) => {
|
Some(arena_ptr) => {
|
||||||
assert_eq!(arena_ptr.into_bytes(), stream_cell.into_bytes());
|
assert_eq!(arena_ptr.into_bytes(), stream_cell.to_untyped_arena_ptr_bytes());
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
assert!(false);
|
assert!(false);
|
||||||
@@ -1101,7 +1114,7 @@ mod tests {
|
|||||||
|
|
||||||
read_heap_cell!(cell,
|
read_heap_cell!(cell,
|
||||||
(HeapCellValueTag::Atom, (el, _arity)) => {
|
(HeapCellValueTag::Atom, (el, _arity)) => {
|
||||||
assert_eq!(el.flat_index() as usize, empty_list_as_cell!().get_value());
|
assert_eq!(el.flat_index(), empty_list_as_cell!().get_value());
|
||||||
assert_eq!(el.as_str(), "[]");
|
assert_eq!(el.as_str(), "[]");
|
||||||
}
|
}
|
||||||
_ => { unreachable!() }
|
_ => { unreachable!() }
|
||||||
|
|||||||
@@ -169,8 +169,8 @@ impl Atom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn from(index: usize) -> Self {
|
pub fn from(index: u64) -> Self {
|
||||||
Self { index: index as u64 }
|
Self { index }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -386,7 +386,7 @@ impl AtomCell {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_name(self) -> Atom {
|
pub fn get_name(self) -> Atom {
|
||||||
Atom::from(self.get_index() << 3)
|
Atom::from((self.get_index() as u64) << 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -396,6 +396,6 @@ impl AtomCell {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_name_and_arity(self) -> (Atom, usize) {
|
pub fn get_name_and_arity(self) -> (Atom, usize) {
|
||||||
(Atom::from(self.get_index() << 3), self.get_arity())
|
(Atom::from((self.get_index() as u64) << 3), self.get_arity())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,8 +187,8 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
fn copy_attr_var_list(&mut self, mut list_addr: HeapCellValue) {
|
fn copy_attr_var_list(&mut self, mut list_addr: HeapCellValue) {
|
||||||
while let HeapCellValueTag::Lis = list_addr.get_tag() {
|
while let HeapCellValueTag::Lis = list_addr.get_tag() {
|
||||||
let threshold = self.target.threshold();
|
let threshold = self.target.threshold();
|
||||||
let heap_loc = list_addr.get_value();
|
let heap_loc = list_addr.get_value() as usize;
|
||||||
let str_loc = self.target[heap_loc].get_value();
|
let str_loc = self.target[heap_loc].get_value() as usize;
|
||||||
|
|
||||||
self.target.push(heap_loc_as_cell!(threshold+2));
|
self.target.push(heap_loc_as_cell!(threshold+2));
|
||||||
self.target.push(heap_loc_as_cell!(threshold+1));
|
self.target.push(heap_loc_as_cell!(threshold+1));
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ pub(crate) struct StacklessPreOrderHeapIter<'a, UMP: UnmarkPolicy> {
|
|||||||
orig_heap_len: usize,
|
orig_heap_len: usize,
|
||||||
start: usize,
|
start: usize,
|
||||||
current: usize,
|
current: usize,
|
||||||
next: usize,
|
next: u64,
|
||||||
_marker: PhantomData<UMP>,
|
_marker: PhantomData<UMP>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,14 +153,14 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn forward_var(&mut self) -> Option<HeapCellValue> {
|
fn forward_var(&mut self) -> Option<HeapCellValue> {
|
||||||
if self.heap[self.next].get_forwarding_bit() {
|
if self.heap[self.next as usize].get_forwarding_bit() {
|
||||||
return self.backward_and_return();
|
return self.backward_and_return();
|
||||||
}
|
}
|
||||||
|
|
||||||
let temp = self.heap[self.next].get_value();
|
let temp = self.heap[self.next as usize].get_value();
|
||||||
|
|
||||||
self.heap[self.next].set_value(self.current);
|
self.heap[self.next as usize].set_value(self.current as u64);
|
||||||
self.current = self.next;
|
self.current = self.next as usize;
|
||||||
self.next = temp;
|
self.next = temp;
|
||||||
|
|
||||||
None
|
None
|
||||||
@@ -175,23 +175,23 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
HeapCellValueTag::AttrVar => {
|
HeapCellValueTag::AttrVar => {
|
||||||
if let Some(cell) = UMP::forward_attr_var(self) { return Some(cell); }
|
if let Some(cell) = UMP::forward_attr_var(self) { return Some(cell); }
|
||||||
|
|
||||||
if self.heap[self.next].get_mark_bit() {
|
if self.heap[self.next as usize].get_mark_bit() {
|
||||||
return Some(attr_var_as_cell!(self.current));
|
return Some(attr_var_as_cell!(self.current));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HeapCellValueTag::Var => {
|
HeapCellValueTag::Var => {
|
||||||
if let Some(cell) = self.forward_var() { return Some(cell); }
|
if let Some(cell) = self.forward_var() { return Some(cell); }
|
||||||
|
|
||||||
if self.heap[self.next].get_mark_bit() {
|
if self.heap[self.next as usize].get_mark_bit() {
|
||||||
return Some(heap_loc_as_cell!(self.current));
|
return Some(heap_loc_as_cell!(self.current));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HeapCellValueTag::Str => {
|
HeapCellValueTag::Str => {
|
||||||
if self.heap[self.next + 1].get_forwarding_bit() {
|
if self.heap[self.next as usize + 1].get_forwarding_bit() {
|
||||||
return self.backward_and_return();
|
return self.backward_and_return();
|
||||||
}
|
}
|
||||||
|
|
||||||
let h = self.next;
|
let h = self.next as usize;
|
||||||
let cell = self.heap[h];
|
let cell = self.heap[h];
|
||||||
|
|
||||||
let arity = cell_as_atom_cell!(self.heap[h]).get_arity();
|
let arity = cell_as_atom_cell!(self.heap[h]).get_arity();
|
||||||
@@ -203,13 +203,13 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
let last_cell_loc = h + arity;
|
let last_cell_loc = h + arity;
|
||||||
|
|
||||||
self.next = self.heap[last_cell_loc].get_value();
|
self.next = self.heap[last_cell_loc].get_value();
|
||||||
self.heap[last_cell_loc].set_value(self.current);
|
self.heap[last_cell_loc].set_value(self.current as u64);
|
||||||
self.current = last_cell_loc;
|
self.current = last_cell_loc;
|
||||||
|
|
||||||
return Some(cell);
|
return Some(cell);
|
||||||
}
|
}
|
||||||
HeapCellValueTag::Lis => {
|
HeapCellValueTag::Lis => {
|
||||||
let last_cell_loc = self.next + 1;
|
let last_cell_loc = self.next as usize + 1;
|
||||||
|
|
||||||
if self.heap[last_cell_loc].get_forwarding_bit() {
|
if self.heap[last_cell_loc].get_forwarding_bit() {
|
||||||
return self.backward_and_return();
|
return self.backward_and_return();
|
||||||
@@ -218,13 +218,13 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
self.heap[last_cell_loc].set_forwarding_bit(true);
|
self.heap[last_cell_loc].set_forwarding_bit(true);
|
||||||
|
|
||||||
self.next = self.heap[last_cell_loc].get_value();
|
self.next = self.heap[last_cell_loc].get_value();
|
||||||
self.heap[last_cell_loc].set_value(self.current);
|
self.heap[last_cell_loc].set_value(self.current as u64);
|
||||||
self.current = last_cell_loc;
|
self.current = last_cell_loc;
|
||||||
|
|
||||||
return Some(list_loc_as_cell!(last_cell_loc - 1));
|
return Some(list_loc_as_cell!(last_cell_loc - 1));
|
||||||
}
|
}
|
||||||
HeapCellValueTag::PStrLoc => {
|
HeapCellValueTag::PStrLoc => {
|
||||||
let h = self.next;
|
let h = self.next as usize;
|
||||||
let cell = self.heap[h];
|
let cell = self.heap[h];
|
||||||
|
|
||||||
if self.heap[h+1].get_forwarding_bit() {
|
if self.heap[h+1].get_forwarding_bit() {
|
||||||
@@ -236,13 +236,13 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
self.heap[last_cell_loc].set_forwarding_bit(true);
|
self.heap[last_cell_loc].set_forwarding_bit(true);
|
||||||
|
|
||||||
self.next = self.heap[last_cell_loc].get_value();
|
self.next = self.heap[last_cell_loc].get_value();
|
||||||
self.heap[last_cell_loc].set_value(self.current);
|
self.heap[last_cell_loc].set_value(self.current as u64);
|
||||||
self.current = last_cell_loc;
|
self.current = last_cell_loc;
|
||||||
} else {
|
} else {
|
||||||
debug_assert!(self.heap[h].get_tag() == HeapCellValueTag::PStrOffset);
|
debug_assert!(self.heap[h].get_tag() == HeapCellValueTag::PStrOffset);
|
||||||
|
|
||||||
self.next = self.heap[h].get_value();
|
self.next = self.heap[h].get_value();
|
||||||
self.heap[h].set_value(self.current);
|
self.heap[h].set_value(self.current as u64);
|
||||||
self.current = h;
|
self.current = h;
|
||||||
|
|
||||||
if self.heap[h].get_mark_bit() {
|
if self.heap[h].get_mark_bit() {
|
||||||
@@ -253,7 +253,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
return Some(cell);
|
return Some(cell);
|
||||||
}
|
}
|
||||||
HeapCellValueTag::PStrOffset => {
|
HeapCellValueTag::PStrOffset => {
|
||||||
let h = self.next;
|
let h = self.next as usize;
|
||||||
let cell = self.heap[h];
|
let cell = self.heap[h];
|
||||||
|
|
||||||
// mark the Fixnum offset.
|
// mark the Fixnum offset.
|
||||||
@@ -269,20 +269,20 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
self.heap[last_cell_loc].set_forwarding_bit(true);
|
self.heap[last_cell_loc].set_forwarding_bit(true);
|
||||||
|
|
||||||
self.next = self.heap[last_cell_loc].get_value();
|
self.next = self.heap[last_cell_loc].get_value();
|
||||||
self.heap[last_cell_loc].set_value(self.current);
|
self.heap[last_cell_loc].set_value(self.current as u64);
|
||||||
self.current = last_cell_loc;
|
self.current = last_cell_loc;
|
||||||
} else {
|
} else {
|
||||||
debug_assert!(self.heap[h].get_tag() == HeapCellValueTag::CStr);
|
debug_assert!(self.heap[h].get_tag() == HeapCellValueTag::CStr);
|
||||||
|
|
||||||
self.next = self.heap[h].get_value();
|
self.next = self.heap[h].get_value();
|
||||||
self.heap[h].set_value(self.current);
|
self.heap[h].set_value(self.current as u64);
|
||||||
self.current = h;
|
self.current = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Some(cell);
|
return Some(cell);
|
||||||
}
|
}
|
||||||
tag @ HeapCellValueTag::Atom => {
|
tag @ HeapCellValueTag::Atom => {
|
||||||
let cell = HeapCellValue::build_with(tag, self.next as u64);
|
let cell = HeapCellValue::build_with(tag, self.next);
|
||||||
let arity = AtomCell::from_bytes(cell.into_bytes()).get_arity();
|
let arity = AtomCell::from_bytes(cell.into_bytes()).get_arity();
|
||||||
|
|
||||||
if arity == 0 {
|
if arity == 0 {
|
||||||
@@ -315,8 +315,8 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
UMP::unmark(self.heap, self.current);
|
UMP::unmark(self.heap, self.current);
|
||||||
|
|
||||||
self.heap[self.current].set_value(self.next);
|
self.heap[self.current].set_value(self.next);
|
||||||
self.next = self.current;
|
self.next = self.current as u64;
|
||||||
self.current = temp;
|
self.current = temp as usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.heap[self.current].set_forwarding_bit(false);
|
self.heap[self.current].set_forwarding_bit(false);
|
||||||
|
|||||||
@@ -143,6 +143,10 @@ impl IndexPtr {
|
|||||||
#[derive(Debug, Clone, Copy, Ord, Hash, PartialOrd, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Ord, Hash, PartialOrd, Eq, PartialEq)]
|
||||||
pub struct CodeIndex(TypedArenaPtr<IndexPtr>);
|
pub struct CodeIndex(TypedArenaPtr<IndexPtr>);
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width="32")]
|
||||||
|
const_assert!(std::mem::align_of::<CodeIndex>() == 4);
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width="64")]
|
||||||
const_assert!(std::mem::align_of::<CodeIndex>() == 8);
|
const_assert!(std::mem::align_of::<CodeIndex>() == 8);
|
||||||
|
|
||||||
impl Deref for CodeIndex {
|
impl Deref for CodeIndex {
|
||||||
@@ -164,7 +168,7 @@ impl DerefMut for CodeIndex {
|
|||||||
impl From<CodeIndex> for UntypedArenaPtr {
|
impl From<CodeIndex> for UntypedArenaPtr {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(ptr: CodeIndex) -> UntypedArenaPtr {
|
fn from(ptr: CodeIndex) -> UntypedArenaPtr {
|
||||||
unsafe { std::mem::transmute(ptr.0.as_ptr()) }
|
UntypedArenaPtr::build_with(ptr.0.as_ptr() as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1247,7 +1247,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TrailEntryTag::TrailedBlackboardEntry => {
|
TrailEntryTag::TrailedBlackboardEntry => {
|
||||||
let key = Atom::from(h);
|
let key = Atom::from(h as u64);
|
||||||
|
|
||||||
match self.indices.global_variables.get_mut(&key) {
|
match self.indices.global_variables.get_mut(&key) {
|
||||||
Some((_, ref mut loc)) => *loc = None,
|
Some((_, ref mut loc)) => *loc = None,
|
||||||
@@ -1255,7 +1255,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TrailEntryTag::TrailedBlackboardOffset => {
|
TrailEntryTag::TrailedBlackboardOffset => {
|
||||||
let key = Atom::from(h);
|
let key = Atom::from(h as u64);
|
||||||
let value_cell = HeapCellValue::from(u64::from(self.machine_st.trail[i + 1]));
|
let value_cell = HeapCellValue::from(u64::from(self.machine_st.trail[i + 1]));
|
||||||
|
|
||||||
match self.indices.global_variables.get_mut(&key) {
|
match self.indices.global_variables.get_mut(&key) {
|
||||||
|
|||||||
@@ -372,7 +372,7 @@ impl StreamOptions {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_alias(self) -> Option<Atom> {
|
pub fn get_alias(self) -> Option<Atom> {
|
||||||
if self.has_alias() {
|
if self.has_alias() {
|
||||||
Some(Atom::from((self.alias() << 3) as usize))
|
Some(Atom::from((self.alias() as u64) << 3))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -988,7 +988,7 @@ impl MachineState {
|
|||||||
pub(crate) fn call_continuation_chunk(&mut self, chunk: HeapCellValue, return_p: usize) -> usize {
|
pub(crate) fn call_continuation_chunk(&mut self, chunk: HeapCellValue, return_p: usize) -> usize {
|
||||||
let chunk = self.store(self.deref(chunk));
|
let chunk = self.store(self.deref(chunk));
|
||||||
|
|
||||||
let s = chunk.get_value();
|
let s = chunk.get_value() as usize;
|
||||||
let arity = cell_as_atom_cell!(self.heap[s]).get_arity();
|
let arity = cell_as_atom_cell!(self.heap[s]).get_arity();
|
||||||
|
|
||||||
let num_cells = arity - 1;
|
let num_cells = arity - 1;
|
||||||
@@ -1169,7 +1169,7 @@ impl Machine {
|
|||||||
let attr_var = self.deref_register(1);
|
let attr_var = self.deref_register(1);
|
||||||
|
|
||||||
if let HeapCellValueTag::AttrVar = attr_var.get_tag() {
|
if let HeapCellValueTag::AttrVar = attr_var.get_tag() {
|
||||||
let attr_var_loc = attr_var.get_value();
|
let attr_var_loc = attr_var.get_value() as usize;
|
||||||
self.machine_st.heap[attr_var_loc] = heap_loc_as_cell!(attr_var_loc);
|
self.machine_st.heap[attr_var_loc] = heap_loc_as_cell!(attr_var_loc);
|
||||||
self.machine_st.trail(TrailRef::Ref(Ref::attr_var(attr_var_loc)));
|
self.machine_st.trail(TrailRef::Ref(Ref::attr_var(attr_var_loc)));
|
||||||
}
|
}
|
||||||
@@ -1355,7 +1355,7 @@ impl Machine {
|
|||||||
} else {
|
} else {
|
||||||
if is_internal_call {
|
if is_internal_call {
|
||||||
debug_assert_eq!(goal.get_tag(), HeapCellValueTag::Str);
|
debug_assert_eq!(goal.get_tag(), HeapCellValueTag::Str);
|
||||||
goal = self.machine_st.heap[goal.get_value()+1];
|
goal = self.machine_st.heap[goal.get_value() as usize+1];
|
||||||
(module_name, goal) = self.machine_st.strip_module(goal, module_name);
|
(module_name, goal) = self.machine_st.strip_module(goal, module_name);
|
||||||
|
|
||||||
if let Some((inner_name, inner_arity)) = self.machine_st.name_and_arity_from_heap(goal) {
|
if let Some((inner_name, inner_arity)) = self.machine_st.name_and_arity_from_heap(goal) {
|
||||||
@@ -1585,7 +1585,7 @@ impl Machine {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if HeapCellValueTag::Str == qualified_goal.get_tag() {
|
if HeapCellValueTag::Str == qualified_goal.get_tag() {
|
||||||
let s = qualified_goal.get_value();
|
let s = qualified_goal.get_value() as usize;
|
||||||
let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
|
let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
|
||||||
.get_name_and_arity();
|
.get_name_and_arity();
|
||||||
|
|
||||||
@@ -4896,7 +4896,7 @@ impl Machine {
|
|||||||
Some(AttrListMatch { match_site: MatchSite::Match(match_site), .. }) => {
|
Some(AttrListMatch { match_site: MatchSite::Match(match_site), .. }) => {
|
||||||
let list_head = self.machine_st.heap[match_site];
|
let list_head = self.machine_st.heap[match_site];
|
||||||
|
|
||||||
if list_head.get_value() == match_site {
|
if list_head.get_value() as usize == match_site {
|
||||||
// at the end of the list, no match found in this case.
|
// at the end of the list, no match found in this case.
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -4969,7 +4969,7 @@ impl Machine {
|
|||||||
prev_tail
|
prev_tail
|
||||||
} else {
|
} else {
|
||||||
if self.machine_st.heap[match_site + 1].is_var() {
|
if self.machine_st.heap[match_site + 1].is_var() {
|
||||||
let h = attr_var.get_value();
|
let h = attr_var.get_value() as usize;
|
||||||
|
|
||||||
self.machine_st.heap[h] = heap_loc_as_cell!(h);
|
self.machine_st.heap[h] = heap_loc_as_cell!(h);
|
||||||
self.machine_st.trail(TrailRef::Ref(Ref::attr_var(h)));
|
self.machine_st.trail(TrailRef::Ref(Ref::attr_var(h)));
|
||||||
@@ -5044,13 +5044,13 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
MatchSite::Match(match_site) => {
|
MatchSite::Match(match_site) => {
|
||||||
let l = self.machine_st.heap[match_site].get_value();
|
let l = self.machine_st.heap[match_site].get_value();
|
||||||
self.machine_st.heap[match_site].set_value(h);
|
self.machine_st.heap[match_site].set_value(h as u64);
|
||||||
|
|
||||||
(match_site, l)
|
(match_site, l)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.machine_st.trail(TrailRef::AttrVarListLink(match_site, l));
|
self.machine_st.trail(TrailRef::AttrVarListLink(match_site, l as usize));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// the list is empty.
|
// the list is empty.
|
||||||
@@ -5080,7 +5080,7 @@ impl Machine {
|
|||||||
let mut prev_tail = None;
|
let mut prev_tail = None;
|
||||||
|
|
||||||
while let HeapCellValueTag::Lis = attrs_list.get_tag() {
|
while let HeapCellValueTag::Lis = attrs_list.get_tag() {
|
||||||
let mut list_head = self.machine_st.heap[attrs_list.get_value()];
|
let mut list_head = self.machine_st.heap[attrs_list.get_value() as usize];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
read_heap_cell!(list_head,
|
read_heap_cell!(list_head,
|
||||||
@@ -5100,7 +5100,7 @@ impl Machine {
|
|||||||
|
|
||||||
if module == module_loc && name == t_name && arity == t_arity {
|
if module == module_loc && name == t_name && arity == t_arity {
|
||||||
return Some(AttrListMatch {
|
return Some(AttrListMatch {
|
||||||
match_site: MatchSite::Match(attrs_list.get_value()),
|
match_site: MatchSite::Match(attrs_list.get_value() as usize),
|
||||||
prev_tail,
|
prev_tail,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -5113,7 +5113,7 @@ impl Machine {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tail_loc = attrs_list.get_value() + 1;
|
let tail_loc = attrs_list.get_value() as usize + 1;
|
||||||
prev_tail = Some(tail_loc);
|
prev_tail = Some(tail_loc);
|
||||||
|
|
||||||
// do the work of self.store(self.deref(...)) but inline it
|
// do the work of self.store(self.deref(...)) but inline it
|
||||||
@@ -5458,7 +5458,7 @@ impl Machine {
|
|||||||
let value = self.deref_register(2);
|
let value = self.deref_register(2);
|
||||||
|
|
||||||
debug_assert_eq!(HeapCellValueTag::AttrVar, var.get_tag());
|
debug_assert_eq!(HeapCellValueTag::AttrVar, var.get_tag());
|
||||||
self.machine_st.heap[var.get_value()] = value;
|
self.machine_st.heap[var.get_value() as usize] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ macro_rules! cell_as_string {
|
|||||||
macro_rules! cell_as_atom {
|
macro_rules! cell_as_atom {
|
||||||
($cell:expr) => {{
|
($cell:expr) => {{
|
||||||
let cell = AtomCell::from_bytes($cell.into_bytes());
|
let cell = AtomCell::from_bytes($cell.into_bytes());
|
||||||
let name = cell.get_index() << 3;
|
let name = (cell.get_index() as u64) << 3;
|
||||||
|
|
||||||
Atom::from(name as usize)
|
Atom::from(name)
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,14 +87,14 @@ macro_rules! cell_as_atom_cell {
|
|||||||
|
|
||||||
macro_rules! cell_as_f64_ptr {
|
macro_rules! cell_as_f64_ptr {
|
||||||
($cell:expr) => {{
|
($cell:expr) => {{
|
||||||
let offset = $cell.get_value();
|
let offset = $cell.get_value() as usize;
|
||||||
F64Ptr::from_offset(offset)
|
F64Ptr::from_offset(offset)
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! cell_as_untyped_arena_ptr {
|
macro_rules! cell_as_untyped_arena_ptr {
|
||||||
($cell:expr) => {
|
($cell:expr) => {
|
||||||
UntypedArenaPtr::from(u64::from($cell) as *const ArenaHeader)
|
UntypedArenaPtr::from_bytes($cell.to_untyped_arena_ptr_bytes())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +173,14 @@ macro_rules! attr_var_loc_as_cell {
|
|||||||
|
|
||||||
macro_rules! typed_arena_ptr_as_cell {
|
macro_rules! typed_arena_ptr_as_cell {
|
||||||
($ptr:expr) => {
|
($ptr:expr) => {
|
||||||
untyped_arena_ptr_as_cell!($ptr.header_ptr())
|
raw_ptr_as_cell!($ptr.header_ptr())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! raw_ptr_as_cell {
|
||||||
|
($ptr:expr) => {
|
||||||
|
// Cell is 64-bit, but raw ptr is 32-bit in 32-bit systems
|
||||||
|
HeapCellValue::from_raw_ptr_bytes(unsafe { std::mem::transmute($ptr) })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +224,7 @@ macro_rules! string_as_pstr_cell {
|
|||||||
|
|
||||||
macro_rules! stream_as_cell {
|
macro_rules! stream_as_cell {
|
||||||
($ptr:expr) => {
|
($ptr:expr) => {
|
||||||
untyped_arena_ptr_as_cell!($ptr.as_ptr())
|
raw_ptr_as_cell!($ptr.as_ptr())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,13 +257,15 @@ macro_rules! match_untyped_arena_ptr_pat_body {
|
|||||||
#[allow(unused_braces)]
|
#[allow(unused_braces)]
|
||||||
$code
|
$code
|
||||||
}};
|
}};
|
||||||
($cell:ident, OssifiedOpDir, $n:ident, $code:expr) => {{
|
($ptr:ident, OssifiedOpDir, $n:ident, $code:expr) => {{
|
||||||
let $n = cell_as_ossified_op_dir!($cell);
|
let payload_ptr = unsafe { std::mem::transmute::<_, *mut OssifiedOpDir>($ptr.payload_offset()) };
|
||||||
|
let $n = TypedArenaPtr::new(payload_ptr);
|
||||||
#[allow(unused_braces)]
|
#[allow(unused_braces)]
|
||||||
$code
|
$code
|
||||||
}};
|
}};
|
||||||
($cell:ident, LiveLoadState, $n:ident, $code:expr) => {{
|
($ptr:ident, LiveLoadState, $n:ident, $code:expr) => {{
|
||||||
let $n = cell_as_load_state_payload!($cell);
|
let payload_ptr = unsafe { std::mem::transmute::<_, *mut LiveLoadState>($ptr.payload_offset()) };
|
||||||
|
let $n = TypedArenaPtr::new(payload_ptr);
|
||||||
#[allow(unused_braces)]
|
#[allow(unused_braces)]
|
||||||
$code
|
$code
|
||||||
}};
|
}};
|
||||||
|
|||||||
89
src/types.rs
89
src/types.rs
@@ -88,6 +88,15 @@ impl ConsPtr {
|
|||||||
.with_tag(tag)
|
.with_tag(tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width="32")]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn as_ptr(self) -> *mut u8 {
|
||||||
|
let bytes = self.into_bytes();
|
||||||
|
let raw_ptr_bytes = [bytes[1], bytes[2], bytes[3], bytes[4]];
|
||||||
|
unsafe { mem::transmute(raw_ptr_bytes) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width="64")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn as_ptr(self) -> *mut u8 {
|
pub fn as_ptr(self) -> *mut u8 {
|
||||||
self.ptr() as *mut _
|
self.ptr() as *mut _
|
||||||
@@ -444,7 +453,7 @@ impl HeapCellValue {
|
|||||||
pub fn is_compound(self, heap: &[HeapCellValue]) -> bool {
|
pub fn is_compound(self, heap: &[HeapCellValue]) -> bool {
|
||||||
match self.get_tag() {
|
match self.get_tag() {
|
||||||
HeapCellValueTag::Str => {
|
HeapCellValueTag::Str => {
|
||||||
cell_as_atom_cell!(heap[self.get_value()]).get_arity() > 0
|
cell_as_atom_cell!(heap[self.get_value() as usize]).get_arity() > 0
|
||||||
}
|
}
|
||||||
HeapCellValueTag::Lis |
|
HeapCellValueTag::Lis |
|
||||||
HeapCellValueTag::CStr |
|
HeapCellValueTag::CStr |
|
||||||
@@ -491,13 +500,13 @@ impl HeapCellValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_value(self) -> usize {
|
pub fn get_value(self) -> u64 {
|
||||||
self.val() as usize
|
self.val() as u64
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_value(&mut self, val: usize) {
|
pub fn set_value(&mut self, val: u64) {
|
||||||
self.set_val(val as u64);
|
self.set_val(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -513,7 +522,7 @@ impl HeapCellValue {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_atom(self) -> Option<Atom> {
|
pub fn to_atom(self) -> Option<Atom> {
|
||||||
match self.tag() {
|
match self.tag() {
|
||||||
HeapCellValueTag::Atom => Some(Atom::from((self.val() << 3) as usize)),
|
HeapCellValueTag::Atom => Some(Atom::from(self.val() << 3)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -522,7 +531,7 @@ impl HeapCellValue {
|
|||||||
pub fn to_pstr(self) -> Option<PartialString> {
|
pub fn to_pstr(self) -> Option<PartialString> {
|
||||||
match self.tag() {
|
match self.tag() {
|
||||||
HeapCellValueTag::PStr => {
|
HeapCellValueTag::PStr => {
|
||||||
Some(PartialString::from(Atom::from((self.val() as usize) << 3)))
|
Some(PartialString::from(Atom::from(self.val() << 3)))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@@ -536,10 +545,39 @@ impl HeapCellValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width="32")]
|
||||||
|
#[inline]
|
||||||
|
pub fn from_raw_ptr_bytes(ptr_bytes: [u8; 4]) -> Self {
|
||||||
|
HeapCellValue::from_bytes([ptr_bytes[0], ptr_bytes[1], ptr_bytes[2], ptr_bytes[3], 0, 0, 0, 0])
|
||||||
|
}
|
||||||
|
#[cfg(target_pointer_width="64")]
|
||||||
|
#[inline]
|
||||||
|
pub fn from_raw_ptr_bytes(ptr_bytes: [u8; 8]) -> Self {
|
||||||
|
HeapCellValue::from_bytes(ptr_bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cfg(target_pointer_width="32")]
|
||||||
|
pub fn to_raw_ptr_bytes(self) -> [u8; 4] {
|
||||||
|
let bytes = self.into_bytes();
|
||||||
|
[bytes[0], bytes[1], bytes[2], bytes[3]]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cfg(target_pointer_width="64")]
|
||||||
|
pub fn to_raw_ptr_bytes(self) -> [u8; 8] {
|
||||||
|
self.into_bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn to_untyped_arena_ptr_bytes(self) -> [u8; 8] {
|
||||||
|
self.into_bytes()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_untyped_arena_ptr(self) -> Option<UntypedArenaPtr> {
|
pub fn to_untyped_arena_ptr(self) -> Option<UntypedArenaPtr> {
|
||||||
match self.tag() {
|
match self.get_tag() {
|
||||||
HeapCellValueTag::Cons => Some(UntypedArenaPtr::from_bytes(self.into_bytes())),
|
HeapCellValueTag::Cons => Some(UntypedArenaPtr::from_bytes(self.to_untyped_arena_ptr_bytes())),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -607,7 +645,7 @@ impl HeapCellValue {
|
|||||||
Some(TermOrderCategory::Compound)
|
Some(TermOrderCategory::Compound)
|
||||||
}
|
}
|
||||||
HeapCellValueTag::Str => {
|
HeapCellValueTag::Str => {
|
||||||
let value = heap[self.get_value()];
|
let value = heap[self.get_value() as usize];
|
||||||
let arity = cell_as_atom_cell!(value).get_arity();
|
let arity = cell_as_atom_cell!(value).get_arity();
|
||||||
|
|
||||||
if arity == 0 {
|
if arity == 0 {
|
||||||
@@ -647,26 +685,34 @@ pub struct UntypedArenaPtr {
|
|||||||
#[allow(unused)] padding: B2,
|
#[allow(unused)] padding: B2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl UntypedArenaPtr {
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn build_with(ptr: usize) -> Self {
|
||||||
|
UntypedArenaPtr::new()
|
||||||
|
.with_ptr(ptr as u64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const_assert!(mem::size_of::<UntypedArenaPtr>() == 8);
|
const_assert!(mem::size_of::<UntypedArenaPtr>() == 8);
|
||||||
|
|
||||||
impl From<*const ArenaHeader> for UntypedArenaPtr {
|
impl From<*const ArenaHeader> for UntypedArenaPtr {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(ptr: *const ArenaHeader) -> UntypedArenaPtr {
|
fn from(ptr: *const ArenaHeader) -> UntypedArenaPtr {
|
||||||
unsafe { mem::transmute(ptr) }
|
UntypedArenaPtr::build_with(ptr as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<*const IndexPtr> for UntypedArenaPtr {
|
impl From<*const IndexPtr> for UntypedArenaPtr {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(ptr: *const IndexPtr) -> UntypedArenaPtr {
|
fn from(ptr: *const IndexPtr) -> UntypedArenaPtr {
|
||||||
unsafe { mem::transmute(ptr) }
|
UntypedArenaPtr::build_with(ptr as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<UntypedArenaPtr> for *const ArenaHeader {
|
impl From<UntypedArenaPtr> for *const ArenaHeader {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(ptr: UntypedArenaPtr) -> *const ArenaHeader {
|
fn from(ptr: UntypedArenaPtr) -> *const ArenaHeader {
|
||||||
unsafe { mem::transmute(ptr) }
|
ptr.get_ptr() as *const ArenaHeader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,6 +722,15 @@ impl UntypedArenaPtr {
|
|||||||
self.set_m(m);
|
self.set_m(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width="32")]
|
||||||
|
#[inline]
|
||||||
|
pub fn get_ptr(self) -> *const u8 {
|
||||||
|
let bytes = self.into_bytes();
|
||||||
|
let raw_ptr_bytes = [bytes[0], bytes[1], bytes[2], bytes[3]];
|
||||||
|
unsafe { mem::transmute(raw_ptr_bytes) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width="64")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_ptr(self) -> *const u8 {
|
pub fn get_ptr(self) -> *const u8 {
|
||||||
self.ptr() as *const u8
|
self.ptr() as *const u8
|
||||||
@@ -684,7 +739,7 @@ impl UntypedArenaPtr {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_tag(self) -> ArenaHeaderTag {
|
pub fn get_tag(self) -> ArenaHeaderTag {
|
||||||
unsafe {
|
unsafe {
|
||||||
let header = *(self.ptr() as *const ArenaHeader);
|
let header = *(self.get_ptr() as *const ArenaHeader);
|
||||||
header.get_tag()
|
header.get_tag()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -714,7 +769,7 @@ impl Add<usize> for HeapCellValue {
|
|||||||
tag @ HeapCellValueTag::PStrLoc |
|
tag @ HeapCellValueTag::PStrLoc |
|
||||||
tag @ HeapCellValueTag::Var |
|
tag @ HeapCellValueTag::Var |
|
||||||
tag @ HeapCellValueTag::AttrVar => {
|
tag @ HeapCellValueTag::AttrVar => {
|
||||||
HeapCellValue::build_with(tag, (self.get_value() + rhs) as u64)
|
HeapCellValue::build_with(tag, (self.get_value() as usize + rhs) as u64)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self
|
self
|
||||||
@@ -734,7 +789,7 @@ impl Sub<usize> for HeapCellValue {
|
|||||||
tag @ HeapCellValueTag::PStrLoc |
|
tag @ HeapCellValueTag::PStrLoc |
|
||||||
tag @ HeapCellValueTag::Var |
|
tag @ HeapCellValueTag::Var |
|
||||||
tag @ HeapCellValueTag::AttrVar => {
|
tag @ HeapCellValueTag::AttrVar => {
|
||||||
HeapCellValue::build_with(tag, (self.get_value() - rhs) as u64)
|
HeapCellValue::build_with(tag, (self.get_value() as usize - rhs) as u64)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self
|
self
|
||||||
@@ -762,7 +817,7 @@ impl Sub<i64> for HeapCellValue {
|
|||||||
tag @ HeapCellValueTag::PStrLoc |
|
tag @ HeapCellValueTag::PStrLoc |
|
||||||
tag @ HeapCellValueTag::Var |
|
tag @ HeapCellValueTag::Var |
|
||||||
tag @ HeapCellValueTag::AttrVar => {
|
tag @ HeapCellValueTag::AttrVar => {
|
||||||
HeapCellValue::build_with(tag, (self.get_value() + rhs.abs() as usize) as u64)
|
HeapCellValue::build_with(tag, self.get_value() + rhs.abs() as u64)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self
|
self
|
||||||
|
|||||||
Reference in New Issue
Block a user