From 2b0cfe19bee43e128b15d31cba1b1732f173f7f4 Mon Sep 17 00:00:00 2001 From: Cassie Jones Date: Sat, 2 Jan 2021 18:03:27 -0500 Subject: [PATCH] [rt] Change is_ predicates to tag checks --- rt/src/int.rs | 3 ++- rt/src/lam.rs | 9 ++------ rt/src/lib.rs | 60 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/rt/src/int.rs b/rt/src/int.rs index 6b11d1d..f6148b4 100644 --- a/rt/src/int.rs +++ b/rt/src/int.rs @@ -11,7 +11,7 @@ pub struct ObjInt { #[no_mangle] pub unsafe extern "C" fn ivy_check_int(obj: Obj) { - if !obj.is_int() { + if obj.tag() != Some(ObjTag::Int) { panic!( "ivy_check_int called with non-integer object {:016x}.", obj.int @@ -24,5 +24,6 @@ pub unsafe extern "C" fn ivy_check_int(obj: Obj) { // Or maybe it's valuable if we want to support big integers. #[no_mangle] pub unsafe extern "C" fn ivy_make_int(value: i64) -> Obj { + // @TODO: Handle 64 bit values rather than 63 bit integers Obj { int: value << 1 } } diff --git a/rt/src/lam.rs b/rt/src/lam.rs index ffdb5f6..72fd667 100644 --- a/rt/src/lam.rs +++ b/rt/src/lam.rs @@ -14,7 +14,7 @@ pub struct ObjLam { #[no_mangle] pub unsafe extern "C" fn ivy_check_lam(obj: Obj) { - if !obj.is_lam() { + if obj.tag() != Some(ObjTag::Lam) { panic!( "ivy_check_lam called with non-lambda object {:016x}.", obj.int @@ -54,7 +54,7 @@ pub unsafe extern "C" fn ivy_app(fun: Obj, arg: Obj) -> Obj { #[no_mangle] pub unsafe extern "C" fn ivy_app_mut(fun: Obj, arg: Obj) -> Obj { trace!("APP {:016x} {:016x}", fun.int, arg.int); - if !fun.is_lam() { + if fun.tag() != Some(ObjTag::Lam) { panic!( "ivy_app called with a non-lam as the function: {:016x}.", fun.int @@ -112,11 +112,6 @@ impl ObjLam { unsafe { core::slice::from_raw_parts(ptr, self.params as usize) } } - unsafe fn upvars_mut(&mut self) -> &mut [Obj] { - let ptr = self.raw_fields_mut().add(self.params as usize); - core::slice::from_raw_parts_mut(ptr, self.upvars as usize) - } - pub(crate) fn upvars(&self) -> &[Obj] { unsafe { let ptr = self.raw_fields_mut().add(self.params as usize); diff --git a/rt/src/lib.rs b/rt/src/lib.rs index 2bd2386..692d3dc 100644 --- a/rt/src/lib.rs +++ b/rt/src/lib.rs @@ -19,7 +19,7 @@ macro_rules! trace { } #[repr(u8)] -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, Clone, Copy)] pub enum ObjTag { Lam = 0, Int = 1, @@ -81,18 +81,23 @@ pub unsafe extern "C" fn ivy_clone(obj: Obj) -> Obj { if obj.is_null() || !obj.is_box() { return obj; } - if obj.is_int() { - unimplemented!("copying boxed integers") + match obj.tag() { + None => unreachable!(), + Some(ObjTag::Int) => { + unimplemented!("copying boxed integers") + } + Some(ObjTag::Lam) => { + let lam = &*obj.box_lam; + let size = lam.size(); + let data = sys::malloc(size); + core::ptr::copy(obj.box_lam as *const u8, data, size); + let box_hdr = data as *mut ObjHeader; + *(*box_hdr).rc.get_mut() = 0; + trace!("COPY {:016x} {:016x}", obj.int, box_hdr as usize); + let box_lam = data as *mut ObjLam; + Obj { box_lam } + } } - let lam = &*obj.box_lam; - let size = lam.size(); - let data = sys::malloc(size); - core::ptr::copy(obj.box_lam as *const u8, data, size); - let box_hdr = data as *mut ObjHeader; - *(*box_hdr).rc.get_mut() = 0; - trace!("COPY {:016x} {:016x}", obj.int, box_hdr as usize); - let box_lam = data as *mut ObjLam; - Obj { box_lam } } impl Obj { @@ -104,12 +109,14 @@ impl Obj { !self.is_null() && unsafe { self.int & 1 == 0 } } - unsafe fn is_int(self) -> bool { - !self.is_null() && (!self.is_box() || (*self.header).tag == ObjTag::Int) - } - - unsafe fn is_lam(self) -> bool { - self.is_box() && (*self.header).tag == ObjTag::Lam + unsafe fn tag(self) -> Option { + if self.is_null() { + None + } else if self.is_box() { + Some((*self.header).tag) + } else { + Some(ObjTag::Int) + } } unsafe fn incref(self) { @@ -141,13 +148,16 @@ impl Obj { if !self.is_box() { return; } - if self.is_lam() { - let lam = &mut *self.box_lam; - for param in lam.params() { - param.decref(); - } - for upvar in lam.upvars() { - upvar.decref(); + match self.tag() { + None | Some(ObjTag::Int) => (), + Some(ObjTag::Lam) => { + let lam = &mut *self.box_lam; + for param in lam.params() { + param.decref(); + } + for upvar in lam.upvars() { + upvar.decref(); + } } } sys::free(self.header as *mut u8); -- 2.47.0