use crate::place::Ptr;
use crate::slice::Slice;
use crate::string::GoStr;
use crate::trace::{Trace, Tracer};
use crate::value::GoValue;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[repr(transparent)]
pub struct UPtr(usize);
impl GoValue for UPtr {
#[inline]
fn zero() -> Self {
UPtr(0)
}
}
impl Trace for UPtr {
#[inline]
fn trace(&self, t: &mut Tracer<'_>) {
t.edge(self.0);
}
}
impl UPtr {
#[inline]
pub fn from_ptr<P>(p: Ptr<P>) -> Self {
UPtr(p.addr() as usize)
}
#[inline]
pub fn from_addr(u: u64) -> Self {
UPtr(u as usize)
}
#[inline]
pub fn addr(self) -> u64 {
self.0 as u64
}
#[inline]
pub unsafe fn to_ptr<P>(self) -> Ptr<P> {
unsafe { Ptr::from_addr(self.0) }
}
#[inline]
pub fn offset(self, n: i64) -> Self {
UPtr(self.0.wrapping_add(n as usize))
}
}
impl<P> Slice<P> {
#[inline]
pub unsafe fn from_raw(ptr: Ptr<P>, len: i64) -> Self {
if len < 0 {
crate::panic::runtime_error(crate::panic::RuntimeError::UnsafeSliceLen);
}
if ptr.addr() == 0 && len > 0 {
crate::panic::runtime_error(crate::panic::RuntimeError::UnsafeSliceNil);
}
unsafe { Slice::from_parts(ptr.addr() as usize as *mut P, len as usize, len as usize) }
}
#[inline]
pub fn data_ptr(self) -> Ptr<P> {
unsafe { Ptr::from_addr(self.addr() as usize) }
}
}
impl GoStr {
#[inline]
pub unsafe fn from_raw(ptr: Ptr<crate::place::Slot<u8>>, len: i64) -> Self {
if len < 0 {
crate::panic::runtime_error(crate::panic::RuntimeError::UnsafeStringLen);
}
unsafe { GoStr::from_parts(ptr.addr() as usize as *const u8, len as usize) }
}
#[inline]
pub fn data_ptr(self) -> Ptr<crate::place::Slot<u8>> {
unsafe { Ptr::from_addr(self.bytes().as_ptr() as usize) }
}
}