factor/native/alien.c

165 lines
3.7 KiB
C
Raw Normal View History

2005-04-09 18:30:46 -04:00
#include "factor.h"
/* test if alien is no longer valid (it survived an image save/load) */
2005-06-28 23:50:23 -04:00
void primitive_expired(void)
{
CELL object = dpeek();
if(type_of(object) == ALIEN_TYPE)
{
ALIEN *alien = untag_alien_fast(object);
2005-06-28 23:50:23 -04:00
drepl(tag_boolean(alien->expired));
}
2006-02-09 22:11:22 -05:00
else if(object == F)
drepl(T);
2005-06-28 23:50:23 -04:00
else
drepl(F);
}
/* gets the address of an object representing a C pointer */
void *alien_offset(CELL object)
2005-04-09 18:30:46 -04:00
{
ALIEN *alien;
F_ARRAY *array;
switch(type_of(object))
{
case BYTE_ARRAY_TYPE:
array = untag_byte_array_fast(object);
return array + 1;
2005-04-09 18:30:46 -04:00
case ALIEN_TYPE:
alien = untag_alien_fast(object);
if(alien->expired)
2006-02-07 19:09:46 -05:00
general_error(ERROR_EXPIRED,object,true);
return alien_offset(alien->alien) + alien->displacement;
2005-09-03 14:48:25 -04:00
case F_TYPE:
return NULL;
2005-04-09 18:30:46 -04:00
default:
type_error(ALIEN_TYPE,object);
return (void*)-1; /* can't happen */
}
}
/* pop an object representing a C pointer */
void *unbox_alien(void)
2005-04-09 18:30:46 -04:00
{
return alien_offset(dpop());
}
2006-02-13 22:20:39 -05:00
/* pop ( alien n ) from datastack, return alien's address plus n */
INLINE void *alien_pointer(void)
{
F_FIXNUM offset = unbox_signed_cell();
return unbox_alien() + offset;
}
/* make an alien */
ALIEN *make_alien(CELL delegate, CELL displacement)
2005-04-09 18:30:46 -04:00
{
ALIEN *alien = allot_object(ALIEN_TYPE,sizeof(ALIEN));
alien->alien = delegate;
alien->displacement = displacement;
2005-04-09 18:30:46 -04:00
alien->expired = false;
return alien;
}
/* make an alien and push */
void box_alien(CELL ptr)
{
if(ptr == 0)
2006-01-09 21:17:58 -05:00
dpush(F);
else
dpush(tag_object(make_alien(F,ptr)));
2005-04-09 18:30:46 -04:00
}
/* make an alien pointing at an offset of another alien */
2005-04-09 18:30:46 -04:00
void primitive_displaced_alien(void)
{
CELL alien;
CELL displacement;
maybe_gc(sizeof(ALIEN));
2005-04-09 18:30:46 -04:00
alien = dpop();
displacement = unbox_unsigned_cell();
if(alien == F && displacement == 0)
dpush(F);
else
dpush(tag_object(make_alien(alien,displacement)));
2005-04-09 18:30:46 -04:00
}
/* address of an object representing a C pointer */
2005-04-09 18:30:46 -04:00
void primitive_alien_address(void)
{
box_unsigned_cell((CELL)alien_offset(dpop()));
}
/* convert C string at address to Factor string */
void primitive_alien_to_string(void)
{
maybe_gc(0);
drepl(tag_object(from_c_string(alien_offset(dpeek()))));
}
/* convert Factor string to C string allocated in the Factor heap */
void primitive_string_to_alien(void)
{
2006-03-09 01:44:17 -05:00
CELL string, type;
maybe_gc(0);
2006-03-09 01:44:17 -05:00
string = dpeek();
type = type_of(string);
if(type != ALIEN_TYPE && type != BYTE_ARRAY_TYPE && type != F_TYPE)
drepl(tag_object(string_to_alien(untag_string(string),true)));
}
/* image loading */
void fixup_alien(ALIEN *d)
2005-04-09 18:30:46 -04:00
{
data_fixup(&d->alien);
d->expired = true;
2005-04-09 18:30:46 -04:00
}
/* GC */
void collect_alien(ALIEN *d)
2005-04-09 18:30:46 -04:00
{
2005-05-12 01:02:39 -04:00
copy_handle(&d->alien);
2005-04-09 18:30:46 -04:00
}
/* define words to read/write numericals values at an alien address */
2005-04-09 18:30:46 -04:00
#define DEF_ALIEN_SLOT(name,type,boxer) \
void primitive_alien_##name (void) \
{ \
box_##boxer (*(type*)alien_pointer()); \
} \
void primitive_set_alien_##name (void) \
{ \
type* ptr = alien_pointer(); \
type value = unbox_##boxer(); \
2005-04-09 18:30:46 -04:00
*ptr = value; \
}
2005-12-04 22:29:55 -05:00
DEF_ALIEN_SLOT(signed_cell,F_FIXNUM,signed_cell)
2005-04-09 18:30:46 -04:00
DEF_ALIEN_SLOT(unsigned_cell,CELL,unsigned_cell)
DEF_ALIEN_SLOT(signed_8,s64,signed_8)
DEF_ALIEN_SLOT(unsigned_8,u64,unsigned_8)
DEF_ALIEN_SLOT(signed_4,s32,signed_4)
DEF_ALIEN_SLOT(unsigned_4,u32,unsigned_4)
DEF_ALIEN_SLOT(signed_2,s16,signed_2)
DEF_ALIEN_SLOT(unsigned_2,u16,unsigned_2)
DEF_ALIEN_SLOT(signed_1,BYTE,signed_1)
DEF_ALIEN_SLOT(unsigned_1,BYTE,unsigned_1)
2005-05-05 03:12:37 -04:00
DEF_ALIEN_SLOT(float,float,float)
DEF_ALIEN_SLOT(double,double,double)
/* for FFI calls passing structs by value */
void unbox_value_struct(void *dest, CELL size)
{
memcpy(dest,unbox_alien(),size);
}
2006-03-10 22:16:46 -05:00
/* for FFI callbacks receiving structs by value */
void box_value_struct(void *src, CELL size)
{
2006-03-11 03:26:55 -05:00
F_ARRAY *array = byte_array(size);
2006-03-10 22:16:46 -05:00
memcpy(array + 1,src,size);
dpush(tag_object(array));
}