]>
Witch of Git - ivy/blob - rt/src/lib.rs
   2 use core
::{sync
::atomic
::{AtomicU32
, Ordering
}, panic
::PanicInfo
, fmt
::Write
}; 
   5 fn handle_panic(panic_info
: &PanicInfo
) -> ! { 
   6     if let Some(s
) = panic_info
.payload().downcast_ref
::<&str>() { 
   9         abort("a panic occurred\n"); 
  13 const STDOUT
: i32 = 1; 
  14 const STDERR
: i32 = 2; 
  17 #[derive(PartialEq, Eq)] 
  24 pub struct ObjHeader 
{ 
  41     func
: fn(&ObjLam
) -> Obj
, 
  46 #[derive(Clone, Copy)] 
  49     header
: *mut ObjHeader
, 
  56         pub fn write(fd
: i32, buf
: *const u8, len
: usize) -> isize; 
  57         pub fn exit(code
: i32) -> !; 
  58         pub fn malloc(size
: usize) -> *mut u8; 
  59         pub fn free(ptr
: *mut u8); 
  64 pub unsafe extern "C" fn ivy_debug(obj
: Obj
) -> Obj 
{ 
  65     // let mut buffer = String::new(); 
  66     // writeln!(&mut buffer, "DBUG {:016x}", obj.int); 
  67     const BUFFER
: &str = "DEBUG\n"; 
  68     sys
::write(STDOUT
, BUFFER
.as_ptr(), BUFFER
.len()); 
  73 pub unsafe extern "C" fn ivy_abort(msg
: *const u8, len
: usize) -> ! { 
  74     sys
::write(STDERR
, msg
, len
); 
  79 pub unsafe extern "C" fn ivy_exit(code
: i32) -> ! { 
  84 pub unsafe extern "C" fn ivy_check_int(obj
: Obj
) { 
  86         abort("Abort: ivy_check_int called with non-integer object.\n"); 
  91 pub unsafe extern "C" fn ivy_check_lam(obj
: Obj
) { 
  93         abort("Abort: ivy_check_lam called with non-lambda object.\n"); 
  97 // This should probably be a macro rather than a call? 
  98 // But it might be good to have it for completeness. 
  99 // Or maybe it's valuable if we want to support big integers. 
 101 pub unsafe extern "C" fn ivy_make_int(value
: i64) -> Obj 
{ 
 102     Obj 
{ int
: value 
<< 1 } 
 106 pub unsafe extern "C" fn ivy_make_lam(func
: fn(&ObjLam
) -> Obj
, params
: u16, upvars
: u16) -> Obj 
{ 
 107     let size 
= ObjLam
::size_of(params
, upvars
); 
 108     let box_lam 
= sys
::malloc(size
) as *mut ObjLam
; 
 109     box_lam
.write(ObjLam 
{ 
 112         rc
: AtomicU32
::new(0), 
 119         .write_bytes(0, (params 
+ upvars
) as usize); 
 120     // println!("MAKE {:016x}", box_lam as usize); 
 125 pub unsafe extern "C" fn ivy_free(obj
: Obj
) { 
 129     sys
::free(obj
.header 
as *mut u8) 
 133 pub unsafe extern "C" fn ivy_incref(obj
: Obj
) { 
 138 pub unsafe extern "C" fn ivy_decref(obj
: Obj
) { 
 143 pub unsafe extern "C" fn ivy_clone(obj
: Obj
) -> Obj 
{ 
 144     if obj
.is_null() || !obj
.is_box() { 
 148         abort("Abort: copying boxed integers is not implemented.\n") 
 150     let lam 
= &*obj
.box_lam
; 
 151     let size 
= lam
.size(); 
 152     let data 
= sys
::malloc(size
); 
 153     core
::ptr
::copy(obj
.box_lam 
as *const u8, data
, size
); 
 154     let box_lam 
= data 
as *mut ObjLam
; 
 155     *(*box_lam
).rc
.get_mut() = 0; 
 156     // println!("COPY {:016x} {:016x}", obj.int, box_lam as usize); 
 161 pub unsafe extern "C" fn ivy_app(mut fun
: Obj
, arg
: Obj
) -> Obj 
{ 
 162     ivy_app_mut(ivy_clone(fun
), arg
) 
 166 pub unsafe extern "C" fn ivy_app_mut(fun
: Obj
, arg
: Obj
) -> Obj 
{ 
 167     // println!("APP  {:016x} {:016x}", fun.int, arg.int); 
 169         abort("Abort: ivy_app called with a non-lam as the function.\n"); 
 171     let lam 
= &mut *fun
.box_lam
; 
 172     if lam
.filled 
< lam
.params 
{ 
 174             abort("Abort: ivy_app called with a null arg.\n"); 
 177         let idx 
= lam
.filled 
as usize; 
 178         lam
.params_mut()[idx
] = arg
; 
 180     } else if lam
.params 
== lam
.filled 
{ 
 182             abort("Abort: ivy_app called for a 0-arity application with a non-null arg.\n"); 
 186     if lam
.params 
== lam
.filled 
{ 
 187         // println!("RUN  {:016x}", fun.int); 
 190         // println!("UPD8 {:016x}", fun.int); 
 196 fn abort(msg
: &str) -> ! { 
 197     unsafe { ivy_abort(msg
.as_ptr(), msg
.len()) } 
 201     fn is_null(self) -> bool 
{ 
 202         unsafe { self.int 
== 0 } 
 205     fn is_box(self) -> bool 
{ 
 206         !self.is_null() && unsafe { self.int 
& 1 == 0 } 
 209     unsafe fn refcount(self) -> u32 { 
 211             (*self.header
).rc
.load(Ordering
::SeqCst
) 
 217     unsafe fn unique(self) -> bool 
{ 
 221     unsafe fn is_int(self) -> bool 
{ 
 222         !self.is_null() && (!self.is_box() || (*self.header
).tag 
== ObjTag
::Int
) 
 225     unsafe fn is_lam(self) -> bool 
{ 
 226         self.is_box() && (*self.header
).tag 
== ObjTag
::Lam
 
 229     unsafe fn incref(self) { 
 233         (*self.header
).rc
.fetch_add(1, Ordering
::SeqCst
); 
 236     unsafe fn decref(self) { 
 240         if (*self.header
).rc
.fetch_sub(1, Ordering
::SeqCst
) == 1 { 
 245     unsafe fn dealloc(self) { 
 250             let lam 
= &mut *self.box_lam
; 
 251             for param 
in lam
.params_mut() { 
 254             for upvar 
in lam
.upvars_mut() { 
 258         sys
::free(self.header 
as *mut u8); 
 263     fn size_of(params
: u16, upvars
: u16) -> usize { 
 264         core
::mem
::size_of
::<ObjLam
>() + params 
as usize * 8 + upvars 
as usize * 8 
 267     fn size(&self) -> usize { 
 268         ObjLam
::size_of(self.params
, self.upvars
) 
 271     unsafe fn raw_fields_mut(&mut self) -> *mut Obj 
{ 
 272         (self as *mut ObjLam
).add(1) as *mut Obj
 
 275     unsafe fn params_mut(&mut self) -> &mut [Obj
] { 
 276         let ptr 
= self.raw_fields_mut(); 
 277         core
::slice
::from_raw_parts_mut(ptr
, self.params 
as usize) 
 280     unsafe fn upvars_mut(&mut self) -> &mut [Obj
] { 
 281         let ptr 
= self.raw_fields_mut().add(self.params 
as usize); 
 282         core
::slice
::from_raw_parts_mut(ptr
, self.upvars 
as usize) 
 
This page took 0.066281 seconds  and 5 git commands  to generate.