some optimizations
This commit is contained in:
parent
ad4a086790
commit
0a3590aa01
|
@ -771,6 +771,7 @@ static value_t do_trycatch(value_t expr, value_t *penv, uint32_t envsz)
|
||||||
|
|
||||||
static value_t do_trycatch2()
|
static value_t do_trycatch2()
|
||||||
{
|
{
|
||||||
|
uint32_t saveSP = SP;
|
||||||
value_t v;
|
value_t v;
|
||||||
value_t thunk = Stack[SP-2];
|
value_t thunk = Stack[SP-2];
|
||||||
Stack[SP-2] = Stack[SP-1];
|
Stack[SP-2] = Stack[SP-1];
|
||||||
|
@ -783,6 +784,7 @@ static value_t do_trycatch2()
|
||||||
Stack[SP-1] = lasterror;
|
Stack[SP-1] = lasterror;
|
||||||
v = apply_cl(1);
|
v = apply_cl(1);
|
||||||
}
|
}
|
||||||
|
SP = saveSP;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1426,7 +1428,9 @@ static value_t eval_sexpr(value_t e, value_t *penv, int tail, uint32_t envsz)
|
||||||
assert(SP > bp+1);
|
assert(SP > bp+1);
|
||||||
if (__likely(iscons(f))) {
|
if (__likely(iscons(f))) {
|
||||||
if (car_(f) == COMPILEDLAMBDA) {
|
if (car_(f) == COMPILEDLAMBDA) {
|
||||||
|
i = SP;
|
||||||
e = apply_cl(nargs);
|
e = apply_cl(nargs);
|
||||||
|
SP = i;
|
||||||
if (noeval == 2) {
|
if (noeval == 2) {
|
||||||
if (selfevaluating(e)) { SP=saveSP; return(e); }
|
if (selfevaluating(e)) { SP=saveSP; return(e); }
|
||||||
noeval = 0;
|
noeval = 0;
|
||||||
|
@ -1510,12 +1514,12 @@ static value_t eval_sexpr(value_t e, value_t *penv, int tail, uint32_t envsz)
|
||||||
- provide arg count
|
- provide arg count
|
||||||
- respect tail position
|
- respect tail position
|
||||||
- call correct entry point (either eval_sexpr or apply_cl)
|
- call correct entry point (either eval_sexpr or apply_cl)
|
||||||
|
- restore SP
|
||||||
|
|
||||||
callee's responsibility:
|
callee's responsibility:
|
||||||
- check arg counts
|
- check arg counts
|
||||||
- allocate vararg array
|
- allocate vararg array
|
||||||
- push closed env, set up new environment
|
- push closed env, set up new environment
|
||||||
- restore SP
|
|
||||||
|
|
||||||
** need 'copyenv' instruction that moves env to heap, installs
|
** need 'copyenv' instruction that moves env to heap, installs
|
||||||
heap version as the current env, and pushes the result vector.
|
heap version as the current env, and pushes the result vector.
|
||||||
|
@ -1525,34 +1529,31 @@ static value_t eval_sexpr(value_t e, value_t *penv, int tail, uint32_t envsz)
|
||||||
*/
|
*/
|
||||||
static value_t apply_cl(uint32_t nargs)
|
static value_t apply_cl(uint32_t nargs)
|
||||||
{
|
{
|
||||||
uint32_t i, n, ip, bp, envsz, saveSP=SP;
|
uint32_t i, n, ip, bp, envsz, captured;
|
||||||
fixnum_t s, lo, hi;
|
fixnum_t s, lo, hi;
|
||||||
int64_t accum;
|
int64_t accum;
|
||||||
uint8_t op, *code;
|
uint8_t op, *code;
|
||||||
value_t func, v, bcode, x, e, ftl;
|
value_t func, v, bcode, x, e;
|
||||||
value_t *penv, *pvals, *lenv, *pv;
|
value_t *pvals, *lenv, *pv;
|
||||||
symbol_t *sym;
|
symbol_t *sym;
|
||||||
cons_t *c;
|
cons_t *c;
|
||||||
|
|
||||||
apply_cl_top:
|
apply_cl_top:
|
||||||
|
captured = 0;
|
||||||
func = Stack[SP-nargs-1];
|
func = Stack[SP-nargs-1];
|
||||||
assert(iscons(func));
|
assert(iscons(func));
|
||||||
assert(iscons(cdr_(func)));
|
assert(iscons(cdr_(func)));
|
||||||
assert(iscons(cdr_(cdr_(func))));
|
assert(iscons(cdr_(cdr_(func))));
|
||||||
ftl = cdr_(cdr_(func));
|
x = cdr_(cdr_(func));
|
||||||
bcode = car_(ftl);
|
bcode = car_(x);
|
||||||
code = cv_data((cvalue_t*)ptr(car_(bcode)));
|
code = cv_data((cvalue_t*)ptr(car_(bcode)));
|
||||||
assert(!ismanaged((uptrint_t)code));
|
assert(!ismanaged((uptrint_t)code));
|
||||||
if (nargs < code[1])
|
if (nargs < code[1])
|
||||||
lerror(ArgError, "apply: too few arguments");
|
lerror(ArgError, "apply: too few arguments");
|
||||||
|
|
||||||
bp = SP-nargs;
|
bp = SP-nargs;
|
||||||
x = cdr_(ftl); // cloenv
|
x = cdr_(x); // cloenv
|
||||||
Stack[bp-1] = car_(cdr_(func)); // lambda list
|
|
||||||
penv = &Stack[bp-1];
|
|
||||||
PUSH(x);
|
PUSH(x);
|
||||||
// must keep a reference to the bcode object while executing it
|
|
||||||
PUSH(bcode);
|
|
||||||
PUSH(cdr_(bcode));
|
PUSH(cdr_(bcode));
|
||||||
pvals = &Stack[SP-1];
|
pvals = &Stack[SP-1];
|
||||||
|
|
||||||
|
@ -1579,15 +1580,13 @@ static value_t apply_cl(uint32_t nargs)
|
||||||
Stack[bp+i] = v;
|
Stack[bp+i] = v;
|
||||||
Stack[bp+i+1] = Stack[bp+nargs];
|
Stack[bp+i+1] = Stack[bp+nargs];
|
||||||
Stack[bp+i+2] = Stack[bp+nargs+1];
|
Stack[bp+i+2] = Stack[bp+nargs+1];
|
||||||
Stack[bp+i+3] = Stack[bp+nargs+2];
|
pvals = &Stack[bp+nargs+1];
|
||||||
pvals = &Stack[bp+nargs+2];
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PUSH(NIL);
|
PUSH(NIL);
|
||||||
Stack[SP-1] = Stack[SP-2];
|
Stack[SP-1] = Stack[SP-2];
|
||||||
Stack[SP-2] = Stack[SP-3];
|
Stack[SP-2] = Stack[SP-3];
|
||||||
Stack[SP-3] = Stack[SP-4];
|
Stack[SP-3] = NIL;
|
||||||
Stack[SP-4] = NIL;
|
|
||||||
pvals = &Stack[SP-1];
|
pvals = &Stack[SP-1];
|
||||||
}
|
}
|
||||||
nargs = i+1;
|
nargs = i+1;
|
||||||
|
@ -1656,7 +1655,7 @@ static value_t apply_cl(uint32_t nargs)
|
||||||
if (v != FL_F) ip = *(uint32_t*)&code[ip];
|
if (v != FL_F) ip = *(uint32_t*)&code[ip];
|
||||||
else ip += 4;
|
else ip += 4;
|
||||||
break;
|
break;
|
||||||
case OP_RET: v = POP(); SP = saveSP; return v;
|
case OP_RET: v = POP(); return v;
|
||||||
|
|
||||||
case OP_EQ:
|
case OP_EQ:
|
||||||
Stack[SP-2] = ((Stack[SP-2] == Stack[SP-1]) ? FL_T : FL_F);
|
Stack[SP-2] = ((Stack[SP-2] == Stack[SP-1]) ? FL_T : FL_F);
|
||||||
|
@ -1962,10 +1961,12 @@ static value_t apply_cl(uint32_t nargs)
|
||||||
//f = Stack[SP-1];
|
//f = Stack[SP-1];
|
||||||
v = FL_F;
|
v = FL_F;
|
||||||
SP += 2;
|
SP += 2;
|
||||||
|
i = SP;
|
||||||
for(s=lo; s <= hi; s++) {
|
for(s=lo; s <= hi; s++) {
|
||||||
Stack[SP-2] = Stack[SP-3];
|
Stack[SP-2] = Stack[SP-3];
|
||||||
Stack[SP-1] = fixnum(s);
|
Stack[SP-1] = fixnum(s);
|
||||||
v = apply_cl(1);
|
v = apply_cl(1);
|
||||||
|
SP = i;
|
||||||
}
|
}
|
||||||
POPN(4);
|
POPN(4);
|
||||||
Stack[SP-1] = v;
|
Stack[SP-1] = v;
|
||||||
|
@ -2017,10 +2018,11 @@ static value_t apply_cl(uint32_t nargs)
|
||||||
case OP_LOADA:
|
case OP_LOADA:
|
||||||
assert(nargs > 0);
|
assert(nargs > 0);
|
||||||
i = code[ip++];
|
i = code[ip++];
|
||||||
if (penv[0] == NIL) {
|
if (captured) {
|
||||||
assert(isvector(penv[1]));
|
x = Stack[bp];
|
||||||
assert(i+1 < vector_size(penv[1]));
|
assert(isvector(x));
|
||||||
v = vector_elt(penv[1], i+1);
|
assert(i < vector_size(x));
|
||||||
|
v = vector_elt(x, i);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(bp+i < SP);
|
assert(bp+i < SP);
|
||||||
|
@ -2032,10 +2034,11 @@ static value_t apply_cl(uint32_t nargs)
|
||||||
assert(nargs > 0);
|
assert(nargs > 0);
|
||||||
v = Stack[SP-1];
|
v = Stack[SP-1];
|
||||||
i = code[ip++];
|
i = code[ip++];
|
||||||
if (penv[0] == NIL) {
|
if (captured) {
|
||||||
assert(isvector(penv[1]));
|
x = Stack[bp];
|
||||||
assert(i+1 < vector_size(penv[1]));
|
assert(isvector(x));
|
||||||
vector_elt(penv[1], i+1) = v;
|
assert(i < vector_size(x));
|
||||||
|
vector_elt(x, i) = v;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(bp+i < SP);
|
assert(bp+i < SP);
|
||||||
|
@ -2045,16 +2048,16 @@ static value_t apply_cl(uint32_t nargs)
|
||||||
case OP_LOADC:
|
case OP_LOADC:
|
||||||
case OP_SETC:
|
case OP_SETC:
|
||||||
s = code[ip++];
|
s = code[ip++];
|
||||||
i = code[ip++]+1;
|
i = code[ip++];
|
||||||
if (penv[0]==NIL) {
|
if (captured) {
|
||||||
if (nargs > 0) {
|
if (nargs > 0) {
|
||||||
// current frame has been captured
|
// current frame has been captured
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
v = penv[1];
|
v = Stack[bp];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v = penv[nargs+1];
|
v = Stack[bp+nargs];
|
||||||
}
|
}
|
||||||
while (s--)
|
while (s--)
|
||||||
v = vector_elt(v, vector_size(v)-1);
|
v = vector_elt(v, vector_size(v)-1);
|
||||||
|
@ -2068,10 +2071,10 @@ static value_t apply_cl(uint32_t nargs)
|
||||||
|
|
||||||
case OP_CLOSURE:
|
case OP_CLOSURE:
|
||||||
// build a closure (lambda args body . env)
|
// build a closure (lambda args body . env)
|
||||||
if (penv[0] != NIL) {
|
if (nargs > 0 && !captured) {
|
||||||
// save temporary environment to the heap
|
// save temporary environment to the heap
|
||||||
lenv = penv;
|
lenv = &Stack[bp];
|
||||||
envsz = nargs+2;
|
envsz = nargs+1;
|
||||||
pv = alloc_words(envsz + 1);
|
pv = alloc_words(envsz + 1);
|
||||||
PUSH(tagptr(pv, TAG_VECTOR));
|
PUSH(tagptr(pv, TAG_VECTOR));
|
||||||
pv[0] = fixnum(envsz);
|
pv[0] = fixnum(envsz);
|
||||||
|
@ -2080,11 +2083,11 @@ static value_t apply_cl(uint32_t nargs)
|
||||||
*pv++ = *lenv++;
|
*pv++ = *lenv++;
|
||||||
// environment representation changed; install
|
// environment representation changed; install
|
||||||
// the new representation so everybody can see it
|
// the new representation so everybody can see it
|
||||||
penv[0] = NIL;
|
captured = 1;
|
||||||
penv[1] = Stack[SP-1];
|
Stack[bp] = Stack[SP-1];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PUSH(penv[1]); // env has already been captured; share
|
PUSH(Stack[bp]); // env has already been captured; share
|
||||||
}
|
}
|
||||||
c = (cons_t*)ptr(v=cons_reserve(3));
|
c = (cons_t*)ptr(v=cons_reserve(3));
|
||||||
e = cdr_(Stack[SP-2]); // closure to copy
|
e = cdr_(Stack[SP-2]); // closure to copy
|
||||||
|
|
Loading…
Reference in New Issue