ref: 814112a0ab5f9346b3cf765dc25c0e84f4fed36e
parent: a9dacbaed106828e03ca74be373171610fd9d452
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sat Apr 19 21:18:12 EDT 2025
back to fully dynamic stack; fix a few issues along the way
--- a/meson.build
+++ b/meson.build
@@ -391,9 +391,9 @@
test('mp.sl', sl, args: ['mp.sl'], workdir: tests_dir)
test('perf.sl', sl, args: ['perf.sl'], workdir: tests_dir, timeout: -1)
test('tme.sl', sl, args: ['tme.sl'], workdir: tests_dir, timeout: -1)
-test('torture.sl', sl, args: ['-S', '8m', 'torture.sl'], workdir: tests_dir, timeout: -1)
+test('torture.sl', sl, args: ['torture.sl'], workdir: tests_dir, timeout: -1)
test('torus.sl', sl, args: ['torus.sl'], workdir: tests_dir)
-test('unit.sl', sl, args: ['-S', '1m', 'unittest.sl'], workdir: tests_dir)
+test('unit.sl', sl, args: ['unittest.sl'], workdir: tests_dir)
test('defstruct.sl', sl, args: ['defstruct.sl'], workdir: tests_dir)
test('crash.sl', sl, args: ['crash.sl'], workdir: tests_dir)
--- /dev/null
+++ b/src/maxstack.h
@@ -1,0 +1,171 @@
+#if BYTE_ORDER == BIG_ENDIAN
+#undef SWAP_INT32
+#undef SWAP_INT16
+#define SWAP_INT32(a) \
+ do{ \
+ uint8_t *x = (void*)a, y; \
+ y = x[0]; x[0] = x[3]; x[3] = y; \
+ y = x[1]; x[1] = x[2]; x[2] = y; \
+ }while(0)
+#define SWAP_INT16(a) \
+ do{ \
+ uint8_t *x = (void*)a, y; \
+ y = x[0]; x[0] = x[1]; x[1] = y; \
+ }while(0)
+#else
+#define SWAP_INT32(a)
+#define SWAP_INT16(a)
+#endif
+
+sl_purefn
+static int
+compute_maxstack(u8int *code, usize len)
+{
+ u8int *ip = code, *end = code+len;
+ int i, n, sp = 0, maxsp = 0;
+
+ while(ip < end){
+ sl_op op = *ip++;
+ switch(op){
+ case OP_LOADA: case OP_LOADI8: case OP_LOADV: case OP_LOADG:
+ ip++; // fallthrough
+ case OP_LOADA0: case OP_LOADA1:
+ case OP_DUP: case OP_LOADT: case OP_LOADNIL: case OP_LOADVOID:
+ case OP_LOAD0:
+ case OP_LOAD1: case OP_LOADC0:
+ case OP_LOADC1:
+ sp++;
+ break;
+
+ case OP_POP: case OP_RET:
+ case OP_CONS: case OP_SETCAR: case OP_SETCDR:
+ case OP_EQP: case OP_EQVP: case OP_EQUALP: case OP_ADD2: case OP_SUB2:
+ case OP_DIV0: case OP_COMPARE:
+ case OP_AREF2: case OP_TRYCATCH:
+ sp--;
+ break;
+
+ case OP_AREF:
+ n = 2 + *ip++;
+ sp -= n;
+ break;
+
+ case OP_ARGC: case OP_SETG: case OP_SETA: case OP_BOX:
+ ip++;
+ continue;
+
+ case OP_TCALL: case OP_CALL: case OP_CLOSURE: case OP_SHIFT:
+ n = *ip++; // nargs
+ sp -= n;
+ break;
+
+ case OP_LOADVL: case OP_LOADGL: case OP_LOADAL:
+ sp++; // fallthrough
+ case OP_SETGL: case OP_SETAL: case OP_ARGCL: case OP_BOXL:
+ SWAP_INT32(ip);
+ ip += 4;
+ break;
+
+ case OP_LOADC:
+ sp++;
+ ip++;
+ break;
+
+ case OP_VARGC:
+ n = *ip++;
+ sp += n+2;
+ break;
+ case OP_VARGCL:
+ SWAP_INT32(ip);
+ n = GET_S32(ip); ip += 4;
+ sp += n+2;
+ break;
+ case OP_OPTARGS:
+ SWAP_INT32(ip);
+ i = GET_S32(ip); ip += 4;
+ SWAP_INT32(ip);
+ n = abs(GET_S32(ip)); ip += 4;
+ sp += n-i;
+ break;
+ case OP_KEYARGS:
+ SWAP_INT32(ip);
+ i = GET_S32(ip); ip += 4;
+ SWAP_INT32(ip);
+ ip += 4;
+ SWAP_INT32(ip);
+ n = abs(GET_S32(ip)); ip += 4;
+ sp += n-i;
+ break;
+ case OP_BOUNDA:
+ SWAP_INT32(ip);
+ ip += 4;
+ sp++;
+ break;
+ case OP_TCALLL: case OP_CALLL:
+ SWAP_INT32(ip);
+ n = GET_S32(ip); ip+=4;
+ sp -= n;
+ break;
+ case OP_JMP:
+ SWAP_INT16(ip);
+ ip += 2;
+ continue;
+ case OP_JMPL:
+ SWAP_INT32(ip);
+ ip += 4;
+ continue;
+ case OP_BRNE:
+ SWAP_INT16(ip);
+ ip += 2;
+ sp -= 2;
+ break;
+ case OP_BRNEL:
+ SWAP_INT32(ip);
+ ip += 4;
+ sp -= 2;
+ break;
+ case OP_BRNN: case OP_BRN:
+ SWAP_INT16(ip);
+ ip += 2;
+ sp--;
+ break;
+ case OP_BRNNL: case OP_BRNL:
+ SWAP_INT32(ip);
+ ip += 4; // fallthrough
+ case OP_TAPPLY: case OP_APPLY:
+ case OP_LIST: case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
+ case OP_VEC: case OP_LT: case OP_NUMEQP:
+ n = *ip++;
+ sp -= n-1;
+ break;
+
+ case OP_FOR:
+ if(maxsp < sp+2)
+ maxsp = sp+2; // fallthrough
+ case OP_ASET:
+ sp -= 2;
+ break;
+
+ case OP_LOADCL:
+ sp++; // fallthrough
+ SWAP_INT32(ip);
+ ip += 4;
+ break;
+
+ case OP_CAR: case OP_CDR: case OP_CADR:
+ case OP_NOT: case OP_NEG: case OP_NUMP:
+ case OP_CONSP: case OP_ATOMP: case OP_SYMP:
+ case OP_FIXNUMP: case OP_BOUNDP: case OP_BUILTINP:
+ case OP_FNP: case OP_VECP: case OP_NANP:
+ continue;
+
+ case N_OPCODES:
+ return -1;
+ }
+ if((s32int)sp > (s32int)maxsp)
+ maxsp = sp;
+ }
+ assert(ip == end);
+ assert(maxsp >= 0);
+ return maxsp+4;
+}
--- a/src/mem.h
+++ b/src/mem.h
@@ -1,9 +1,10 @@
#if !defined(HEAP_SIZE0)
+// NOTE: has to be at least enough to start with no gc calls
#define HEAP_SIZE0 4*1024*1024
#endif
#if !defined(STACK_SIZE0)
-#define STACK_SIZE0 64*1024
+#define STACK_SIZE0 4*1024
#endif
#if !defined(ALLOC_LIMIT_TRIGGER)
--- a/src/print.c
+++ b/src/print.c
@@ -446,7 +446,7 @@
outsc(f, "#<eof>");
else if(v == sl_void)
outsc(f, "#<void>");
- else
+ else // unbound, should never happen
abort();
break;
case TAG_FN:
--- a/src/read.c
+++ b/src/read.c
@@ -396,7 +396,7 @@
{
usize i, s = vec_size(v);
usize d = vec_grow_amt(s);
- PUSH(v);
+ PUSH_SAFE(v);
assert(s+d > s);
sl_v newv = alloc_vec(s+d, true);
v = sl.sp[-1];
@@ -417,7 +417,7 @@
{
sl_v v = sl_emptyvec, elt;
u32int i = 0;
- PUSH(v);
+ PUSH_SAFE(v);
if(label != sl_unbound)
ptrhash_put(&sl.readstate->backrefs, (void*)label, (void*)v);
while(peek(ctx) != closer){
@@ -425,7 +425,8 @@
parse_error(ctx, "unexpected EOI");
v = sl.sp[-1]; // reload after possible alloc in peek()
if(i >= vec_size(v)){
- v = sl.sp[-1] = vec_grow(v, label != sl_unbound);
+ v = vec_grow(v, label != sl_unbound);
+ sl.sp[-1] = v;
if(label != sl_unbound)
ptrhash_put(&sl.readstate->backrefs, (void*)label, (void*)v);
}
@@ -584,16 +585,15 @@
static void
read_list(Rctx *ctx, sl_v label, u32int closer)
{
- sl_v c, *pc, *pval, *ipval, *ipc;
- u32int t;
- ios_loc loc0;
+ usize pc, pval;
+ sl_v c;
- loc0 = RS->loc;
+ ios_loc loc0 = RS->loc;
loc0.colno--;
- ipval = sl.sp-1;
- PUSH(sl_nil);
- ipc = sl.sp-1; // to keep track of current cons cell
- t = peek(ctx);
+ usize ipval = sl.sp-sl.stack-1;
+ usize ipc = ipval+1; // to keep track of current cons cell
+ PUSH_SAFE(sl_nil);
+ u32int t = peek(ctx);
while(t != closer){
if(ios_eof(RS)){
parse_error(
@@ -606,18 +606,18 @@
}
c = alloc_cons(); car_(c) = cdr_(c) = sl_nil;
pc = ipc;
- if(iscons(*pc))
- cdr_(*pc) = c;
+ if(iscons(sl.stack[pc]))
+ cdr_(sl.stack[pc]) = c;
else{
pval = ipval;
- *pval = c;
+ sl.stack[pval] = c;
if(label != sl_unbound)
ptrhash_put(&sl.readstate->backrefs, (void*)label, (void*)c);
}
- *pc = c;
+ sl.stack[pc] = c;
c = do_read_sexpr(ctx, sl_unbound);
pc = ipc;
- car_(*pc) = c;
+ car_(sl.stack[pc]) = c;
t = peek(ctx);
if(t == TOK_DOT){
@@ -624,7 +624,7 @@
take(ctx);
c = do_read_sexpr(ctx, sl_unbound);
pc = ipc;
- cdr_(*pc) = c;
+ cdr_(sl.stack[pc]) = c;
t = peek(ctx);
if(ios_eof(RS))
parse_error(ctx, "unexpected EOI");
@@ -658,7 +658,7 @@
take(ctx);
switch(t){
case TOK_OPEN:
- PUSH(sl_nil);
+ PUSH_SAFE(sl_nil);
read_list(ctx, label, TOK_CLOSE);
return POP();
case TOK_SYM:
@@ -665,11 +665,11 @@
case TOK_NUM:
return ctx->tokval;
case TOK_OPENB:
- PUSH(sl_nil);
+ PUSH_SAFE(sl_nil);
read_list(ctx, label, TOK_CLOSEB);
return POP();
case TOK_OPENC:
- PUSH(sl_nil);
+ PUSH_SAFE(sl_nil);
read_list(ctx, label, TOK_CLOSEC);
return POP();
case TOK_COMMA:
@@ -687,7 +687,7 @@
car_(v) = *head;
cdr_(v) = tagptr((sl_cons*)ptr(v)+1, TAG_CONS);
car_(cdr_(v)) = cdr_(cdr_(v)) = sl_nil;
- PUSH(v);
+ PUSH_SAFE(v);
if(label != sl_unbound)
ptrhash_put(&sl.readstate->backrefs, (void*)label, (void*)v);
v = do_read_sexpr(ctx, sl_unbound);
@@ -706,11 +706,12 @@
take(ctx);
parse_error(ctx, "expected argument list for %s", sym_name(ctx->tokval));
}
- PUSH(sl_nil);
+ PUSH_SAFE(sl_nil);
read_list(ctx, sl_unbound, c == '(' ? TOK_CLOSE : (c == '[' ? TOK_CLOSEB : TOK_CLOSEC));
if(sym == sl_vu8sym){
sym = sl_arrsym;
- sl.sp[-1] = mk_cons(sl_u8sym, sl.sp[-1]);
+ v = mk_cons(sl_u8sym, sl.sp[-1]);
+ sl.sp[-1] = v;
}
v = sym_value(sym);
sl.readstate->errloc = loc0;
--- a/src/sl.c
+++ b/src/sl.c
@@ -83,13 +83,15 @@
#define SL_TRY \
sl_exctx _ctx; int l__tr, l__ca; \
- _ctx.sp = sl.sp; _ctx.frame = sl.curr_frame; _ctx.rdst = sl.readstate; _ctx.prev = sl.exctx; \
+ _ctx.osp = sl.sp - sl.stack; _ctx.frame = sl.curr_frame; \
+ _ctx.rdst = sl.readstate; _ctx.prev = sl.exctx; \
_ctx.ngchnd = slg.ngchandles; sl.exctx = &_ctx; \
if(!sl_setjmp(_ctx.buf)) \
for(l__tr = 1; l__tr; l__tr = 0, (void)(sl.exctx = sl.exctx->prev))
#define SL_CATCH_INC \
- l__ca = 0, sl.lasterror = sl_nil, sl.throwing_frame = 0, sl.sp = _ctx.sp, sl.curr_frame = _ctx.frame
+ l__ca = 0, sl.lasterror = sl_nil, sl.throwing_frame = 0, \
+ sl.sp = sl.stack + _ctx.osp, sl.curr_frame = _ctx.frame
#define SL_CATCH \
else \
@@ -102,7 +104,7 @@
void
sl_savestate(sl_exctx *_ctx)
{
- _ctx->sp = sl.sp;
+ _ctx->osp = sl.sp - sl.stack;
_ctx->frame = sl.curr_frame;
_ctx->rdst = sl.readstate;
_ctx->prev = sl.exctx;
@@ -114,7 +116,7 @@
{
sl.lasterror = sl_nil;
sl.throwing_frame = 0;
- sl.sp = _ctx->sp;
+ sl.sp = sl.stack + _ctx->osp;
sl.curr_frame = _ctx->frame;
}
@@ -337,18 +339,17 @@
}
void *
-alloc_words(int n)
+alloc_words(usize n)
{
sl_v *first;
-#if !defined(BITS64)
- // force 8-byte alignment
+ // force 8-byte alignment (32-bit) and always two cells (to forward)
+ assert(n > 0);
if(n & 1)
n++;
-#endif
if(sl_unlikely((sl_v*)slg.curheap > (sl_v*)slg.lim+2-n)){
sl_gc(false);
- while(sl_unlikely((sl_v*)slg.curheap > ((sl_v*)slg.lim)+2-n))
+ while(sl_unlikely((sl_v*)slg.curheap > (sl_v*)slg.lim+2-n))
sl_gc(true);
}
first = (sl_v*)slg.curheap;
@@ -371,6 +372,18 @@
return v;
}
+void
+sl_stack_grow(void)
+{
+ sl_v *s = MEM_REALLOC(sl.stack, 2*sl.nstack*sizeof(sl.stack));
+ if(s == nil)
+ sl_raise(sl_erroom);
+ sl.nstack *= 2;
+ sl.sp = s + (sl.sp - sl.stack);
+ sl.stackend = s + sl.nstack;
+ sl.stack = s;
+}
+
// collector ------------------------------------------------------------------
void
@@ -451,17 +464,20 @@
return nc;
}
if(t == TAG_FN){
- sl_fn *fn = ptr(v);
+ sl_fn *fn = ptr(v), f;
+ f.vals = sl_relocate(fn->vals);
+ f.bcode = sl_relocate(fn->bcode);
+ f.env = sl_relocate(fn->env);
+ f.name = sl_relocate(fn->name);
+ f.maxstack = fn->maxstack;
sl_fn *nfn = alloc_words(sizeof(sl_fn)/sizeof(sl_v));
- nfn->vals = fn->vals;
- nfn->bcode = fn->bcode;
+ *nfn = f;
+ assert(!ismanaged(nfn->vals));
+ assert(!ismanaged(nfn->bcode));
+ assert(!ismanaged(nfn->env));
+ assert(!ismanaged(nfn->name));
nc = tagptr(nfn, TAG_FN);
forward(v, nc);
- nfn->vals = sl_relocate(nfn->vals);
- nfn->bcode = sl_relocate(nfn->bcode);
- nfn->env = sl_relocate(fn->env);
- assert(!ismanaged(fn->name));
- nfn->name = fn->name;
return nc;
}
if(t == TAG_SYM){
@@ -497,21 +513,23 @@
slg.lim = slg.curheap = slg.tospace;
slg.lim += slg.heapsize * (slg.grew ? 2 : 1) - sizeof(sl_cons);
- sl_v *top, *f;
+ usize top, f;
if(sl.throwing_frame > sl.curr_frame){
top = sl.throwing_frame - 3;
- f = (sl_v*)*top;
+ f = sl.stack[top];
}else{
- top = sl.sp;
+ top = sl.sp - sl.stack;
f = sl.curr_frame;
}
for(;;){
- for(sl_v *p = f; p < top; p++)
- *p = sl_relocate(*p);
- if(f == sl.stack)
+ for(usize p = f; p < top; p++){
+ sl_v v = sl_relocate(sl.stack[p]);
+ sl.stack[p] = v;
+ }
+ if(f == 0)
break;
top = f - 3;
- f = (sl_v*)*top;
+ f = sl.stack[top];
}
for(int i = 0; i < slg.ngchandles; i++)
*slg.gchandles[i] = sl_relocate(*slg.gchandles[i]);
@@ -550,7 +568,7 @@
// if we're using > 80% of the space, resize tospace so we have
// more space to fill next time. if we grew tospace last time,
// grow the other half of the heap this time to catch up.
- if(slg.grew || ((intptr)(slg.lim-slg.curheap) < (intptr)slg.heapsize/5) || mustgrow){
+ if(slg.grew || mustgrow || ((intptr)(slg.lim-slg.curheap) < (intptr)slg.heapsize/5)){
sl_segfree(slg.tospace, slg.heapsize);
slg.tospace = sl_segalloc(slg.heapsize*2);
if(sl_unlikely(slg.tospace == nil)){
@@ -586,16 +604,16 @@
static sl_v
_applyn(int n)
{
- sl_v *saveSP = sl.sp;
- sl_v f = saveSP[-n-1];
+ sl_v f = sl.sp[-n-1];
+ usize osp = sl.sp - sl.stack;
sl_v v;
- if(iscbuiltin(f))
- v = ((sl_cv*)ptr(f))->cbuiltin(saveSP-n, n);
- else if(sl_likely(isbuiltin(f))){
+ if(iscbuiltin(f)){
+ v = ((sl_cv*)ptr(f))->cbuiltin(sl.sp-n, n);
+ }else if(sl_likely(isbuiltin(f))){
sl_v tab = sym_value(sl_builtinssym);
if(sl_unlikely(ptr(tab) == nil))
cthrow(unbound_error(tab), n);
- saveSP[-n-1] = vec_elt(tab, uintval(f));
+ sl.sp[-n-1] = vec_elt(tab, uintval(f));
v = apply_cl(n);
}else if(isfn(f)){
v = apply_cl(n);
@@ -602,7 +620,7 @@
}else{
cthrow(type_error(nil, "fn", f), n);
}
- sl.sp = saveSP;
+ sl.sp = sl.stack + osp;
return v;
}
@@ -609,18 +627,16 @@
sl_v
sl_apply(sl_v f, sl_v v)
{
- sl_v *saveSP = sl.sp;
-
- PUSH(f);
+ PUSH_SAFE(f);
int n;
for(n = 0; iscons(v); n++){
- PUSH(car_(v));
+ PUSH_SAFE(car_(v));
v = cdr_(v);
}
if(v != sl_nil)
cthrow(lerrorf(sl_errarg, "apply: last argument: not a list"), f);
v = _applyn(n);
- sl.sp = saveSP;
+ POPN(1+n);
return v;
}
@@ -630,6 +646,7 @@
va_list ap;
va_start(ap, f);
+ stack_for(1+n);
PUSH(f);
for(int i = 0; i < n; i++){
sl_v a = va_arg(ap, sl_v);
@@ -636,7 +653,7 @@
PUSH(a);
}
sl_v v = _applyn(n);
- POPN(n+1);
+ POPN(1+n);
va_end(ap);
return v;
}
@@ -646,8 +663,9 @@
{
va_list ap;
va_start(ap, n);
- sl_v *si = sl.sp;
+ sl_v si = sl.sp - sl.stack;
+ stack_for(n);
for(int i = 0; i < n; i++){
sl_v a = va_arg(ap, sl_v);
PUSH(a);
@@ -655,7 +673,7 @@
sl_cons *c = alloc_words(n*2);
sl_cons *l = c;
for(int i = 0; i < n; i++){
- c->car = *si++;
+ c->car = sl.stack[si++];
c->cdr = tagptr(c+1, TAG_CONS);
c++;
}
@@ -733,23 +751,23 @@
{
if(!iscons(L))
return sl_nil;
- sl_v *plcons = sl.sp;
- sl_v *pL = plcons+1;
+ usize plcons = sl.sp - sl.stack;
+ usize pL = plcons+1;
PUSH(sl_nil);
PUSH(L);
sl_v c;
c = alloc_cons(); PUSH(c); // save first cons
- car_(c) = car_(*pL);
+ car_(c) = car_(sl.stack[pL]);
cdr_(c) = sl_nil;
- *plcons = c;
- *pL = cdr_(*pL);
- while(iscons(*pL)){
+ sl.stack[plcons] = c;
+ sl.stack[pL] = cdr_(sl.stack[pL]);
+ while(iscons(sl.stack[pL])){
c = alloc_cons();
- car_(c) = car_(*pL);
+ car_(c) = car_(sl.stack[pL]);
cdr_(c) = sl_nil;
- cdr_(*plcons) = c;
- *plcons = c;
- *pL = cdr_(*pL);
+ cdr_(sl.stack[plcons]) = c;
+ sl.stack[plcons] = c;
+ sl.stack[pL] = cdr_(sl.stack[pL]);
}
c = POP(); // first cons
POPN(2);
@@ -759,10 +777,10 @@
static sl_v
do_trycatch(void)
{
- sl_v *saveSP = sl.sp;
+ usize osp = sl.sp - sl.stack;
sl_v v = sl_nil;
- sl_v thunk = saveSP[-2];
- sl.sp[-2] = saveSP[-1];
+ sl_v thunk = sl.sp[-2];
+ sl.sp[-2] = sl.sp[-1];
sl.sp[-1] = thunk;
SL_TRY{
@@ -769,12 +787,12 @@
v = apply_cl(0);
}
SL_CATCH{
- v = saveSP[-2];
- PUSH(v);
- PUSH(sl.lasterror);
+ v = sl.stack[osp-2];
+ PUSH_SAFE(v);
+ PUSH_SAFE(sl.lasterror);
v = apply_cl(1);
}
- sl.sp = saveSP;
+ sl.sp = sl.stack + osp;
return v;
}
@@ -783,7 +801,7 @@
|--required args--|--opt args--|--kw args--|--rest args...
*/
static int
-process_keys(sl_v kwtable, int nreq, int nkw, int nopt, sl_v *bp, int nargs, int va)
+process_keys(sl_v kwtable, int nreq, int nkw, int nopt, usize bp, int nargs, int va)
{
int extr = nopt+nkw;
int ntot = nreq+extr;
@@ -799,7 +817,7 @@
for(i = 0; i < extr; i++)
args[i] = sl_unbound;
for(i = nreq; i < nargs; i++){
- v = bp[i];
+ v = sl.stack[bp+i];
if(issym(v) && iskeyword((sl_sym*)ptr(v)))
break;
if(a >= nopt)
@@ -823,7 +841,7 @@
idx += nopt;
if(args[idx] == sl_unbound){
// if duplicate key, keep first value
- args[idx] = bp[i];
+ args[idx] = sl.stack[bp+i];
}
}else{
cthrow(lerrorf(sl_errarg, "unsupported keyword %s", sym_name(v)), kwtable);
@@ -831,7 +849,7 @@
i++;
if(i >= nargs)
break;
- v = bp[i];
+ v = sl.stack[bp+i];
}while(issym(v) && iskeyword((sl_sym*)ptr(v)));
no_kw:
nrestargs = nargs - i;
@@ -839,15 +857,15 @@
cthrow(lerrorf(sl_errarg, "too many arguments"), kwtable);
nargs = ntot + nrestargs;
if(nrestargs)
- memmove(bp+ntot, bp+i, nrestargs*sizeof(sl_v));
- memmove(bp+nreq, args, extr*sizeof(sl_v));
- sl.sp = bp + nargs;
- assert((intptr)(sl.sp-sl.stack) < (intptr)sl.nstack-4);
+ memmove(&sl.stack[bp+ntot], &sl.stack[bp+i], nrestargs*sizeof(sl_v));
+ memmove(&sl.stack[bp+nreq], args, extr*sizeof(sl_v));
+ sl.sp = &sl.stack[bp+nargs];
+ assert(sl.sp < sl.stackend-4);
PUSH(s4);
PUSH(s3);
PUSH(nargs);
PUSH(s1);
- sl.curr_frame = sl.sp;
+ sl.curr_frame = sl.sp - sl.stack;
return nargs;
}
@@ -859,6 +877,8 @@
#define GET_S16(a) (s16int)((a)[0]<<0 | (a)[1]<<8)
#endif
+#include "maxstack.h"
+
/*
stack on entry: <fn> <nargs args...>
caller's responsibility:
@@ -875,8 +895,7 @@
static sl_v
apply_cl(int nargs)
{
- sl_v *top_frame = sl.curr_frame, *bp, *ipd;
- register sl_v *sp = sl.sp;
+ usize obp, ipd, top_frame = sl.curr_frame;
const u8int *ip;
bool tail;
int n;
@@ -891,7 +910,7 @@
#include "vm_goto.h"
#undef GOTO_OP_OFFSET
};
-#define NEXT_OP goto *ops[*ip++]
+#define NEXT_OP do{ goto *ops[*ip++]; }while(0)
#define LABEL(x) x
#define OP(x) op_##x:
#include "vm.h"
@@ -918,17 +937,16 @@
// top = top frame pointer to start at
static sl_v
-_stacktrace(sl_v *top)
+_stacktrace(usize top)
{
sl_v lst = sl_nil, v = sl_nil;
- sl_v *stack = sl.stack;
sl_gc_handle(&lst);
sl_gc_handle(&v);
- while(top > stack){
- const u8int *ip1 = (void*)top[-1];
- int sz = top[-2]+1;
- sl_v *bp = top-4-sz;
+ while(top > 0){
+ const u8int *ip1 = (void*)sl.stack[top-1];
+ int sz = sl.stack[top-2]+1;
+ sl_v *bp = sl.stack+top-4-sz;
sl_v fn = bp[0];
v = alloc_vec(sz+1, 0);
if(iscbuiltin(fn))
@@ -946,7 +964,7 @@
vec_elt(v, i+1) = si == sl_unbound ? sl_void : si;
}
lst = mk_cons(v, lst);
- top = (sl_v*)top[-3];
+ top = sl.stack[top-3];
}
sl_free_gc_handles(2);
return lst;
@@ -979,10 +997,10 @@
sl_cv *arr = ptr(args[0]);
cv_pin(arr);
u8int *data = cv_data(arr);
+ usize sz = cv_len(arr);
if(slg.loading){
// read syntax, shifted 48 for compact text representation
- usize i, sz = cv_len(arr);
- for(i = 0; i < sz; i++)
+ for(usize i = 0; i < sz; i++)
data[i] -= 48;
}
sl_fn *fn = alloc_words(sizeof(sl_fn)/sizeof(sl_v));
@@ -991,6 +1009,7 @@
fn->vals = vals;
fn->env = sl_nil;
fn->name = sl_lambda;
+ fn->maxstack = compute_maxstack(data, sz);
if(nargs > 2){
if(issym(args[2])){
fn->name = args[2];
@@ -1063,16 +1082,27 @@
bthrow(type_error(nil, "fn", v));
}
+BUILTIN("fn-maxstack", fn_maxstack)
+{
+ argcount(nargs, 1);
+ sl_v v = args[0];
+ if(isbuiltin(v) || iscbuiltin(v))
+ return fixnum(0);
+ if(isfn(v))
+ return size_wrap(fn_maxstack(v));
+ bthrow(type_error(nil, "fn", v));
+}
+
BUILTIN("append", append)
{
- sl_v first = sl_nil, lst, lastcons = sl_nil;
- int i;
if(nargs == 0)
return sl_nil;
+
+ sl_v first = sl_nil, lastcons = sl_nil;
sl_gc_handle(&first);
sl_gc_handle(&lastcons);
- for(i = 0; i < nargs; i++){
- lst = args[i];
+ for(int i = 0; i < nargs; i++){
+ sl_v lst = args[i];
if(iscons(lst)){
lst = copy_list(lst);
if(first == sl_nil)
@@ -1142,14 +1172,16 @@
}else{
bthrow(type_error("result-type", "sequence type specifier", rt));
}
- sl_v *k = sl.sp;
+ usize k = sl.sp - sl.stack;
+ usize oargs = args - sl.stack;
+ stack_for(2+nargs*2+2);
PUSH(sl_nil);
PUSH(sl_nil);
for(usize n = 0;; n++){
- PUSH(args[0]);
+ PUSH(sl.stack[oargs+0]);
int pargs = 0;
- for(sl_v *a = args+1; a < args+nargs; a++, pargs++){
- sl_v v = *a;
+ for(int i = 1; i < nargs; i++, pargs++){
+ sl_v v = sl.stack[oargs+i];
if(iscons(v)){
if(!rtdecl){
if(rtype == RT_AUTO)
@@ -1158,7 +1190,7 @@
bthrow(lerrorf(sl_errarg, "sequence type mismatch"));
}
PUSH(car_(v));
- *a = cdr_(v);
+ sl.stack[oargs+i] = cdr_(v);
continue;
}else if(isvec(v)){
if(!rtdecl){
@@ -1234,39 +1266,39 @@
default:
break;
case RT_VEC:
- k[1] = alloc_vec(n, 0);
- memcpy(&vec_elt(k[1], 0), sl.sp-n, n*sizeof(sl_v));
+ sl.stack[k+1] = alloc_vec(n, 0);
+ memmove(&vec_elt(sl.stack[k+1], 0), sl.sp-n, n*sizeof(sl_v));
POPN(n);
break;
case RT_ARR:
- k[0] = sym_value(sl_arrsym);
- k[1] = arrtype;
- k[1] = _applyn(n+1);
+ sl.stack[k+0] = sym_value(sl_arrsym);
+ sl.stack[k+1] = arrtype;
+ sl.stack[k+1] = _applyn(n+1);
POPN(n);
break;
case RT_STR:
- k[1] = sym_value(sl_strsym);
- k[1] = _applyn(n);
+ sl.stack[k+1] = sym_value(sl_strsym);
+ sl.stack[k+1] = _applyn(n);
POPN(n);
break;
case RT_TBL:
- k[1] = sym_value(sl_tablesym);
- k[1] = _applyn(2*n);
+ sl.stack[k+1] = sym_value(sl_tablesym);
+ sl.stack[k+1] = _applyn(2*n);
POPN(2*n);
break;
case RT_NIL:
- k[1] = sl_nil;
+ sl.stack[k+1] = sl_nil;
break;
}
POPN(2);
- return k[1];
+ return sl.stack[k+1];
}
- sl_v v = _applyn(pargs);
+ sl_v c, v = _applyn(pargs);
POPN(pargs+1);
switch(rtype){
- sl_v c;
default:
PUSH(v);
+ break;
case RT_NIL:
break;
case RT_TBL:
@@ -1274,14 +1306,16 @@
PUSH(cdr(v));
break;
case RT_LIST:
+ sl_gc_handle(&v);
c = alloc_cons();
+ sl_free_gc_handles(1);
car_(c) = v;
cdr_(c) = sl_nil;
if(n == 0)
- k[1] = c;
+ sl.stack[k+1] = c;
else
- cdr_(k[0]) = c;
- k[0] = c;
+ cdr_(sl.stack[k+0]) = c;
+ sl.stack[k+0] = c;
break;
}
}
@@ -1341,7 +1375,7 @@
// initialization -------------------------------------------------------------
int
-sl_init(usize heapsize, usize stacksize)
+sl_init(usize heapsize)
{
int i;
@@ -1356,9 +1390,9 @@
MEM_FREE(sl.consflags);
MEM_FREE(slg.finalizers);
MEM_FREE(slg.gchandles);
+ MEM_FREE(sl.stack);
sl_segfree(slg.fromspace, slg.heapsize);
sl_segfree(slg.tospace, slg.heapsize);
- sl_segfree(sl.stack, stacksize*sizeof(sl_v));
htable_free(&sl.printconses);
MEM_FREE(slp);
return -1;
@@ -1369,10 +1403,11 @@
slg.curheap = slg.fromspace;
slg.lim = slg.curheap+slg.heapsize-sizeof(sl_cons);
- if((sl.stack = sl_segalloc(stacksize*sizeof(sl_v))) == nil)
+ sl.nstack = STACK_SIZE0;
+ if((sl.stack = MEM_ALLOC(sl.nstack*sizeof(sl_v))) == nil)
goto failed;
- sl.curr_frame = sl.sp = sl.stack;
- sl.nstack = stacksize;
+ sl.sp = sl.stack;
+ sl.stackend = sl.stack + sl.nstack - 4;
slg.maxfinalizers = 512;
if((slg.finalizers = MEM_ALLOC(slg.maxfinalizers * sizeof(*slg.finalizers))) == nil)
@@ -1449,7 +1484,7 @@
sl.lasterror = sl_nil;
for(i = 0; i < nelem(builtins); i++){
- if(builtins[i].name)
+ if(builtins[i].name != nil)
set(mk_sym(builtins[i].name, false), builtin(i));
}
@@ -1487,10 +1522,10 @@
{
slg.loading = true;
PUSH(sys_image_io);
- sl_v *saveSP = sl.sp;
+ usize osp = sl.sp - sl.stack;
SL_TRY{
while(1){
- sl.sp = saveSP;
+ sl.sp = sl.stack + osp;
sl_v e = sl_read_sexpr(sl.sp[-1], false);
if(ios_eof(value2c(ios*, sl.sp[-1])))
break;
@@ -1518,7 +1553,7 @@
ios_putc(ios_stderr, '\n');
return -1;
}
- sl.sp = saveSP-1;
+ sl.sp = sl.stack + osp - 1;
slg.loading = false;
return 0;
}
--- a/src/sl.h
+++ b/src/sl.h
@@ -62,10 +62,6 @@
#define PRIdFIXNUM PRId32
#endif
-#if !defined(FWD_BIT)
-#define FWD_BIT TOP_BIT
-#endif
-
typedef struct {
sl_v car;
sl_v cdr;
@@ -147,11 +143,12 @@
#define mark_cons(c) bitvector_set(sl.consflags, cons_index(c))
#define unmark_cons(c) bitvector_reset(sl.consflags, cons_index(c))
-#define isforwarded(v) (*(sl_v*)ptr(v) & FWD_BIT)
-#define forwardloc(v) (*(sl_v*)ptr(v) ^ FWD_BIT)
+#define isforwarded(v) (((sl_v*)ptr(v))[0] == sl_unbound)
+#define forwardloc(v) (((sl_v*)ptr(v))[1])
#define forward(v, to) \
do{ \
- *(sl_v*)ptr(v) = (sl_v)(to) | FWD_BIT; \
+ ((sl_v*)ptr(v))[0] = sl_unbound; \
+ ((sl_v*)ptr(v))[1] = (sl_v)(to); \
}while(0)
enum {
@@ -176,6 +173,7 @@
#define fn_vals(f) (((sl_fn*)ptr(f))->vals)
#define fn_env(f) (((sl_fn*)ptr(f))->env)
#define fn_name(f) (((sl_fn*)ptr(f))->name)
+#define fn_maxstack(f) (((sl_fn*)ptr(f))->maxstack)
#define set(s, v) (((sl_sym*)ptr(s))->binding = (v))
#define setc(s, v) \
do{ \
@@ -199,27 +197,39 @@
#define FOR_ARGS(i, i0, arg, args) for(i=i0; i<nargs && ((arg=args[i]) || 1); i++)
#define N_BUILTINS ((int)N_OPCODES)
-#define PUSH(v) \
- do{ \
- *sl.sp++ = (v); \
- }while(0)
-#define POPN(n) \
- do{ \
- sl.sp -= (n); \
- }while(0)
+#define PUSH(v) do{ \
+ *sl.sp++ = (sl_v)(v); \
+}while(0)
+
+#define stack_for(n) do{ \
+ while(sl.sp+(n) >= sl.stackend) \
+ sl_stack_grow(); \
+}while(0)
+
+#define PUSH_SAFE(v) do{ \
+ if(sl.sp >= sl.stackend) \
+ sl_stack_grow(); \
+ PUSH(v); \
+}while(0)
+
+#define POPN(n) do{ \
+ sl.sp -= (n); \
+}while(0)
+
#define POP() *(--sl.sp)
bool isbuiltin(sl_v x) sl_constfn sl_hotfn;
-int sl_init(usize heapsize, usize stacksize);
+int sl_init(usize heapsize);
int sl_load_system_image(sl_v ios);
_Noreturn void sl_exit(const char *status);
-/* collector */
+/* memory */
sl_v sl_relocate(sl_v v) sl_hotfn;
void sl_gc(bool mustgrow);
void sl_gc_handle(sl_v *pv);
void sl_free_gc_handles(int n);
+void sl_stack_grow(void);
/* symbol table */
sl_v mk_gensym(void);
@@ -253,7 +263,7 @@
/* conses */
sl_v alloc_cons(void) sl_hotfn;
-void *alloc_words(int n) sl_hotfn;
+void *alloc_words(usize n) sl_hotfn;
char *uint2str(char *dest, usize len, u64int num, int base);
@@ -270,8 +280,8 @@
sl_readstate *rdst;
struct _ectx_t *prev;
sl_jmp_buf buf;
- sl_v *sp;
- sl_v *frame;
+ usize osp;
+ usize frame;
int ngchnd;
}sl_exctx;
@@ -347,6 +357,7 @@
sl_v bcode;
sl_v env;
sl_v name;
+ usize maxstack;
}sl_aligned(8) sl_fn;
#define cv_class(cv) ((sl_type*)(((uintptr)((sl_cv*)cv)->type)&~(uintptr)3))
@@ -385,16 +396,17 @@
struct Sl {
sl_v *sp;
- sl_v *curr_frame;
+ usize curr_frame;
// saved execution state for an unwind target
sl_exctx *exctx;
- sl_v *throwing_frame; // active frame when exception was thrown
+ usize throwing_frame; // active frame when exception was thrown
sl_v lasterror;
sl_readstate *readstate;
u32int *consflags;
sl_v *stack;
+ sl_v *stackend;
u32int nstack;
sl_htable printconses;
--- a/src/sl_arith_any.h
+++ b/src/sl_arith_any.h
@@ -36,7 +36,7 @@
}
switch(pt){
case T_DBL: Faccum = ARITH_OP(Faccum, *(double*)a); inexact = true; continue;
- case T_FLT: Faccum = ARITH_OP(Faccum, *(float*)a); inexact = true; continue;
+ case T_FLT: Faccum = ARITH_OP(Faccum, *(float*)a); inexact = true; continue;
case T_S8: x = *(s8int*)a; break;
case T_U8: x = *(u8int*)a; break;
case T_S16: x = *(s16int*)a; break;
@@ -119,7 +119,7 @@
}
switch(pt){
case T_DBL: Faccum = ARITH_OP(Faccum, *(double*)a); inexact = true; continue;
- case T_FLT: Faccum = ARITH_OP(Faccum, *(float*)a); inexact = true; continue;
+ case T_FLT: Faccum = ARITH_OP(Faccum, *(float*)a); inexact = true; continue;
case T_S8: x = *(s8int*)a; break;
case T_U8: x = *(u8int*)a; break;
case T_S16: x = *(s16int*)a; break;
--- a/src/slmain.c
+++ b/src/slmain.c
@@ -64,7 +64,7 @@
_Noreturn static void
usage(void)
{
- ios_printf(ios_stderr, "%s: [-i] [-H heapsize] [-S stacksize] ...\n", argv0);
+ ios_printf(ios_stderr, "%s: [-i] [-H heapsize] ...\n", argv0);
exits("usage");
}
@@ -71,7 +71,7 @@
_Noreturn void
slmain(const u8int *boot, int bootsz, int argc, char **argv)
{
- usize heapsize = HEAP_SIZE0, stacksize = STACK_SIZE0;
+ usize heapsize = HEAP_SIZE0;
sl_v interactive;
char *e;
@@ -86,10 +86,6 @@
heapsize = strtoull(EARGF(usage()), &e, 0);
sizesuffix(&heapsize, *e);
break;
- case 'S':
- stacksize = strtoull(EARGF(usage()), &e, 0);
- sizesuffix(&stacksize, *e);
- break;
case 'i':
interactive = sl_t;
break;
@@ -99,7 +95,7 @@
break;
}ARGEND
- if(sl_init(heapsize, stacksize) != 0)
+ if(sl_init(heapsize) != 0)
sysfatal("init failed");
u8int *unpacked = nil;
--- a/src/vm.h
+++ b/src/vm.h
@@ -5,10 +5,17 @@
: (fits_fixnum(i64) ? fixnum(i64) : mk_bignum(vtomp(i64, nil))) \
)
-#define SYNC do { *ipd = (uintptr)ip; sl.sp = sp; }while(0)
+#define ENTER do{ \
+ sl.stack[ipd] = (uintptr)ip; \
+}while(0)
+#define STACK(n) do{ \
+ while(sl.sp+(n) > sl.stackend-4) \
+ sl_stack_grow(); \
+}while(0)
+
OP(OP_LOADA0)
- *sp++ = bp[0];
+ PUSH(sl.stack[obp+0]);
NEXT_OP;
OP(OP_CALL) {
@@ -29,28 +36,30 @@
ip += 4;
}
LABEL(do_call):
- SYNC;
- sl_v v = sp[-n-1];
+ ENTER;
+ sl_v v = sl.sp[-n-1];
if(tag(v) == TAG_FN){
if(!isfnbuiltin(v)){
nargs = n;
if(tail){
- sl.curr_frame = (sl_v*)sl.curr_frame[-3];
+ sl.curr_frame = sl.stack[sl.curr_frame-3];
for(sl_fx s = -1; s < (sl_fx)n; s++)
- bp[s] = sp[s-n];
- sp = bp+n;
+ sl.stack[obp+s] = sl.sp[s-n];
+ sl.sp = &sl.stack[obp+n];
}else{
LABEL(apply_func):
- bp = sp-nargs;
+ obp = sl.sp-sl.stack-nargs;
}
- sl_fn *fn = (sl_fn*)ptr(bp[-1]);
+ sl_fn *fn = (sl_fn*)ptr(sl.stack[obp-1]);
+ assert(ismanaged(fn));
+ stack_for(fn->maxstack);
ip = cvalue_data(fn->bcode);
assert(!ismanaged((uintptr)ip));
- *sp++ = fn->env;
- *sp++ = (sl_v)sl.curr_frame;
- *sp++ = nargs;
- ipd = sp++;
- sl.curr_frame = sp;
+ PUSH(fn->env);
+ PUSH(sl.curr_frame);
+ PUSH(nargs);
+ ipd = sl.sp++ - sl.stack;
+ sl.curr_frame = ipd + 1;
NEXT_OP;
}
int i = uintval(v);
@@ -62,9 +71,9 @@
else if(s != ANYARGS && n < -s)
argcount(n, -s);
// remove function arg
- for(sl_v *p = sp-n-1; p < sp-1; p++)
+ for(sl_v *p = sl.sp-n-1; p < sl.sp-1; p++)
p[0] = p[1];
- sp--;
+ POPN(1);
switch(i){
case OP_VEC: goto LABEL(apply_vec);
case OP_ADD: goto LABEL(apply_add);
@@ -87,17 +96,17 @@
}
}else if(sl_likely(iscbuiltin(v))){
builtin_t f = ((sl_cv*)ptr(v))->cbuiltin;
- *sp++ = sl_nil; // fn->env;
- *sp++ = (sl_v)sl.curr_frame;
- *sp++ = n;
- *sp++ = (sl_v)f; // ip
- sl.curr_frame = sp;
- sl.sp = sp;
- v = f(sp-n-4, n);
- sp = sl.curr_frame;
- sl.curr_frame = (sl_v*)sp[-3];
- sp -= 4+n;
- sp[-1] = v;
+ 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];
+ sl.sp -= 4+n;
+ sl.sp[-1] = v;
NEXT_OP;
}
type_error(tail ? "tcall" : "call", "fn", v);
@@ -111,7 +120,7 @@
ip += 4;
}
if(sl_unlikely(nargs != na)){
- SYNC;
+ ENTER;
arity_error(nargs, na);
}
NEXT_OP;
@@ -118,46 +127,44 @@
}
OP(OP_LOADA1)
- *sp++ = bp[1];
+ PUSH(sl.stack[obp+1]);
NEXT_OP;
OP(OP_RET) {
- sl_v v = *(--sp);
- sp = sl.curr_frame;
- sl.curr_frame = (sl_v*)sp[-3];
- if(sl.curr_frame == top_frame){
- sl.sp = sp;
+ sl_v v = POP();
+ sl.sp = sl.stack + sl.curr_frame;
+ sl.curr_frame = sl.sp[-3];
+ if(sl.curr_frame == top_frame)
return v;
- }
- sp -= 4+nargs;
+ sl.sp -= 4+nargs;
ipd = sl.curr_frame-1;
- ip = (u8int*)*ipd;
- nargs = sl.curr_frame[-2];
- bp = sl.curr_frame - 4 - nargs;
- sp[-1] = v;
+ ip = (u8int*)sl.stack[ipd];
+ nargs = sl.stack[sl.curr_frame-2];
+ obp = sl.curr_frame-4-nargs;
+ sl.sp[-1] = v;
NEXT_OP;
}
OP(OP_LOAD1)
- *sp++ = fixnum(1);
+ PUSH(fixnum(1));
NEXT_OP;
OP(OP_LOADA)
- *sp++ = bp[*ip++];
+ PUSH(sl.stack[obp + *ip++]);
NEXT_OP;
OP(OP_BRN)
- ip += *(--sp) == sl_nil ? GET_S16(ip) : 2;
+ ip += POP() == sl_nil ? GET_S16(ip) : 2;
NEXT_OP;
OP(OP_LOADG) {
- sl_v v = fn_vals(bp[-1]);
+ sl_v v = fn_vals(sl.stack[obp-1]);
assert(*ip < vec_size(v));
v = vec_elt(v, *ip);
ip++;
if(0){
OP(OP_LOADGL)
- v = fn_vals(bp[-1]);
+ v = fn_vals(sl.stack[obp-1]);
v = vec_elt(v, GET_S32(ip));
ip += 4;
}
@@ -164,10 +171,10 @@
assert(issym(v));
sl_sym *sym = ptr(v);
if(sl_unlikely(sym->binding == sl_unbound)){
- SYNC;
+ ENTER;
unbound_error(v);
}
- *sp++ = sym->binding;
+ PUSH(sym->binding);
NEXT_OP;
}
@@ -175,10 +182,10 @@
n = *ip++;
LABEL(apply_lt):;
int i = n;
- sl_v a = sp[-i], b, v;
+ sl_v a = sl.sp[-i], b, v;
for(v = sl_t; i > 1; a = b){
i--;
- b = sp[-i];
+ b = sl.sp[-i];
if(bothfixnums(a, b)){
if((sl_fx)a >= (sl_fx)b){
v = sl_nil;
@@ -194,15 +201,16 @@
}
}
}
- sp -= n;
- *sp++ = v;
+ sl.sp -= n;
+ PUSH(v);
NEXT_OP;
}
OP(OP_LOADV) {
- sl_v v = fn_vals(bp[-1]);
+ sl_v v = fn_vals(sl.stack[obp-1]);
assert(*ip < vec_size(v));
- *sp++ = vec_elt(v, *ip++);
+ PUSH(vec_elt(v, *ip++));
+ assert(sl.sp < sl.stackend);
NEXT_OP;
}
@@ -210,59 +218,59 @@
sl_fx a, b, q;
sl_v v;
LABEL(do_add2):
- SYNC;
+ ENTER;
if(0){
OP(OP_SUB2)
LABEL(do_sub2):
- SYNC;
- v = sp[-1];
+ ENTER;
+ v = sl.sp[-1];
s64int i64;
b = isfixnum(v) ? fixnum_neg(v) : sl_neg(v);
}else{
- b = sp[-1];
+ b = sl.sp[-1];
}
- a = sp[-2];
+ a = sl.sp[-2];
if(bothfixnums(a, b) && !sadd_overflow(a, b, &q))
v = q;
else{
- sp[-1] = b;
- v = sl_add_any(sp-2, 2);
+ sl.sp[-1] = b;
+ v = sl_add_any(sl.sp-2, 2);
}
- sp--;
- sp[-1] = v;
+ POPN(1);
+ sl.sp[-1] = v;
NEXT_OP;
}
OP(OP_LOADI8)
- *sp++ = fixnum((s8int)*ip++);
+ PUSH(fixnum((s8int)*ip++));
NEXT_OP;
OP(OP_POP)
- sp--;
+ POPN(1);
NEXT_OP;
OP(OP_BRNN)
- ip += *(--sp) != sl_nil ? GET_S16(ip) : 2;
+ ip += POP() != sl_nil ? GET_S16(ip) : 2;
NEXT_OP;
OP(OP_DUP)
- sp[0] = sp[-1];
- sp++;
+ sl.sp[0] = sl.sp[-1];
+ sl.sp++;
NEXT_OP;
OP(OP_LOADC0)
- *sp++ = vec_elt(bp[nargs], 0);
+ PUSH(vec_elt(sl.stack[obp+nargs], 0));
NEXT_OP;
OP(OP_CAR) {
- sl_v v = sp[-1];
+ sl_v v = sl.sp[-1];
if(sl_likely(iscons(v)))
v = car_(v);
else if(sl_unlikely(v != sl_nil)){
- SYNC;
+ ENTER;
type_error("car", "cons", v);
}
- sp[-1] = v;
+ sl.sp[-1] = v;
NEXT_OP;
}
@@ -269,75 +277,64 @@
OP(OP_CLOSURE) {
int x = *ip++;
assert(x > 0);
- SYNC;
- sl_v *pv = alloc_words(
- 1+x+
-#if !defined(BITS64)
- !(x&1)+
-#endif
- sizeof(sl_fn)/sizeof(sl_v));
- sl_v v = tagptr(pv, TAG_VEC);
- *pv++ = fixnum(x);
+ ENTER;
+ sl_v v = alloc_vec(x, false);
for(int i = 0; i < x; i++)
- *pv++ = sp[-x+i];
- sp -= x;
- *sp = v;
-#if !defined(BITS64)
- if((x & 1) == 0)
- pv++;
-#endif
- sl_fn *f = (sl_fn*)pv;
- sl_v e = sp[-1]; // closure to copy
- sp[-1] = tagptr(f, TAG_FN);
+ vec_elt(v, i) = sl.sp[-x+i];
+ POPN(x);
+ PUSH(v);
+ sl_fn *fn = (sl_fn*)alloc_words(sizeof(sl_fn)/sizeof(sl_v));
+ sl_v e = sl.sp[-2]; // closure to copy
assert(isfn(e));
- f->vals = fn_vals(e);
- f->bcode = fn_bcode(e);
- f->env = sp[0];
- f->name = fn_name(e);
+ fn->vals = fn_vals(e);
+ fn->bcode = fn_bcode(e);
+ fn->env = sl.sp[-1];
+ fn->name = fn_name(e);
+ fn->maxstack = fn_maxstack(e);
+ POPN(1);
+ sl.sp[-1] = tagptr(fn, TAG_FN);
NEXT_OP;
}
OP(OP_CONS) {
- if(slg.curheap > slg.lim){
- SYNC;
- sl_gc(0);
- }
+ if(sl_unlikely((sl_v*)slg.curheap > (sl_v*)slg.lim))
+ sl_gc(false);
sl_cons *c = (sl_cons*)slg.curheap;
slg.curheap += sizeof(sl_cons);
- c->car = sp[-2];
- c->cdr = sp[-1];
- sp[-2] = tagptr(c, TAG_CONS);
- sp--;
+ c->car = sl.sp[-2];
+ c->cdr = sl.sp[-1];
+ sl.sp[-2] = tagptr(c, TAG_CONS);
+ POPN(1);
NEXT_OP;
}
OP(OP_BRNE)
- ip += sp[-2] != sp[-1] ? GET_S16(ip) : 2;
- sp -= 2;
+ ip += sl.sp[-2] != sl.sp[-1] ? GET_S16(ip) : 2;
+ sl.sp -= 2;
NEXT_OP;
OP(OP_CDR) {
- sl_v v = sp[-1];
+ sl_v v = sl.sp[-1];
if(sl_likely(iscons(v)))
v = cdr_(v);
else if(sl_unlikely(v != sl_nil)){
- SYNC;
+ ENTER;
type_error("cdr", "cons", v);
}
- sp[-1] = v;
+ sl.sp[-1] = v;
NEXT_OP;
}
OP(OP_LOADVOID)
- *sp++ = sl_void;
+ PUSH(sl_void);
NEXT_OP;
OP(OP_NOT)
- sp[-1] = sp[-1] == sl_nil ? sl_t : sl_nil;
+ sl.sp[-1] = sl.sp[-1] == sl_nil ? sl_t : sl_nil;
NEXT_OP;
OP(OP_SETA)
- bp[*ip++] = sp[-1];
+ sl.stack[obp + *ip++] = sl.sp[-1];
NEXT_OP;
OP(OP_VARGC) {
@@ -348,29 +345,29 @@
ip += 4;
}
sl_fx s = (sl_fx)nargs - (sl_fx)i;
+ ENTER;
if(s > 0){
- sl_v v = list(bp+i, s, false);
- bp[i] = v;
+ sl_v v = list(&sl.stack[obp+i], s, false);
+ sl.stack[obp+i] = v;
if(s > 1){
- bp[i+1] = bp[nargs+0];
- bp[i+2] = bp[nargs+1];
- bp[i+3] = i+1;
- bp[i+4] = 0;
- sp = bp+i+5;
- sl.curr_frame = sp;
+ sl.stack[obp+i+1] = sl.stack[obp+nargs+0];
+ sl.stack[obp+i+2] = sl.stack[obp+nargs+1];
+ sl.stack[obp+i+3] = i+1;
+ sl.stack[obp+i+4] = 0;
+ sl.sp = sl.stack+obp+i+5;
+ sl.curr_frame = sl.sp - sl.stack;
}
}else if(sl_unlikely(s < 0)){
- SYNC;
lerrorf(sl_errarg, "too few arguments");
}else{
- sp++;
- sp[-2] = i+1;
- sp[-3] = sp[-4];
- sp[-4] = sp[-5];
- sp[-5] = sl_nil;
- sl.curr_frame = sp;
+ sl.sp++;
+ sl.sp[-2] = i+1;
+ sl.sp[-3] = sl.sp[-4];
+ sl.sp[-4] = sl.sp[-5];
+ sl.sp[-5] = sl_nil;
+ sl.curr_frame = sl.sp - sl.stack;
}
- ipd = sp-1;
+ ipd = sl.curr_frame-1;
nargs = i+1;
NEXT_OP;
}
@@ -377,33 +374,33 @@
OP(OP_SHIFT) {
int i = *ip++;
- sp[-1-i] = sp[-1];
- sp -= i;
+ sl.sp[-1-i] = sl.sp[-1];
+ sl.sp -= i;
NEXT_OP;
}
OP(OP_SETCAR) {
- sl_v v = sp[-2];
+ sl_v v = sl.sp[-2];
if(sl_unlikely(!iscons(v))){
- SYNC;
+ ENTER;
type_error("set-car!", "cons", v);
}
- car_(v) = sp[-1];
- sp--;
+ car_(v) = sl.sp[-1];
+ POPN(1);
NEXT_OP;
}
OP(OP_LOADNIL)
- *sp++ = sl_nil;
+ PUSH(sl_nil);
NEXT_OP;
OP(OP_BOX) {
int i = *ip++;
- SYNC;
+ ENTER;
sl_v v = alloc_cons();
- car_(v) = bp[i];
+ car_(v) = sl.stack[obp+i];
cdr_(v) = sl_nil;
- bp[i] = v;
+ sl.stack[obp+i] = v;
NEXT_OP;
}
@@ -412,7 +409,7 @@
NEXT_OP;
OP(OP_ATOMP)
- sp[-1] = iscons(sp[-1]) ? sl_nil : sl_t;
+ sl.sp[-1] = iscons(sl.sp[-1]) ? sl_nil : sl_t;
NEXT_OP;
OP(OP_AREF2) {
@@ -419,17 +416,17 @@
n = 2;
if(0){
OP(OP_AREF)
- SYNC;
+ ENTER;
n = 3 + *ip++;
}
LABEL(apply_aref):;
- sl_v v = sp[-n];
+ sl_v v = sl.sp[-n];
for(int i = n-1; i > 0; i--){
- sl_v e = sp[-i];
+ sl_v e = sl.sp[-i];
usize isz = tosize(e);
if(isarr(v)){
- sp[-i-1] = v;
- v = cvalue_arr_aref(sp-i-1);
+ sl.sp[-i-1] = v;
+ v = cvalue_arr_aref(sl.sp-i-1);
continue;
}
if(isvec(v)){
@@ -450,13 +447,13 @@
bounds_error(v0, e);
}
}
- sp -= n;
- *sp++ = v;
+ sl.sp -= n;
+ PUSH(v);
NEXT_OP;
}
OP(OP_NANP) {
- sl_v v = sp[-1];
+ sl_v v = sl.sp[-1];
if(!iscvalue(v))
v = sl_nil;
else{
@@ -473,43 +470,43 @@
break;
}
}
- sp[-1] = v;
+ sl.sp[-1] = v;
NEXT_OP;
}
OP(OP_LOAD0)
- *sp++ = fixnum(0);
+ PUSH(fixnum(0));
NEXT_OP;
OP(OP_SETCDR) {
- sl_v v = sp[-2];
+ sl_v v = sl.sp[-2];
if(sl_unlikely(!iscons(v))){
- SYNC;
+ ENTER;
type_error("set-cdr!", "cons", v);
}
- cdr_(v) = sp[-1];
- sp--;
+ cdr_(v) = sl.sp[-1];
+ POPN(1);
NEXT_OP;
}
OP(OP_LOADC1)
- *sp++ = vec_elt(bp[nargs], 1);
+ PUSH(vec_elt(sl.stack[obp+nargs], 1));
NEXT_OP;
OP(OP_ASET) {
- SYNC;
- sl_v v = sp[-3];
+ ENTER;
+ sl_v v = sl.sp[-3];
n = 3;
if(0){
LABEL(apply_aset):
- v = sp[-n];
+ v = sl.sp[-n];
for(int i = n-1; i >= 3; i--){
if(isarr(v)){
- sp[-i-1] = v;
- v = cvalue_arr_aref(sp-i-1);
+ sl.sp[-i-1] = v;
+ v = cvalue_arr_aref(sl.sp-i-1);
continue;
}
- sl_v e = sp[-i];
+ sl_v e = sl.sp[-i];
usize isz = tosize(e);
if(isvec(v)){
if(sl_unlikely(isz >= vec_size(v)))
@@ -529,18 +526,18 @@
bounds_error(v0, e);
}
}
- sp[-3] = v;
+ sl.sp[-3] = v;
}
- sl_v e = sp[-2];
+ sl_v e = sl.sp[-2];
usize isz = tosize(e);
if(isvec(v)){
if(sl_unlikely(isz >= vec_size(v)))
bounds_error(v, e);
- vec_elt(v, isz) = (e = sp[-1]);
+ vec_elt(v, isz) = (e = sl.sp[-1]);
}else if(iscons(v)){
for(sl_v v0 = v;; isz--){
if(isz == 0){
- car_(v) = (e = sp[-1]);
+ car_(v) = (e = sl.sp[-1]);
break;
}
v = cdr_(v);
@@ -548,45 +545,45 @@
bounds_error(v0, e);
}
}else if(isarr(v)){
- e = cvalue_arr_aset(sp-3);
+ e = cvalue_arr_aset(sl.sp-3);
}else{
type_error("aset!", "sequence", v);
}
- sp -= n;
- *sp++ = e;
+ sl.sp -= n;
+ PUSH(e);
NEXT_OP;
}
OP(OP_EQUALP) {
- sl_v a = sp[-2], b = sp[-1];
- sp--;
- sp[-1] = (a == b || sl_compare(a, b, true) == 0) ? sl_t : sl_nil;
+ sl_v a = sl.sp[-2], b = sl.sp[-1];
+ POPN(1);
+ sl.sp[-1] = (a == b || sl_compare(a, b, true) == 0) ? sl_t : sl_nil;
NEXT_OP;
}
OP(OP_CONSP)
- sp[-1] = iscons(sp[-1]) ? sl_t : sl_nil;
+ sl.sp[-1] = iscons(sl.sp[-1]) ? sl_t : sl_nil;
NEXT_OP;
OP(OP_LOADC) {
- sl_v v = bp[nargs];
+ sl_v v = sl.stack[obp+nargs];
int i = *ip++;
assert(isvec(v));
assert(i < (int)vec_size(v));
- *sp++ = vec_elt(v, i);
+ PUSH(vec_elt(v, i));
NEXT_OP;
}
OP(OP_SYMP)
- sp[-1] = issym(sp[-1]) ? sl_t : sl_nil;
+ sl.sp[-1] = issym(sl.sp[-1]) ? sl_t : sl_nil;
NEXT_OP;
OP(OP_NUMP)
- sp[-1] = isnum(sp[-1]) ? sl_t : sl_nil;
+ sl.sp[-1] = isnum(sl.sp[-1]) ? sl_t : sl_nil;
NEXT_OP;
OP(OP_BOUNDA)
- *sp++ = bp[GET_S32(ip)] != sl_unbound ? sl_t : sl_nil;
+ PUSH(sl.stack[obp+GET_S32(ip)] != sl_unbound ? sl_t : sl_nil);
ip += 4;
NEXT_OP;
@@ -596,12 +593,12 @@
int x = GET_S32(ip);
ip += 4;
if(sl_unlikely(nargs < i)){
- SYNC;
+ ENTER;
lerrorf(sl_errarg, "too few arguments");
}
if(x > 0){
if(sl_unlikely(nargs > x)){
- SYNC;
+ ENTER;
lerrorf(sl_errarg, "too many arguments");
}
}else
@@ -608,15 +605,15 @@
x = -x;
if(sl_likely(x > nargs)){
x -= nargs;
- sp += x;
- sp[-1] = sp[-x-1];
- sp[-2] = nargs+x;
- sp[-3] = sp[-x-3];
- sp[-4] = sp[-x-4];
- sl.curr_frame = sp;
- ipd = sp-1;
+ sl.sp += x;
+ sl.sp[-1] = sl.sp[-x-1];
+ sl.sp[-2] = nargs+x;
+ sl.sp[-3] = sl.sp[-x-3];
+ sl.sp[-4] = sl.sp[-x-4];
+ sl.curr_frame = sl.sp - sl.stack;
+ ipd = sl.curr_frame - 1;
for(i = 0; i < x; i++)
- bp[nargs+i] = sl_unbound;
+ sl.stack[obp+nargs+i] = sl_unbound;
nargs += x;
}
NEXT_OP;
@@ -623,23 +620,24 @@
}
OP(OP_EQP)
- sp[-2] = sp[-2] == sp[-1] ? sl_t : sl_nil;
- sp--;
+ sl.sp[-2] = sl.sp[-2] == sl.sp[-1] ? sl_t : sl_nil;
+ POPN(1);
NEXT_OP;
OP(OP_LIST) {
n = *ip++;
LABEL(apply_list):;
- sl_v v = list(sp-n, n, false);
- sp -= n;
- *sp++ = v;
+ ENTER;
+ sl_v v = list(sl.sp-n, n, false);
+ sl.sp -= n;
+ PUSH(v);
NEXT_OP;
}
OP(OP_BOUNDP) {
- SYNC;
- sl_sym *sym = tosym(sp[-1]);
- sp[-1] = sym->binding == sl_unbound ? sl_nil : sl_t;
+ ENTER;
+ sl_sym *sym = tosym(sl.sp[-1]);
+ sl.sp[-1] = sym->binding == sl_unbound ? sl_nil : sl_t;
NEXT_OP;
}
@@ -647,10 +645,10 @@
n = *ip++;
LABEL(apply_numeqp):;
int i = n;
- sl_v a = sp[-i], b, v;
+ sl_v a = sl.sp[-i], b, v;
for(v = sl_t; i > 1; a = b){
i--;
- b = sp[-i];
+ b = sl.sp[-i];
if(bothfixnums(a, b)){
if(a != b){
v = sl_nil;
@@ -661,13 +659,13 @@
break;
}
}
- sp -= n;
- *sp++ = v;
+ sl.sp -= n;
+ PUSH(v);
NEXT_OP;
}
OP(OP_CADR) {
- sl_v v = sp[-1];
+ sl_v v = sl.sp[-1];
if(sl_likely(iscons(v))){
v = cdr_(v);
if(sl_likely(iscons(v)))
@@ -677,11 +675,11 @@
}else{
LABEL(cadr_nil):
if(sl_unlikely(v != sl_nil)){
- SYNC;
+ ENTER;
type_error("cadr", "cons", v);
}
}
- sp[-1] = v;
+ sl.sp[-1] = v;
NEXT_OP;
}
@@ -693,58 +691,58 @@
}
n = *ip++;
LABEL(apply_apply):;
- sl_v v = *(--sp); // arglist
- sl_v *p = sp-(n-2); // n-2 == # leading arguments not in the list
+ sl_v v = POP(); // arglist
+ n -= 2; // n-2 == # leading arguments not in the list
while(iscons(v)){
- *sp++ = car_(v);
+ n++;
+ PUSH_SAFE(car_(v));
v = cdr_(v);
}
if(v != sl_nil){
- SYNC;
+ ENTER;
lerrorf(sl_errarg, "apply: last argument: not a list");
}
- n = sp-p;
goto LABEL(do_call);
}
OP(OP_LOADT)
- *sp++ = sl_t;
+ PUSH(sl_t);
NEXT_OP;
OP(OP_BUILTINP) {
- sl_v v = sp[-1];
- sp[-1] = (isbuiltin(v) || iscbuiltin(v)) ? sl_t : sl_nil;
+ sl_v v = sl.sp[-1];
+ sl.sp[-1] = (isbuiltin(v) || iscbuiltin(v)) ? sl_t : sl_nil;
NEXT_OP;
}
OP(OP_NEG) {
LABEL(do_neg):
- SYNC;
- sl_v v = sp[-1];
+ ENTER;
+ sl_v v = sl.sp[-1];
s64int i64;
- sp[-1] = isfixnum(v) ? fixnum_neg(v) : sl_neg(v);
+ sl.sp[-1] = isfixnum(v) ? fixnum_neg(v) : sl_neg(v);
NEXT_OP;
}
OP(OP_FIXNUMP)
- sp[-1] = isfixnum(sp[-1]) ? sl_t : sl_nil;
+ sl.sp[-1] = isfixnum(sl.sp[-1]) ? sl_t : sl_nil;
NEXT_OP;
OP(OP_MUL) {
n = *ip++;
LABEL(apply_mul):
- SYNC;
- sl_v v = sl_mul_any(sp-n, n);
- sp -= n;
- *sp++ = v;
+ ENTER;
+ sl_v v = sl_mul_any(sl.sp-n, n);
+ sl.sp -= n;
+ PUSH(v);
NEXT_OP;
}
OP(OP_DIV0) {
- sl_v a = sp[-2];
- sl_v b = sp[-1];
+ sl_v a = sl.sp[-2];
+ sl_v b = sl.sp[-1];
if(sl_unlikely(b == 0)){
- SYNC;
+ ENTER;
divide_by_0_error();
}
sl_v v;
@@ -751,11 +749,11 @@
if(bothfixnums(a, b))
v = fixnum((sl_fx)a / (sl_fx)b);
else{
- SYNC;
+ ENTER;
v = sl_idiv2(a, b);
}
- sp--;
- sp[-1] = v;
+ POPN(1);
+ sl.sp[-1] = v;
NEXT_OP;
}
@@ -762,20 +760,20 @@
OP(OP_DIV) {
n = *ip++;
LABEL(apply_div):
- SYNC;
- sl_v *p = sp-n;
+ ENTER;
+ sl_v *p = sl.sp-n;
if(n == 1){
- sp[-1] = sl_div2(fixnum(1), *p);
+ sl.sp[-1] = sl_div2(fixnum(1), *p);
}else{
if(sl_unlikely(n > 2)){
- *sp++ = *p;
+ PUSH(*p);
*p = fixnum(1);
p[1] = sl_mul_any(p, n);
- *p = *(--sp);
+ *p = POP();
}
sl_v v = sl_div2(p[0], p[1]);
- sp -= n;
- *sp++ = v;
+ sl.sp -= n;
+ PUSH(v);
}
NEXT_OP;
}
@@ -783,46 +781,45 @@
OP(OP_VEC) {
n = *ip++;
LABEL(apply_vec):;
- SYNC;
+ ENTER;
int type = VEC_VEC;
- sp -= n;
- if(*sp == sl_vecstructsym){
+ sl.sp -= n;
+ if(*sl.sp == sl_vecstructsym){
if(n < 2)
arity_error(n, 2);
- sp++;
+ sl.sp++;
n--;
type = VEC_STRUCT;
}
sl_v v = alloc_vec(n, 0);
- memcpy(&vec_elt(v, 0), sp, n*sizeof(sl_v));
+ memcpy(&vec_elt(v, 0), sl.sp, n*sizeof(sl_v));
if(type != VEC_VEC){
- sp--;
+ POPN(1);
vec_setsize(v, vec_size(v), type);
}
- *sp++ = v;
+ PUSH(v);
NEXT_OP;
}
OP(OP_COMPARE)
- sp[-2] = sl_compare(sp[-2], sp[-1], false);
- sp--;
+ sl.sp[-2] = sl_compare(sl.sp[-2], sl.sp[-1], false);
+ POPN(1);
NEXT_OP;
OP(OP_FOR) {
- SYNC;
- sl_v *p = sp;
+ usize p = sl.sp - sl.stack;
sl_v v;
- sl_fx s = tofixnum(p[-3]);
- sl_fx hi = tofixnum(p[-2]);
- sp += 2;
- SYNC;
+ sl_fx s = tofixnum(sl.stack[p-3]);
+ sl_fx hi = tofixnum(sl.stack[p-2]);
+ sl.sp += 2;
+ ENTER;
for(v = sl_void; s <= hi; s++){
- p[0] = p[-1];
- p[1] = fixnum(s);
+ sl.stack[p+0] = sl.stack[p-1];
+ sl.stack[p+1] = fixnum(s);
v = _applyn(1);
}
- sp -= 4;
- p[1] = v;
+ sl.sp -= 4;
+ sl.stack[p+1] = v;
NEXT_OP;
}
@@ -833,28 +830,28 @@
i = GET_S32(ip);
ip += 4;
}
- sl_v v = fn_vals(bp[-1]);
+ sl_v v = fn_vals(sl.stack[obp-1]);
assert(i < (int)vec_size(v));
v = vec_elt(v, i);
assert(issym(v));
sl_sym *sym = ptr(v);
if(sl_unlikely(isconst(sym))){
- SYNC;
+ ENTER;
const_error(v);
}
- sym->binding = sp[-1];
+ sym->binding = sl.sp[-1];
NEXT_OP;
}
OP(OP_VECP)
- sp[-1] = isvec(sp[-1]) && !isstruct(sp[-1]) ? sl_t : sl_nil;
+ sl.sp[-1] = isvec(sl.sp[-1]) && !isstruct(sl.sp[-1]) ? sl_t : sl_nil;
NEXT_OP;
OP(OP_TRYCATCH) {
- SYNC;
+ ENTER;
sl_v v = do_trycatch();
- sp--;
- sp[-1] = v;
+ POPN(1);
+ sl.sp[-1] = v;
NEXT_OP;
}
@@ -863,28 +860,28 @@
if(n == 2)
goto LABEL(do_add2);
LABEL(apply_add):
- SYNC;
- sl_v v = sl_add_any(sp-n, n);
- sp -= n;
- *sp++ = v;
+ ENTER;
+ sl_v v = sl_add_any(sl.sp-n, n);
+ sl.sp -= n;
+ PUSH(v);
NEXT_OP;
}
OP(OP_LOADAL)
assert(nargs > 0);
- *sp++ = bp[GET_S32(ip)];
+ PUSH(sl.stack[obp+GET_S32(ip)]);
ip += 4;
NEXT_OP;
OP(OP_EQVP) {
- sl_v a = sp[-2], b = sp[-1];
- sp[-2] = (a == b || (leafp(a) && leafp(b) && sl_compare(a, b, true) == 0)) ? sl_t : sl_nil;
- sp--;
+ sl_v a = sl.sp[-2], b = sl.sp[-1];
+ sl.sp[-2] = (a == b || (leafp(a) && leafp(b) && sl_compare(a, b, true) == 0)) ? sl_t : sl_nil;
+ POPN(1);
NEXT_OP;
}
OP(OP_KEYARGS) {
- sl_v v = fn_vals(bp[-1]);
+ sl_v v = fn_vals(sl.stack[obp-1]);
v = vec_elt(v, 0);
int i = GET_S32(ip);
ip += 4;
@@ -892,10 +889,9 @@
ip += 4;
sl_fx s = GET_S32(ip);
ip += 4;
- SYNC;
- nargs = process_keys(v, i, x, labs(s)-(i+x), bp, nargs, s<0);
- sp = sl.sp;
- ipd = sp-1;
+ ENTER;
+ nargs = process_keys(v, i, x, labs(s)-(i+x), obp, nargs, s<0);
+ ipd = sl.sp-sl.stack-1;
NEXT_OP;
}
@@ -906,28 +902,28 @@
goto LABEL(do_sub2);
if(n == 1)
goto LABEL(do_neg);
- SYNC;
- sl_v *p = sp-n;
+ 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
- *sp++ = *p;
+ 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] = *(--sp);
+ p[0] = POP();
v = sl_add_any(p, 2);
- sp -= n;
- *sp++ = v;
+ sl.sp -= n;
+ PUSH(v);
NEXT_OP;
}
OP(OP_BRNL)
- ip += *(--sp) == sl_nil ? GET_S32(ip) : 4;
+ ip += POP() == sl_nil ? GET_S32(ip) : 4;
NEXT_OP;
OP(OP_SETAL)
- bp[GET_S32(ip)] = sp[-1];
+ sl.stack[obp+GET_S32(ip)] = sl.sp[-1];
ip += 4;
NEXT_OP;
@@ -934,16 +930,16 @@
OP(OP_BOXL) {
int i = GET_S32(ip);
ip += 4;
- SYNC;
+ ENTER;
sl_v v = alloc_cons();
- car_(v) = bp[i];
+ car_(v) = sl.stack[obp+i];
cdr_(v) = sl_nil;
- bp[i] = v;
+ sl.stack[obp+i] = v;
NEXT_OP;
}
OP(OP_FNP)
- sp[-1] = isfn(sp[-1]) ? sl_t : sl_nil;
+ sl.sp[-1] = isfn(sl.sp[-1]) ? sl_t : sl_nil;
NEXT_OP;
OP(OP_JMPL)
@@ -951,27 +947,27 @@
NEXT_OP;
OP(OP_BRNEL)
- ip += sp[-2] != sp[-1] ? GET_S32(ip) : 4;
- sp -= 2;
+ ip += sl.sp[-2] != sl.sp[-1] ? GET_S32(ip) : 4;
+ sl.sp -= 2;
NEXT_OP;
OP(OP_BRNNL)
- ip += *(--sp) != sl_nil ? GET_S32(ip) : 4;
+ ip += POP() != sl_nil ? GET_S32(ip) : 4;
NEXT_OP;
OP(OP_LOADCL)
ip += 4;
- *sp++ = vec_elt(bp[nargs], GET_S32(ip));
+ PUSH(vec_elt(sl.stack[obp+nargs], GET_S32(ip)));
ip += 4;
NEXT_OP;
OP(OP_LOADVL) {
- sl_v v = fn_vals(bp[-1]);
+ sl_v v = fn_vals(sl.stack[obp-1]);
v = vec_elt(v, GET_S32(ip));
ip += 4;
- *sp++ = v;
+ PUSH(v);
NEXT_OP;
}
#undef fixnum_neg
-#undef SYNC
+#undef ENTER
--- a/test/mkfile
+++ b/test/mkfile
@@ -16,5 +16,5 @@
test:QV:
for(t in $TESTS){
echo $t
- ../$O.out -S 8m $t
+ ../$O.out $t
}
--- a/tools/bootstrap.sh
+++ b/tools/bootstrap.sh
@@ -11,5 +11,5 @@
$WRAPPER $F ../tools/mkboot0.sl builtins.sl instructions.sl system.sl compiler.sl > ../boot/sl.boot && \
ninja -C ../build && \
cd ../boot && \
-$WRAPPER $F -S 8m ../tools/mkboot1.sl && \
+$WRAPPER $F ../tools/mkboot1.sl && \
ninja -C ../build || { cp "$P/boot/sl.boot.bak" "$P/boot/sl.boot"; exit 1; }