#include "inc/priv.h"#include "inc/cvalues.h"#include "inc/equal.h"#include "inc/types.h" sl_type *get_type(sl_v t, usize sz){ sl_type *ft; if(issym(t)){ ft = (sl_type*)ptr(sl_sym, t)->type; if(ft != nil) return ft; } void **bp = equalhash_bp(slvm.types, (void*)t); if(*bp != HT_NOTFOUND){ assert(*bp != nil); return *bp; } bool isarr = iscons(t) && car_(t) == sl_arrsym && iscons(cdr_(t)); if(sz == 0){ if(isarr && !iscons(cdr_(cdr_(t)))) // special case: incomplete array type sz = 0; else sz = ctype_sizeof(t); } if((ft = MEM_CALLOC(1, sizeof(sl_type))) == nil) cthrow(error(sl_errmem, "no memory for a type"), t); ft->type = t; ft->numtype = T_NONNUMERIC; if(issym(t)){ ft->numtype = sym_numtype(t); assert(valid_numtype(ft->numtype) || t == sl_runesym); ptr(sl_sym, t)->type = ft; } ft->size = sz; if(isarr && iscons(t)){ sl_type *eltype = get_type(car_(cdr_(t)), 0); assert(eltype != nil && eltype->size > 0); ft->elsz = eltype->size; ft->eltype = eltype; ft->init = cvalue_arr_init; //eltype->artype = ft; -- this is a bad idea since some types carry array sizes } *bp = ft; return ft;} const sl_type *get_arr_type(sl_v eltype){ sl_type *et = get_type(eltype, 0); if(et->artype == nil) cthrow(type_error("eltype", "c type", eltype), eltype); return et->artype;} const sl_type *define_opaque_type(sl_v sym, usize sz, sl_cvtable *vtab, sl_cvinitfn init){ sl_type *ft = MEM_CALLOC(1, sizeof(sl_type)); if(ft == nil) cthrow(error(sl_errmem, "no memory for an opaque type"), sym); ft->type = sym; ft->numtype = T_NONNUMERIC; ft->size = sz; ft->vtable = vtab; ft->init = init; return ft;} voidrelocate_typetable(void){ sl_htable *h = slvm.types; for(usize i = 0; i < h->size; i += 2){ if(sl_unlikely(h->table[i] != HT_NOTFOUND)){ void *nv = (void*)sl_relocate((sl_v)h->table[i]); h->table[i] = nv; if(h->table[i+1] != HT_NOTFOUND) ((sl_type*)h->table[i+1])->type = (sl_v)nv; } }}
#include "inc/priv.h"
#include "inc/cvalues.h"
#include "inc/equal.h"
#include "inc/types.h"
sl_type *
get_type(sl_v t, usize sz)
{
sl_type *ft;
if(issym(t)){
ft = (sl_type*)ptr(sl_sym, t)->type;
if(ft != nil)
return ft;
}
void **bp = equalhash_bp(slvm.types, (void*)t);
if(*bp != HT_NOTFOUND){
assert(*bp != nil);
return *bp;
}
bool isarr = iscons(t) && car_(t) == sl_arrsym && iscons(cdr_(t));
if(sz == 0){
if(isarr && !iscons(cdr_(cdr_(t))))
// special case: incomplete array type
sz = 0;
else
sz = ctype_sizeof(t);
}
if((ft = MEM_CALLOC(1, sizeof(sl_type))) == nil)
cthrow(error(sl_errmem, "no memory for a type"), t);
ft->type = t;
ft->numtype = T_NONNUMERIC;
if(issym(t)){
ft->numtype = sym_numtype(t);
assert(valid_numtype(ft->numtype) || t == sl_runesym);
ptr(sl_sym, t)->type = ft;
}
ft->size = sz;
if(isarr && iscons(t)){
sl_type *eltype = get_type(car_(cdr_(t)), 0);
assert(eltype != nil && eltype->size > 0);
ft->elsz = eltype->size;
ft->eltype = eltype;
ft->init = cvalue_arr_init;
//eltype->artype = ft; -- this is a bad idea since some types carry array sizes
}
*bp = ft;
return ft;
}
const sl_type *
get_arr_type(sl_v eltype)
{
sl_type *et = get_type(eltype, 0);
if(et->artype == nil)
cthrow(type_error("eltype", "c type", eltype), eltype);
return et->artype;
}
const sl_type *
define_opaque_type(sl_v sym, usize sz, sl_cvtable *vtab, sl_cvinitfn init)
{
sl_type *ft = MEM_CALLOC(1, sizeof(sl_type));
if(ft == nil)
cthrow(error(sl_errmem, "no memory for an opaque type"), sym);
ft->type = sym;
ft->numtype = T_NONNUMERIC;
ft->size = sz;
ft->vtable = vtab;
ft->init = init;
return ft;
}
void
relocate_typetable(void)
{
sl_htable *h = slvm.types;
for(usize i = 0; i < h->size; i += 2){
if(sl_unlikely(h->table[i] != HT_NOTFOUND)){
void *nv = (void*)sl_relocate((sl_v)h->table[i]);
h->table[i] = nv;
if(h->table[i+1] != HT_NOTFOUND)
((sl_type*)h->table[i+1])->type = (sl_v)nv;
}
}
}