Sigrid Solveig Haflínudóttirindentation fixe85fcbf2 months agoHistory
1213 lines · 19.1 KB · C
RawDownload
#include "inc/priv.h"#include "inc/equal.h"#include "inc/cvalues.h"#include "inc/io.h" #define OP_ARGS \	int nargs, const u8int *ip, usize top_frame, usize obp, \	usize ipd, int n, bool tail #if __has_attribute(musttail)#define sl_musttail __attribute__((musttail))#else#define sl_musttail#endif #if __has_attribute(preserve_none)#define sl_preserve_less __attribute__((preserve_none))#elif __has_attribute(preserve_most)#define sl_preserve_less __attribute__((preserve_most))#else#define sl_preserve_less#endif #define CALL_OP(op) \	sl_musttail \	return op(nargs, ip, top_frame, obp, ipd, n, tail) #define MAKE_OP(name) \	sl_preserve_less \	static sl_v op_##name(OP_ARGS) typedef sl_v (*op_func)(OP_ARGS) sl_preserve_less; extern const op_func sl_ops[]; #define NEXT_OP do{ \	ip++; \	CALL_OP(sl_ops[ip[-1]]); \}while(0) #define ENTER do{ \	sl.stack[ipd] = (uintptr)ip; \}while(0) static sl_v op_CALL_(OP_ARGS) sl_preserve_less; MAKE_OP(LT_){	int i = n;	sl_v a = sl.sp[-i], b, v;	for(v = sl_t; i > 1; a = b){		i--;		b = sl.sp[-i];		if(sl_likely(bothfixnums(a, b))){			if((sl_fx)a >= (sl_fx)b){				v = sl_nil;				break;			}		}else{			int x = numeric_compare(a, b, false);			if(x > 1)				x = numval(sl_compare(a, b, false));			if(sl_unlikely(x >= 0)){				v = sl_nil;				break;			}		}	}	POPN(n);	PUSH(v);	NEXT_OP;} MAKE_OP(LT){	n = *ip++;	CALL_OP(op_LT_);} MAKE_OP(LIST_){	ENTER;	sl_v v = sl_list(sl.sp-n, n, false);	POPN(n);	PUSH(v);	NEXT_OP;} MAKE_OP(LIST){	n = *ip++;	CALL_OP(op_LIST_);} MAKE_OP(VEC_){	ENTER;	sl_v v;	if(sl.sp[-n] == sl_vecstructsym){		if(sl_unlikely(n < 2))			cthrow(arity_error(n, 2, sl_minsym), nargs);		v = alloc_vec(n-1, false);		vec_setsize(v, vec_size(v), VEC_STRUCT);		for(int i = 0; i < n-1; i++)			vec_elt(v, i) = sl.sp[-n+1+i];	}else{		v = alloc_vec(n, false);		for(int i = 0; i < n; i++)			vec_elt(v, i) = sl.sp[-n+i];	}	POPN(n);	PUSH(v);	NEXT_OP;} MAKE_OP(VEC){	n = *ip++;	CALL_OP(op_VEC_);} MAKE_OP(ADD_){	ENTER;	sl_v v = sl_add_any(sl.sp-n, n);	POPN(n);	PUSH(v);	NEXT_OP;} MAKE_OP(ADD){	n = *ip++;	CALL_OP(op_ADD_);} MAKE_OP(APPLY_){	sl_v v = POP(); // arglist	n -= 2; // n-2 == # leading arguments not in the list	if(v == sl_nil || iscons(v)){		while(iscons(v)){			n++;			PUSH_SAFE(car_(v));			v = cdr_(v);		}		if(sl_unlikely(v != sl_nil)){			ENTER;			cthrow(type_error("apply", "null", v), nargs);		}	}else if(isvec(v)){		usize s = vec_size(v);		stack_for(s);		memcpy(sl.sp, &vec_elt(v, 0), s*sizeof(sl_v));		sl.sp += s;		n += s;	}else{		ENTER;		cthrow(type_error("apply", "(or list vec)", v), nargs);	}	CALL_OP(op_CALL_);} MAKE_OP(TAPPLY){	n = *ip++;	tail = true;	CALL_OP(op_APPLY_);} MAKE_OP(APPLY){	n = *ip++;	tail = false;	CALL_OP(op_APPLY_);} MAKE_OP(SUB2){	sl_fx a, b, q;	sl_v v;	ENTER;	v = sl.sp[-1];	s64int i64;	b = isfixnum(v) ? fixnum_neg(v) : sl_neg(v);	a = sl.sp[-2];	if(sl_likely(bothfixnums(a, b) && !sadd_overflow(a, b, &q)))		v = q;	else{		sl.sp[-1] = b;		v = sl_add_any(sl.sp-2, 2);	}	POPN(1);	sl.sp[-1] = v;	NEXT_OP;} MAKE_OP(ADD2){	sl_fx a, b, q;	sl_v v;	ENTER;	b = sl.sp[-1];	a = sl.sp[-2];	if(sl_likely(bothfixnums(a, b) && !sadd_overflow(a, b, &q)))		v = q;	else{		sl.sp[-1] = b;		v = sl_add_any(sl.sp-2, 2);	}	POPN(1);	sl.sp[-1] = v;	NEXT_OP;} MAKE_OP(SUB_){	if(n == 2)		CALL_OP(op_SUB2);	assert(n != 1);	ENTER;	sl_v *p = sl.sp-n;	// we need to pass the full arglist on to sl_add_any	// so it can handle rest args properly	PUSH(*p);	*p = fixnum(0);	sl_v v = sl_add_any(p, n);	s64int i64;	p[1] = isfixnum(v) ? fixnum_neg(v) : sl_neg(v);	p[0] = POP();	v = sl_add_any(p, 2);	POPN(n);	PUSH(v);	NEXT_OP;} MAKE_OP(SUB){	n = *ip++;	CALL_OP(op_SUB_);} MAKE_OP(MUL_){	ENTER;	sl_v v = sl_mul_any(sl.sp-n, n);	POPN(n);	PUSH(v);	NEXT_OP;} MAKE_OP(MUL){	n = *ip++;	CALL_OP(op_MUL_);} MAKE_OP(DIV_){	ENTER;	sl_v *p = sl.sp-n;	if(sl_unlikely(n == 1)){		sl.sp[-1] = sl_div2(fixnum(1), *p);	}else{		if(sl_unlikely(n > 2)){			PUSH(*p);			*p = fixnum(1);			p[1] = sl_mul_any(p, n);			*p = POP();		}		sl_v v = sl_div2(p[0], p[1]);		POPN(n);		PUSH(v);	}	NEXT_OP;} MAKE_OP(DIV){	n = *ip++;	CALL_OP(op_DIV_);} MAKE_OP(AREF_){	sl_v v = sl.sp[-n];	for(int i = n-1; i > 0; i--){		sl_v e = sl.sp[-i];		usize isz = tosize(e);		if(sl_unlikely(isarr(v))){			sl.sp[-i-1] = v;			v = cvalue_arr_aref(sl.sp-i-1);			continue;		}		if(isvec(v)){			if(sl_unlikely(isz >= (usize)vec_size(v)))				cthrow(bounds_error(v, e), nargs);			v = vec_elt(v, isz);			continue;		}		if(sl_unlikely(!iscons(v))){			if(isio(v)){				ios *s = toio(v, true, true, false);				if(sl_unlikely(s->bm != IOS_BUF_MEM))					cthrow(error(sl_errarg, "requires in-memory io"), nargs);				if(isz >= s->size)					cthrow(bounds_error(v, e), nargs);				v = mk_u8(s->buf[isz]);				continue;			}else				cthrow(type_error("aref", "sequence", v), nargs);		}		for(sl_v v0 = v;; isz--){			if(isz == 0){				v = car_(v);				break;			}			v = cdr_(v);			if(sl_unlikely(!iscons(v)))				cthrow(bounds_error(v0, e), nargs);		}	}	POPN(n);	PUSH(v);	NEXT_OP;} MAKE_OP(AREF){	n = 3 + *ip++;	CALL_OP(op_AREF_);} MAKE_OP(ASET__){	sl_v v = sl.sp[-3];	sl_v e = sl.sp[-2];	usize isz = tosize(e);	if(sl_likely(isvec(v))){		if(sl_unlikely(isz >= (usize)vec_size(v)))			cthrow(bounds_error(v, e), nargs);		vec_elt(v, isz) = (e = sl.sp[-1]);	}else if(iscons(v)){		for(sl_v v0 = v;; isz--){			if(isz == 0){				car_(v) = (e = sl.sp[-1]);				break;			}			v = cdr_(v);			if(sl_unlikely(!iscons(v)))				cthrow(bounds_error(v0, e), nargs);		}	}else if(isarr(v)){		e = cvalue_arr_aset(sl.sp-3);	}else if(isio(v)){		ios *s = toio(v, true, false, true);		if(sl_unlikely(s->bm != IOS_BUF_MEM))			cthrow(error(sl_errarg, "requires in-memory io"), nargs);		if(isz >= s->size)			cthrow(bounds_error(v, e), nargs);		s->buf[isz] = tou32(sl.sp[-1]);		e = mk_u8(s->buf[isz]);	}else{		cthrow(type_error("aset!", "sequence", v), nargs);	}	POPN(n);	PUSH(e);	NEXT_OP;} MAKE_OP(ASET_){	sl_v v = sl.sp[-n];	for(int i = n-1; i >= 3; i--){		if(sl_unlikely(isarr(v))){			sl.sp[-i-1] = v;			v = cvalue_arr_aref(sl.sp-i-1);			continue;		}		sl_v e = sl.sp[-i];		sl_fx isz = tosize(e);		if(isvec(v)){			if(sl_unlikely(isz >= vec_size(v)))				cthrow(bounds_error(v, e), nargs);			v = vec_elt(v, isz);			continue;		}		if(sl_unlikely(!iscons(v)))			cthrow(type_error("aset!", "sequence", v), nargs);		for(sl_v v0 = v;; isz--){			if(isz == 0){				v = car_(v);				break;			}			v = cdr_(v);			if(sl_unlikely(!iscons(v)))				cthrow(bounds_error(v0, e), nargs);		}	}	sl.sp[-3] = v;	CALL_OP(op_ASET__);} MAKE_OP(ASET){	ENTER;	n = 3;	CALL_OP(op_ASET__);} MAKE_OP(NUMEQP_){	ENTER;	int i = n;	sl_v a = sl.sp[-i], b, v;	for(v = sl_t; i > 1; a = b){		i--;		b = sl.sp[-i];		if(bothfixnums(a, b)){			if(a != b){				v = sl_nil;				break;			}		}else if(numeric_compare(a, b, true) != 0){			v = sl_nil;			break;		}	}	POPN(n);	PUSH(v);	NEXT_OP;} MAKE_OP(CALL_){	ENTER;	sl_v v = sl.sp[-n-1];	if(tag(v) == TAG_FN){		if(sl_likely(!isfnbuiltin(v))){			nargs = n;			if(tail){				sl.curr_frame = sl.stack[sl.curr_frame-3];				for(sl_fx s = -1; s < (sl_fx)n; s++)					sl.stack[obp+s] = sl.sp[s-n];				sl.sp = &sl.stack[obp+n];			}else{				obp = sl.sp-sl.stack-nargs;			}			sl_fn *fn = ptr(sl_fn, sl.stack[obp-1]);			assert(ismanaged(fn));			stack_for(fn->maxstack);			ip = cvalue_data(fn->bcode);			assert(!ismanaged((uintptr)ip));			PUSH(fn->env);			PUSH(sl.curr_frame);			PUSH(nargs);			ipd = sl.sp++ - sl.stack;			sl.curr_frame = ipd + 1;			NEXT_OP;		}		assert(isbuiltin(v));		int i = u32numval(v), s = builtins[i].nargs;		if(n != s && s != ANYARGS && (s >= 0 || n < -s))			cthrow(arity_error(n, s, sl_nil), nargs);		// remove function arg		for(sl_v *p = sl.sp-n-1; p < sl.sp-1; p++)			p[0] = p[1];		POPN(1);		switch(i){		case OP_LT: CALL_OP(op_LT_);		case OP_LIST: CALL_OP(op_LIST_);		case OP_VEC: CALL_OP(op_VEC_);		case OP_ADD: CALL_OP(op_ADD_);		case OP_APPLY: CALL_OP(op_APPLY_);		case OP_SUB: CALL_OP(op_SUB_);		case OP_MUL: CALL_OP(op_MUL_);		case OP_DIV: CALL_OP(op_DIV_);		case OP_AREF: CALL_OP(op_AREF_);		case OP_ASET: CALL_OP(op_ASET_);		case OP_NUMEQP: CALL_OP(op_NUMEQP_);		default:			CALL_OP(sl_ops[i]);		}	}else if(iscbuiltin(v)){		sl_builtinfn f = ptr(sl_cv, v)->cbuiltin;		stack_for(4);		PUSH(sl_nil); // fn->env;		PUSH(sl.curr_frame);		PUSH(n);		PUSH(f); // ip		sl.curr_frame = sl.sp - sl.stack;		v = f(sl.sp-n-4, n);		sl.sp = sl.stack + sl.curr_frame;		sl.curr_frame = sl.sp[-3];		POPN(4+n);		sl.sp[-1] = v;		NEXT_OP;	}	cthrow(type_error(tail ? "tcall" : "call", "fn", v), nargs);}

Lines 1–500 of 1213.

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