fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated;
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 {
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 layout = alloc::Layout::from_size_align_unchecked(size, align);
}
}
+#[repr(C)]
#[derive(Clone, Copy, Debug)]
struct AllocSlab {
next: *mut AllocSlab,
+ #[cfg(target_pointer_width="32")]
+ _padding: u32,
header: ArenaHeader,
}
#[test]
fn heap_cell_value_const_cast() {
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(
0x0000_5555_ff00_0431 as *const _,
ConsPtrMaskTag::Cons,
match const_value.to_untyped_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 => {
assert!(false);
match stream_cell.to_untyped_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 => {
assert!(false);
read_heap_cell!(cell,
(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(), "[]");
}
_ => { unreachable!() }
}
#[inline(always)]
- pub fn from(index: usize) -> Self {
- Self { index: index as u64 }
+ pub fn from(index: u64) -> Self {
+ Self { index }
}
#[inline(always)]
#[inline]
pub fn get_name(self) -> Atom {
- Atom::from(self.get_index() << 3)
+ Atom::from((self.get_index() as u64) << 3)
}
#[inline]
#[inline]
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())
}
}
fn copy_attr_var_list(&mut self, mut list_addr: HeapCellValue) {
while let HeapCellValueTag::Lis = list_addr.get_tag() {
let threshold = self.target.threshold();
- let heap_loc = list_addr.get_value();
- let str_loc = self.target[heap_loc].get_value();
+ let heap_loc = list_addr.get_value() as usize;
+ 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+1));
orig_heap_len: usize,
start: usize,
current: usize,
- next: usize,
+ next: u64,
_marker: PhantomData<UMP>,
}
}
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();
}
- 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.current = self.next;
+ self.heap[self.next as usize].set_value(self.current as u64);
+ self.current = self.next as usize;
self.next = temp;
None
HeapCellValueTag::AttrVar => {
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));
}
}
HeapCellValueTag::Var => {
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));
}
}
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();
}
- let h = self.next;
+ let h = self.next as usize;
let cell = self.heap[h];
let arity = cell_as_atom_cell!(self.heap[h]).get_arity();
let last_cell_loc = h + arity;
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;
return Some(cell);
}
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() {
return self.backward_and_return();
self.heap[last_cell_loc].set_forwarding_bit(true);
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;
return Some(list_loc_as_cell!(last_cell_loc - 1));
}
HeapCellValueTag::PStrLoc => {
- let h = self.next;
+ let h = self.next as usize;
let cell = self.heap[h];
if self.heap[h+1].get_forwarding_bit() {
self.heap[last_cell_loc].set_forwarding_bit(true);
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;
} else {
debug_assert!(self.heap[h].get_tag() == HeapCellValueTag::PStrOffset);
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;
if self.heap[h].get_mark_bit() {
return Some(cell);
}
HeapCellValueTag::PStrOffset => {
- let h = self.next;
+ let h = self.next as usize;
let cell = self.heap[h];
// mark the Fixnum offset.
self.heap[last_cell_loc].set_forwarding_bit(true);
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;
} else {
debug_assert!(self.heap[h].get_tag() == HeapCellValueTag::CStr);
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;
}
return Some(cell);
}
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();
if arity == 0 {
UMP::unmark(self.heap, self.current);
self.heap[self.current].set_value(self.next);
- self.next = self.current;
- self.current = temp;
+ self.next = self.current as u64;
+ self.current = temp as usize;
}
self.heap[self.current].set_forwarding_bit(false);
#[derive(Debug, Clone, Copy, Ord, Hash, PartialOrd, Eq, PartialEq)]
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);
impl Deref for CodeIndex {
impl From<CodeIndex> for UntypedArenaPtr {
#[inline(always)]
fn from(ptr: CodeIndex) -> UntypedArenaPtr {
- unsafe { std::mem::transmute(ptr.0.as_ptr()) }
+ UntypedArenaPtr::build_with(ptr.0.as_ptr() as usize)
}
}
}
}
TrailEntryTag::TrailedBlackboardEntry => {
- let key = Atom::from(h);
+ let key = Atom::from(h as u64);
match self.indices.global_variables.get_mut(&key) {
Some((_, ref mut loc)) => *loc = None,
}
}
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]));
match self.indices.global_variables.get_mut(&key) {
#[inline]
pub fn get_alias(self) -> Option<Atom> {
if self.has_alias() {
- Some(Atom::from((self.alias() << 3) as usize))
+ Some(Atom::from((self.alias() as u64) << 3))
} else {
None
}
pub(crate) fn call_continuation_chunk(&mut self, chunk: HeapCellValue, return_p: usize) -> usize {
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 num_cells = arity - 1;
let attr_var = self.deref_register(1);
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.trail(TrailRef::Ref(Ref::attr_var(attr_var_loc)));
}
} else {
if is_internal_call {
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);
if let Some((inner_name, inner_arity)) = self.machine_st.name_and_arity_from_heap(goal) {
);
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])
.get_name_and_arity();
Some(AttrListMatch { match_site: MatchSite::Match(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.
self.machine_st.fail = true;
} else {
prev_tail
} else {
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.trail(TrailRef::Ref(Ref::attr_var(h)));
}
MatchSite::Match(match_site) => {
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)
}
};
- self.machine_st.trail(TrailRef::AttrVarListLink(match_site, l));
+ self.machine_st.trail(TrailRef::AttrVarListLink(match_site, l as usize));
}
None => {
// the list is empty.
let mut prev_tail = None;
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 {
read_heap_cell!(list_head,
if module == module_loc && name == t_name && arity == t_arity {
return Some(AttrListMatch {
- match_site: MatchSite::Match(attrs_list.get_value()),
+ match_site: MatchSite::Match(attrs_list.get_value() as usize),
prev_tail,
});
}
);
}
- let tail_loc = attrs_list.get_value() + 1;
+ let tail_loc = attrs_list.get_value() as usize + 1;
prev_tail = Some(tail_loc);
// do the work of self.store(self.deref(...)) but inline it
let value = self.deref_register(2);
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)]
macro_rules! cell_as_atom {
($cell:expr) => {{
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)
}};
}
macro_rules! cell_as_f64_ptr {
($cell:expr) => {{
- let offset = $cell.get_value();
+ let offset = $cell.get_value() as usize;
F64Ptr::from_offset(offset)
}};
}
macro_rules! cell_as_untyped_arena_ptr {
($cell:expr) => {
- UntypedArenaPtr::from(u64::from($cell) as *const ArenaHeader)
+ UntypedArenaPtr::from_bytes($cell.to_untyped_arena_ptr_bytes())
};
}
macro_rules! typed_arena_ptr_as_cell {
($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) })
};
}
macro_rules! stream_as_cell {
($ptr:expr) => {
- untyped_arena_ptr_as_cell!($ptr.as_ptr())
+ raw_ptr_as_cell!($ptr.as_ptr())
};
}
#[allow(unused_braces)]
$code
}};
- ($cell:ident, OssifiedOpDir, $n:ident, $code:expr) => {{
- let $n = cell_as_ossified_op_dir!($cell);
+ ($ptr:ident, OssifiedOpDir, $n:ident, $code:expr) => {{
+ let payload_ptr = unsafe { std::mem::transmute::<_, *mut OssifiedOpDir>($ptr.payload_offset()) };
+ let $n = TypedArenaPtr::new(payload_ptr);
#[allow(unused_braces)]
$code
}};
- ($cell:ident, LiveLoadState, $n:ident, $code:expr) => {{
- let $n = cell_as_load_state_payload!($cell);
+ ($ptr:ident, LiveLoadState, $n:ident, $code:expr) => {{
+ let payload_ptr = unsafe { std::mem::transmute::<_, *mut LiveLoadState>($ptr.payload_offset()) };
+ let $n = TypedArenaPtr::new(payload_ptr);
#[allow(unused_braces)]
$code
}};
.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)]
pub fn as_ptr(self) -> *mut u8 {
self.ptr() as *mut _
pub fn is_compound(self, heap: &[HeapCellValue]) -> bool {
match self.get_tag() {
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::CStr |
}
#[inline]
- pub fn get_value(self) -> usize {
- self.val() as usize
+ pub fn get_value(self) -> u64 {
+ self.val() as u64
}
#[inline]
- pub fn set_value(&mut self, val: usize) {
- self.set_val(val as u64);
+ pub fn set_value(&mut self, val: u64) {
+ self.set_val(val);
}
#[inline]
#[inline]
pub fn to_atom(self) -> Option<Atom> {
match self.tag() {
- HeapCellValueTag::Atom => Some(Atom::from((self.val() << 3) as usize)),
+ HeapCellValueTag::Atom => Some(Atom::from(self.val() << 3)),
_ => None,
}
}
pub fn to_pstr(self) -> Option<PartialString> {
match self.tag() {
HeapCellValueTag::PStr => {
- Some(PartialString::from(Atom::from((self.val() as usize) << 3)))
+ Some(PartialString::from(Atom::from(self.val() << 3)))
}
_ => None,
}
}
}
+ #[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]
pub fn to_untyped_arena_ptr(self) -> Option<UntypedArenaPtr> {
- match self.tag() {
- HeapCellValueTag::Cons => Some(UntypedArenaPtr::from_bytes(self.into_bytes())),
+ match self.get_tag() {
+ HeapCellValueTag::Cons => Some(UntypedArenaPtr::from_bytes(self.to_untyped_arena_ptr_bytes())),
_ => None,
}
}
Some(TermOrderCategory::Compound)
}
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();
if arity == 0 {
#[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);
impl From<*const ArenaHeader> for UntypedArenaPtr {
#[inline]
fn from(ptr: *const ArenaHeader) -> UntypedArenaPtr {
- unsafe { mem::transmute(ptr) }
+ UntypedArenaPtr::build_with(ptr as usize)
}
}
impl From<*const IndexPtr> for UntypedArenaPtr {
#[inline]
fn from(ptr: *const IndexPtr) -> UntypedArenaPtr {
- unsafe { mem::transmute(ptr) }
+ UntypedArenaPtr::build_with(ptr as usize)
}
}
impl From<UntypedArenaPtr> for *const ArenaHeader {
#[inline]
fn from(ptr: UntypedArenaPtr) -> *const ArenaHeader {
- unsafe { mem::transmute(ptr) }
+ ptr.get_ptr() as *const ArenaHeader
}
}
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]
pub fn get_ptr(self) -> *const u8 {
- self.ptr() as *const u8
+ self.ptr() as *const u8
}
#[inline]
pub fn get_tag(self) -> ArenaHeaderTag {
unsafe {
- let header = *(self.ptr() as *const ArenaHeader);
+ let header = *(self.get_ptr() as *const ArenaHeader);
header.get_tag()
}
}
tag @ HeapCellValueTag::PStrLoc |
tag @ HeapCellValueTag::Var |
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
tag @ HeapCellValueTag::PStrLoc |
tag @ HeapCellValueTag::Var |
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
tag @ HeapCellValueTag::PStrLoc |
tag @ HeapCellValueTag::Var |
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