]>
Witch of Git - ivy/blob - rt/src/lam.rs
1 use crate::{sys
, trace
, Obj
, 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
) {
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(0),
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_app(fun
: Obj
, arg
: Obj
) -> Obj
{
51 ivy_app_mut(crate::ivy_clone(fun
), arg
)
55 pub unsafe extern "C" fn ivy_app_mut(fun
: Obj
, arg
: Obj
) -> Obj
{
56 trace
!("APP {:016x} {:016x}", fun
.int
, arg
.int
);
59 "ivy_app called with a non-lam as the function: {:016x}.",
63 let lam
= &mut *fun
.box_lam
;
64 if lam
.filled
< lam
.params
{
67 "Lam @ {:016x} ({:016x}) has {} of {} arguments filled.",
68 fun
.int
, lam
.func
as usize, lam
.filled
, lam
.params
70 panic
!("ivy_app called with a null arg.");
73 let idx
= lam
.filled
as usize;
74 lam
.params_mut()[idx
] = arg
;
76 } else if lam
.params
== lam
.filled
{
78 panic
!("ivy_app called for a 0-arity application with a non-null arg.");
82 if lam
.params
== lam
.filled
{
83 trace
!("RUN {:016x}", fun
.int
);
86 trace
!("UPD8 {:016x}", fun
.int
);
93 pub(crate) fn size_of(params
: u16, upvars
: u16) -> usize {
94 core
::mem
::size_of
::<ObjLam
>() + params
as usize * 8 + upvars
as usize * 8
97 pub(crate) fn size(&self) -> usize {
98 ObjLam
::size_of(self.params
, self.upvars
)
101 pub(crate) unsafe fn raw_fields_mut(&mut self) -> *mut Obj
{
102 (self as *mut ObjLam
).add(1) as *mut Obj
105 pub(crate) unsafe fn params_mut(&mut self) -> &mut [Obj
] {
106 let ptr
= self.raw_fields_mut();
107 core
::slice
::from_raw_parts_mut(ptr
, self.params
as usize)
110 pub(crate) unsafe fn upvars_mut(&mut self) -> &mut [Obj
] {
111 let ptr
= self.raw_fields_mut().add(self.params
as usize);
112 core
::slice
::from_raw_parts_mut(ptr
, self.upvars
as usize)