]>
Witch of Git - ivy/blob - rt/src/lam.rs
1 use crate::{sys
, trace
, Obj
, ObjHeader
, ObjTag
};
2 use std
::sync
::atomic
::AtomicU32
;
10 func
: extern "C" fn(&ObjLam
) -> Obj
,
16 pub unsafe extern "C" fn ivy_check_lam(obj
: Obj
) {
17 if obj
.tag() != Some(ObjTag
::Lam
) {
19 "ivy_check_lam called with non-lambda object {:016x}.",
26 pub unsafe extern "C" fn ivy_make_lam(
27 func
: extern "C" fn(&ObjLam
) -> Obj
,
31 let size
= ObjLam
::size_of(params
, upvars
);
32 let box_lam
= sys
::malloc(size
) as *mut ObjLam
;
33 box_lam
.write(ObjLam
{
37 rc
: AtomicU32
::new(1),
44 .write_bytes(0, (params
+ upvars
) as usize);
45 trace
!("MAKE {:016x} {:016x}", box_lam
as usize, func
as usize);
50 pub unsafe extern "C" fn ivy_clone_lam(lam
: &ObjLam
) -> *mut ObjLam
{
51 let size
= lam
.size();
52 let data
= sys
::malloc(size
);
53 core
::ptr
::copy(lam
as *const _
as *const u8, data
, size
);
54 let box_hdr
= data
as *mut ObjHeader
;
55 *(*box_hdr
).rc
.get_mut() = 1;
57 "COPY {:016x} {:016x}",
58 lam
as *const _
as usize,
65 pub unsafe extern "C" fn ivy_app(fun
: Obj
, arg
: Obj
) -> Obj
{
66 ivy_app_mut(crate::ivy_clone(fun
), arg
)
70 pub unsafe extern "C" fn ivy_app_mut(fun
: Obj
, arg
: Obj
) -> Obj
{
71 trace
!("APP {:016x} {:016x}", fun
.int
, arg
.int
);
72 if fun
.tag() != Some(ObjTag
::Lam
) {
74 "ivy_app called with a non-lam as the function: {:016x}.",
78 let lam
= &mut *fun
.box_lam
;
79 if lam
.filled
< lam
.params
{
82 "Lam @ {:016x} ({:016x}) has {} of {} arguments filled.",
83 fun
.int
, lam
.func
as usize, lam
.filled
, lam
.params
85 panic
!("ivy_app called with a null arg.");
88 let idx
= lam
.filled
as usize;
89 lam
.params_mut()[idx
] = arg
;
91 } else if lam
.params
== lam
.filled
{
93 panic
!("ivy_app called for a 0-arity application with a non-null arg.");
97 if lam
.params
== lam
.filled
{
98 trace
!("RUN {:016x}", fun
.int
);
101 trace
!("UPD8 {:016x}", fun
.int
);
107 pub(crate) fn size_of(params
: u16, upvars
: u16) -> usize {
108 let obj_size
= core
::mem
::size_of
::<Obj
>();
109 core
::mem
::size_of
::<ObjLam
>() + params
as usize * obj_size
+ upvars
as usize * obj_size
112 pub(crate) fn size(&self) -> usize {
113 ObjLam
::size_of(self.params
, self.upvars
)
116 fn raw_fields_mut(&self) -> *mut Obj
{
117 unsafe { (self as *const ObjLam
).add(1) as *mut Obj
}
120 unsafe fn params_mut(&mut self) -> &mut [Obj
] {
121 let ptr
= self.raw_fields_mut();
122 core
::slice
::from_raw_parts_mut(ptr
, self.params
as usize)
125 pub(crate) fn params(&self) -> &[Obj
] {
126 let ptr
= self.raw_fields_mut();
127 unsafe { core
::slice
::from_raw_parts(ptr
, self.params
as usize) }
130 pub(crate) fn upvars(&self) -> &[Obj
] {
132 let ptr
= self.raw_fields_mut().add(self.params
as usize);
133 core
::slice
::from_raw_parts(ptr
, self.upvars
as usize)