Sigrid Solveig Haflínudóttirremove plain-old-data? (unused)453b03d1 year agoHistory
1560 lines · 34.9 KB · C
RawDownload
#include "sl.h"#include "operators.h"#include "cvalues.h"#include "types.h"#include "io.h"#include "equal.h" enum {	MAX_INL_SIZE = 384,	CVALUE_NWORDS = sizeof(sl_cv)/sizeof(sl_v), 	CV_OWNED = 1<<0,}; #define owned(cv) ((uintptr)(cv)->type & CV_OWNED) sl_type notype = {0};sl_type *unboxedtypes[T_UNBOXED_NUM];sl_v unboxedtypesyms[T_UNBOXED_NUM]; static void cvalue_init(sl_type *type, sl_v v, void *dest); voidadd_finalizer(sl_cv *cv){	if(slvm.nfinalizers == slvm.maxfinalizers){		slvm.maxfinalizers *= 2;		slvm.finalizers = MEM_REALLOC(slvm.finalizers, slvm.maxfinalizers*sizeof(slvm.finalizers));		assert(slvm.finalizers != nil);	}	slvm.finalizers[slvm.nfinalizers++] = cv;} voidsweep_cv(sl_cv *cv){	sl_type *t = cv_class(cv);	if(t->vtable != nil && t->vtable->finalize != nil)		t->vtable->finalize(tagptr(cv, TAG_CVALUE));	if(!isinlined(cv) && owned(cv)){		MEM_FREE(cv_data(cv));	}	cv->type = &notype;} // remove dead objects from finalization list in-placevoidsweep_finalizers(void){	sl_cv **lst = slvm.finalizers;	usize n = 0, ndel = 0, l = slvm.nfinalizers;	sl_cv *tmp;#define SWAP_sf(a, b) (tmp = a, a = b, b = tmp, 1)	if(l == 0)		return;	do{		tmp = lst[n];		if(isforwarded((sl_v)tmp)){			// object is alive			lst[n] = ptr(forwardloc((sl_v)tmp));			n++;		}else{			sweep_cv(tmp);			ndel++;		}	}while((n < l-ndel) && SWAP_sf(lst[n], lst[n+ndel])); 	slvm.nfinalizers -= ndel;	slvm.malloc_pressure = 0;} // compute the size of the metadata object for a cvaluestatic usizecv_nwords(sl_cv *cv){	if(!isinlined(cv))		return CVALUE_NWORDS;	usize n = cv_len(cv);	if(cv_isstr(cv))		n++;	return CVALUE_NWORDS + NWORDS(n);} voidcv_autorelease(sl_cv *cv){	cv->type = (sl_type*)(((uintptr)cv->type) | CV_OWNED);	add_finalizer(cv);} voidcvalue_cutdown(sl_v cv, usize nb){	sl_cv *pcv = ptr(cv);	bool isstr = cv_isstr(pcv);	if(isinlined(pcv))		pcv->len = nb;	else		pcv->data = MEM_REALLOC(pcv->data, nb+(isstr ? 1 : 0));	if(isstr)		((char*)pcv->data)[nb] = 0;} sl_vcvalue_(sl_type *type, usize sz, bool nofinalize){	assert(type != nil); 	bool str = false;	if(type->eltype == sl_utf8type){		if(sz == 0)			return sl_emptystr;		sz++;		str = true;	}	sl_cv *pcv;	if(sz <= MAX_INL_SIZE){		usize nw = CVALUE_NWORDS + NWORDS(sz);		pcv = alloc_words(nw);		pcv->type = type;		pcv->data = pcv->_space;		if(!nofinalize && type->vtable != nil && type->vtable->finalize != nil)			add_finalizer(pcv);	}else{		if(slvm.malloc_pressure > ALLOC_LIMIT_TRIGGER)			sl_gc(false);		pcv = alloc_words(CVALUE_NWORDS);		pcv->type = type;		pcv->data = MEM_ALLOC(sz);		cv_autorelease(pcv);		slvm.malloc_pressure += sz;	}	if(str){		((char*)pcv->data)[--sz] = '\0';		if(!isinlined(pcv)){			pcv->startbytes = 0;			pcv->startrune = 0;		}	}	pcv->len = sz;	return tagptr(pcv, TAG_CVALUE);} // this effectively dereferences a pointer// just like *p in C, it only removes a level of indirection from the type,// it doesn't copy any data.// this method of creating a cvalue only allocates metadata.// ptr is user-managed; we don't autorelease it unless the// user explicitly calls (autorelease ) on the result of this function.// 'parent' is an optional cvalue that this pointer is known to point// into; NIL if none.sl_vcvalue_from_ref(sl_type *type, void *ptr, usize sz){	sl_cv *pcv; 	assert(type != nil);	assert(ptr != nil);	pcv = alloc_words(CVALUE_NWORDS);	pcv->data = ptr;	pcv->len = sz;	pcv->type = type;	pcv->startbytes = 0;	pcv->startrune = 0;	return tagptr(pcv, TAG_CVALUE);} sl_vcvalue_str(usize sz){	if(sz == 0)		return sl_emptystr;	return cvalue(sl_strtype, sz);} sl_vcvalue_static_cstr(const char *str){	if(*str == 0)		return sl_emptystr;	return cvalue_from_ref(sl_strtype, (char*)str, strlen(str));} sl_vstr_from_cstrn(char *str, usize n){	sl_v v = cvalue_str(n);	memcpy(cvalue_data(v), str, n);	return v;} sl_vstr_from_cstr(char *str){	return str_from_cstrn(str, strlen(str));} boolisstr(sl_v v){	return iscvalue(v) && cv_isstr(ptr(v));} // convert to malloc representation (fixed address)voidcv_pin(sl_cv *cv){	if(!isinlined(cv))		return;	usize sz = cv_len(cv);	if(cv_isstr(cv))		sz++;	void *data = MEM_ALLOC(sz);	memcpy(data, cv_data(cv), sz);	cv->data = data;	cv_autorelease(cv);} static voidcvalue_rune_init(sl_type *type, sl_v a, void *dest){	Rune r;	USED(type);	if(isfixnum(a))		r = numval(a);	else if(isrune(a))		r = torune(a);	else if(iscvalue(a))		r = conv_to_u32(a, cv_data(ptr(a)), cv_numtype(ptr(a)));	else if(isubnum(a)){		sl_fx v = ubnumval(a);		sl_numtype nt = ubnumtype(a);		r = conv_to_u32(a, ubnumptr(v, nt), nt);	}else		cthrow(type_error(nil, "num", a), type);	if(r >= 0xd800 && r <= 0xdfff)		cthrow(lerrorf(sl_errarg, "invalid rune: utf-16 surrogate pair: 0x%"PRIx32, (u32int)r), type);	if(r > 0x10ffff)		cthrow(lerrorf(sl_errarg, "invalid rune: outside of valid range: 0x%"PRIx32, (u32int)r), type);	*((Rune*)dest) = r;} #define num_init(ctype, cnvt, tag) \	static void \	cvalue_##ctype##_init(sl_type *type, sl_v a, void *dest) \	{ \		ctype n; \		USED(type); \		if(isfixnum(a)){ \			n = (ctype)numval(a); \		}else if(isubnum(a)){ \			sl_fx v = ubnumval(a); \			sl_numtype nt = ubnumtype(a); \			n = (ctype)conv_to_##cnvt(a, ubnumptr(v, nt), nt); \		}else if(iscvalue(a)){ \			n = (ctype)conv_to_##cnvt(a, cv_data(ptr(a)), cv_numtype(ptr(a))); \		}else \			cthrow(type_error(nil, "num", a), type); \		*((ctype*)dest) = n; \	} typedef u32int u32ptr;typedef u64int u64ptr;typedef float f32;typedef double f64; num_init(s8int, s32, T_S8)num_init(u8int, u32, T_U8)num_init(s16int, s32, T_S16)num_init(u16int, u32, T_U16)num_init(s32int, s32, T_S32)num_init(u32int, u32, T_U32)num_init(s64int, s64, T_S64)num_init(u64int, u64, T_U64)num_init(u32ptr, p32, T_P32)num_init(u64ptr, p64, T_P64)num_init(f32, double, T_F32)num_init(f64, double, T_F64) sl_purefnBUILTIN("rune", rune){	if(nargs == 0){		PUSH(fixnum(Runeerror));		args = sl.sp-1;	}else		argcount(nargs, 1);	Rune r;	cvalue_rune_init(sl_runetype, args[0], &r);	return mk_rune(r);} #define num_ctor_init(typenam, ctype, tag) \	static \	BUILTIN(#typenam, typenam) \	{ \		if(nargs == 0){ \			PUSH(fixnum(0)); \			args = sl.sp-1; \		}else \			argcount(nargs, 1); \		sl_v v = cvalue(sl_##typenam##type, sizeof(ctype)); \		cvalue_##ctype##_init(sl_##typenam##type, args[0], cvalue_data(v)); \		return v; \	} #define num_ctor_init_unboxed(typenam, ctype, tag) \	static \	BUILTIN(#typenam, typenam) \	{ \		if(nargs == 0){ \			PUSH(fixnum(0)); \			args = sl.sp-1; \		}else \			argcount(nargs, 1); \		sl_v v; \		ctype n; \		cvalue_##ctype##_init(sl_##typenam##type, args[0], &n); \		if(tag < T_UNBOXED_NUM && \		   (sizeof(n) < sizeof(sl_fx) || (sizeof(n) == sizeof(sl_fx) && fits_bits(n, UNBOXED_BITS-1)))){ \			v = (sl_v)n<<TAG_EXT_BITS | tag<<TAG_UBNUM_SHIFT | TAG_UNBOXED; \		}else{ \			v = cvalue(sl_##typenam##type, sizeof(n)); \			*(ctype*)cvalue_data(v) = n; \		} \		return v; \	} #define num_ctor_ctor(typenam, ctype, tag) \	sl_v \	mk_##typenam(ctype n) \	{ \		sl_v v = cvalue(sl_##typenam##type, sizeof(n)); \		*(ctype*)cvalue_data(v) = n; \		return v; \	} #define num_ctor_ctor_unboxed(typenam, ctype, tag) \	sl_v \	mk_##typenam(ctype n) \	{ \		sl_v v; \		if(tag < T_UNBOXED_NUM && \		   (sizeof(n) < sizeof(sl_fx) || (sizeof(n) == sizeof(sl_fx) && fits_bits(n, UNBOXED_BITS-1)))){ \			v = (sl_v)n<<TAG_EXT_BITS | tag<<TAG_UBNUM_SHIFT | TAG_UNBOXED; \		}else{ \			v = cvalue(sl_##typenam##type, sizeof(n)); \			*(ctype*)cvalue_data(v) = n; \		} \		return v; \	} #define num_ctor(typenam, ctype, tag) \	num_ctor_ctor(typenam, ctype, tag) \	num_ctor_init(typenam, ctype, tag) \ #define num_ctor_unboxed(typenam, ctype, tag) \	num_ctor_ctor_unboxed(typenam, ctype, tag) \	num_ctor_init_unboxed(typenam, ctype, tag) \ #if defined(BITS64)#define sl_constfn64 sl_constfn#else#define sl_constfn64#endif sl_constfn num_ctor_unboxed(s8, s8int, T_S8)sl_constfn num_ctor_unboxed(u8, u8int, T_U8)sl_constfn num_ctor_unboxed(s16, s16int, T_S16)sl_constfn num_ctor_unboxed(u16, u16int, T_U16)sl_constfn64 num_ctor_unboxed(s32, s32int, T_S32)sl_constfn64 num_ctor_unboxed(u32, u32int, T_U32)sl_constfn64 num_ctor_unboxed(p32, u32ptr, T_P32)num_ctor_unboxed(s64, s64int, T_S64)num_ctor_unboxed(u64, u64int, T_U64)num_ctor_unboxed(p64, u64ptr, T_P64)num_ctor(f32, f32, T_F32)num_ctor(f64, f64, T_F64) static voidcvalue_bignum_init(sl_type *type, sl_v a, void *dest){	mpint *n;	USED(type);	if(isfixnum(a))		n = vtomp(numval(a), nil);	else if(isubnum(a)){		sl_fx v = ubnumval(a);		sl_numtype nt = ubnumtype(a);		n = conv_to_bignum(a, ubnumptr(v, nt), nt);	}else if(iscvalue(a)){		sl_cv *cv = ptr(a);		void *p = cv_data(cv);		n = conv_to_bignum(a, p, cv_numtype(cv));	}else		cthrow(type_error(nil, "num", a), type);	*((mpint**)dest) = n;} BUILTIN("bignum", bignum){	if(nargs == 0){		PUSH(fixnum(0));		args = sl.sp-1;	}else		argcount(nargs, 1);	sl_v cv = cvalue(sl_bignumtype, sizeof(mpint*));	cvalue_bignum_init(sl_bignumtype, args[0], cvalue_data(cv));	return cv;}  sl_vmk_bignum(mpint *n){	sl_v cv = cvalue(sl_bignumtype, sizeof(mpint*));	*(mpint**)cvalue_data(cv) = n;	return cv;} static voidfree_bignum(sl_v self){	mpint **s = value2c(mpint**, self);	if(*s != mpzero && *s != mpone && *s != mptwo)		mpfree(*s);} static sl_cvtable bignum_vtable = { nil, nil, free_bignum, nil, nil }; sl_constfnsl_vsize_wrap(usize sz){	if(sizeof(usize) == 8)		return fits_fixnum(sz) ? fixnum(sz): mk_u64(sz);	else		return fits_fixnum(sz) ? fixnum(sz): mk_u32(sz);} usizetosize(sl_v n){	if(sl_unlikely(iscvalue(n))){		if(sl_likely(numeric_compare(n, fixnum(0), false, true) >= 0)){			sl_cv *cv = ptr(n);			if(sizeof(usize) > 4)				return conv_to_u64(n, cv_data(cv), cv_numtype(cv));			return conv_to_u32(n, cv_data(cv), cv_numtype(cv));		}	}else{		sl_fx x;		if(sl_likely(isfixnum(n)))			x = numval(n);		else if(isubnum(n))			x = ubnumval(n);		else			cthrow(type_error(nil, "num", n), n);		if(x >= 0)			return x;	}	cthrow(lerrorf(sl_errarg, "tosize: negative value"), n);} soffsettooffset(sl_v n){	if(isfixnum(n))		return numval(n);	if(isubnum(n))		return ubnumval(n);	if(iscvalue(n)){		sl_cv *cv = ptr(n);		if(sizeof(usize) > 4)			return conv_to_s64(n, cv_data(cv), cv_numtype(cv));		return conv_to_s32(n, cv_data(cv), cv_numtype(cv));	}	cthrow(type_error(nil, "num", n), n);} boolisarr(sl_v v){	return iscvalue(v) && cv_class(ptr(v))->eltype != nil;} static usizepredict_arrlen(sl_v arg){	if(isvec(arg))		return vec_size(arg);	if(iscons(arg))		return llength(arg);	if(arg == sl_nil)		return 0;	if(isarr(arg))		return cvalue_arrlen(arg);	return 1;} 

Lines 1–500 of 1560.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t