ref: e7ec1e13f5e1814f647bcbc18e73eb6be5ce4f16
dir: /vm.inc/
OP(OP_LOADA0)
PUSH(FL(stack)[bp]);
NEXT_OP;
OP(OP_LOADA1)
PUSH(FL(stack)[bp+1]);
NEXT_OP;
OP(OP_LOADV)
v = fn_vals(FL(stack)[bp-1]);
assert(*ip < vector_size(v));
PUSH(vector_elt(v, *ip++));
NEXT_OP;
OP(OP_BRF)
ip += POP() != FL_f ? 2 : GET_INT16(ip);
NEXT_OP;
OP(OP_POP)
POPN(1);
NEXT_OP;
OP(OP_TCALLL)
tail = true;
if(0){
OP(OP_CALLL)
tail = false;
}
n = GET_INT32(ip);
ip += 4;
if(0){
OP(OP_TCALL)
tail = true;
if(0){
OP(OP_CALL)
tail = false;
}
n = *ip++; // nargs
}
LABEL(do_call):
FL(stack)[ipd] = (uintptr_t)ip;
func = FL(stack)[FL(sp)-n-1];
if(tag(func) == TAG_FUNCTION){
if(func > (N_BUILTINS<<3)){
if(tail){
FL(curr_frame) = FL(stack)[FL(curr_frame)-3];
for(s = -1; s < (fixnum_t)n; s++)
FL(stack)[bp+s] = FL(stack)[FL(sp)-n+s];
FL(sp) = bp+n;
}
nargs = n;
goto apply_cl_top;
}else{
i = uintval(func);
if(isbuiltin(func)){
s = builtins[i].nargs;
if(s >= 0)
argcount(n, (unsigned)s);
else if(s != ANYARGS && (signed)n < -s)
argcount(n, (unsigned)-s);
// remove function arg
for(s = FL(sp)-n-1; s < (int)FL(sp)-1; s++)
FL(stack)[s] = FL(stack)[s+1];
FL(sp)--;
switch(i){
case OP_LIST: goto LABEL(apply_list);
case OP_VECTOR: goto LABEL(apply_vector);
case OP_APPLY: goto LABEL(apply_apply);
case OP_ADD: goto LABEL(apply_add);
case OP_SUB: goto LABEL(apply_sub);
case OP_MUL: goto LABEL(apply_mul);
case OP_DIV: goto LABEL(apply_div);
case OP_AREF: goto LABEL(apply_aref);
case OP_ASET: goto LABEL(apply_aset);
case OP_LT: goto LABEL(apply_lt);
case OP_NUMEQ: goto LABEL(apply_numeq);
default:
#if defined(COMPUTED_GOTO)
goto *ops[i];
#else
op = i;
continue;
#endif
}
}
}
}else if(__likely(iscbuiltin(func))){
s = FL(sp) - n;
v = (((builtin_t*)ptr(func))[3])(&FL(stack)[s], n);
FL(sp) = s;
FL(stack)[s-1] = v;
NEXT_OP;
}
type_error("function", func);
OP(OP_LOADGL)
v = fn_vals(FL(stack)[bp-1]);
v = vector_elt(v, GET_INT32(ip));
ip += 4;
if(0){
OP(OP_LOADG)
v = fn_vals(FL(stack)[bp-1]);
assert(*ip < vector_size(v));
v = vector_elt(v, *ip);
ip++;
}
assert(issymbol(v));
sym = (symbol_t*)ptr(v);
if(__unlikely(sym->binding == UNBOUND)){
FL(stack)[ipd] = (uintptr_t)ip;
unbound_error(v);
}
PUSH(sym->binding);
NEXT_OP;
OP(OP_LOADA)
i = *ip++;
v = FL(stack)[bp+i];
PUSH(v);
NEXT_OP;
OP(OP_LOADC)
i = *ip++;
v = FL(stack)[bp+nargs];
assert(isvector(v));
assert(i < vector_size(v));
PUSH(vector_elt(v, i));
NEXT_OP;
OP(OP_BOX)
i = *ip++;
v = mk_cons();
car_(v) = FL(stack)[bp+i];
cdr_(v) = FL_nil;
FL(stack)[bp+i] = v;
NEXT_OP;
OP(OP_BOXL)
i = GET_INT32(ip); ip += 4;
v = mk_cons();
car_(v) = FL(stack)[bp+i];
cdr_(v) = FL_nil;
FL(stack)[bp+i] = v;
NEXT_OP;
OP(OP_SHIFT)
i = *ip++;
FL(stack)[FL(sp)-1-i] = FL(stack)[FL(sp)-1];
FL(sp) -= i;
NEXT_OP;
OP(OP_RET)
v = POP();
FL(sp) = FL(curr_frame);
FL(curr_frame) = FL(stack)[FL(sp)-3];
if(FL(curr_frame) == top_frame)
return v;
FL(sp) -= 4+nargs;
ipd = FL(curr_frame)-1;
ip = (uint8_t*)FL(stack)[ipd];
nargs = FL(stack)[FL(curr_frame)-2];
bp = FL(curr_frame) - 4 - nargs;
FL(stack)[FL(sp)-1] = v;
NEXT_OP;
OP(OP_DUP)
FL(stack)[FL(sp)] = FL(stack)[FL(sp)-1];
FL(sp)++;
NEXT_OP;
OP(OP_CAR)
v = FL(stack)[FL(sp)-1];
if(__likely(iscons(v)))
v = car_(v);
else if(__unlikely(v != FL_nil)){
FL(stack)[ipd] = (uintptr_t)ip;
type_error("cons", v);
}
FL(stack)[FL(sp)-1] = v;
NEXT_OP;
OP(OP_CDR)
v = FL(stack)[FL(sp)-1];
if(__likely(iscons(v)))
v = cdr_(v);
else if(__unlikely(v != FL_nil)){
FL(stack)[ipd] = (uintptr_t)ip;
type_error("cons", v);
}
FL(stack)[FL(sp)-1] = v;
NEXT_OP;
OP(OP_CLOSURE)
n = *ip++;
assert(n > 0);
pv = alloc_words(n + 1);
v = tagptr(pv, TAG_VECTOR);
i = 0;
pv[i++] = fixnum(n);
do{
pv[i] = FL(stack)[FL(sp)-n + i-1];
i++;
}while(i <= n);
POPN(n);
PUSH(v);
if(__unlikely((value_t*)FL(curheap) > (value_t*)FL(lim)-2))
gc(0);
pv = (value_t*)FL(curheap);
FL(curheap) += 4*sizeof(value_t);
e = FL(stack)[FL(sp)-2]; // closure to copy
assert(isfunction(e));
pv[0] = ((value_t*)ptr(e))[0];
pv[1] = ((value_t*)ptr(e))[1];
pv[2] = FL(stack)[FL(sp)-1]; // env
pv[3] = ((value_t*)ptr(e))[3];
POPN(1);
FL(stack)[FL(sp)-1] = tagptr(pv, TAG_FUNCTION);
NEXT_OP;
OP(OP_SETA)
v = FL(stack)[FL(sp)-1];
i = *ip++;
FL(stack)[bp+i] = v;
NEXT_OP;
OP(OP_JMP)
ip += GET_INT16(ip);
NEXT_OP;
OP(OP_LOADC0)
PUSH(vector_elt(FL(stack)[bp+nargs], 0));
NEXT_OP;
OP(OP_CONSP)
FL(stack)[FL(sp)-1] = iscons(FL(stack)[FL(sp)-1]) ? FL_t : FL_f;
NEXT_OP;
OP(OP_BRNE)
ip += FL(stack)[FL(sp)-2] != FL(stack)[FL(sp)-1] ? GET_INT16(ip) : 2;
POPN(2);
NEXT_OP;
OP(OP_LOADT)
PUSH(FL_t);
NEXT_OP;
OP(OP_LOADVOID)
PUSH(FL_void);
NEXT_OP;
OP(OP_LOAD0)
PUSH(fixnum(0));
NEXT_OP;
OP(OP_LOADC1)
PUSH(vector_elt(FL(stack)[bp+nargs], 1));
NEXT_OP;
OP(OP_AREF2)
n = 2;
if(0){
OP(OP_AREF)
FL(stack)[ipd] = (uintptr_t)ip;
n = 3 + *ip++;
}
LABEL(apply_aref):
v = FL(stack)[FL(sp)-n];
for(i = n-1; i > 0; i--){
if(isarray(v)){
FL(stack)[FL(sp)-i-1] = v;
v = cvalue_array_aref(&FL(stack)[FL(sp)-i-1]);
continue;
}
e = FL(stack)[FL(sp)-i];
isz = tosize(e);
if(isvector(v)){
if(__unlikely(isz >= vector_size(v)))
bounds_error(v, e);
v = vector_elt(v, isz);
continue;
}
if(!iscons(v) && v != FL_nil)
type_error("sequence", v);
for(value_t v0 = v;; isz--){
if(isz == 0){
v = car_(v);
break;
}
v = cdr_(v);
if(__unlikely(!iscons(v)))
bounds_error(v0, e);
}
}
POPN(n);
PUSH(v);
NEXT_OP;
OP(OP_ATOMP)
FL(stack)[FL(sp)-1] = iscons(FL(stack)[FL(sp)-1]) ? FL_f : FL_t;
NEXT_OP;
OP(OP_BRT)
ip += POP() != FL_f ? GET_INT16(ip) : 2;
NEXT_OP;
OP(OP_BRNN)
ip += POP() != FL_nil ? GET_INT16(ip) : 2;
NEXT_OP;
OP(OP_LOAD1)
PUSH(fixnum(1));
NEXT_OP;
OP(OP_LT)
n = *ip++;
LABEL(apply_lt):
{
i = n;
value_t a = FL(stack)[FL(sp)-i], b;
for(v = FL_t; i > 1; a = b){
i--;
b = FL(stack)[FL(sp)-i];
if(bothfixnums(a, b)){
if((fixnum_t)a >= (fixnum_t)b){
v = FL_f;
break;
}
}else{
x = numeric_compare(a, b, false, false, false);
if(x > 1)
x = numval(fl_compare(a, b));
if(x >= 0){
v = FL_f;
break;
}
}
}
POPN(n);
PUSH(v);
}
NEXT_OP;
OP(OP_ADD2)
LABEL(do_add2):
FL(stack)[ipd] = (uintptr_t)ip;
if(0){
OP(OP_SUB2)
LABEL(do_sub2):
FL(stack)[ipd] = (uintptr_t)ip;
FL(stack)[FL(sp)-1] = fl_neg(FL(stack)[FL(sp)-1]);
}
{
value_t a, b, q;
a = FL(stack)[FL(sp)-2];
b = FL(stack)[FL(sp)-1];
if(bothfixnums(a, b) && !sadd_overflow(numval(a), numval(b), &q) && fits_fixnum(q)){
v = fixnum(q);
}else{
v = fl_add_any(&FL(stack)[FL(sp)-2], 2);
}
}
POPN(1);
FL(stack)[FL(sp)-1] = v;
NEXT_OP;
OP(OP_SETCDR)
v = FL(stack)[FL(sp)-2];
if(__unlikely(!iscons(v))){
FL(stack)[ipd] = (uintptr_t)ip;
type_error("cons", v);
}
cdr_(v) = FL(stack)[FL(sp)-1];
POPN(1);
NEXT_OP;
OP(OP_LOADF)
PUSH(FL_f);
NEXT_OP;
OP(OP_CONS)
if(FL(curheap) > FL(lim))
gc(0);
c = (cons_t*)FL(curheap);
FL(curheap) += sizeof(cons_t);
c->car = FL(stack)[FL(sp)-2];
c->cdr = FL(stack)[FL(sp)-1];
FL(stack)[FL(sp)-2] = tagptr(c, TAG_CONS);
POPN(1);
NEXT_OP;
OP(OP_EQ)
FL(stack)[FL(sp)-2] = FL(stack)[FL(sp)-2] == FL(stack)[FL(sp)-1] ? FL_t : FL_f;
POPN(1);
NEXT_OP;
OP(OP_SYMBOLP)
FL(stack)[FL(sp)-1] = issymbol(FL(stack)[FL(sp)-1]) ? FL_t : FL_f;
NEXT_OP;
OP(OP_NOT)
FL(stack)[FL(sp)-1] = FL(stack)[FL(sp)-1] == FL_f ? FL_t : FL_f;
NEXT_OP;
OP(OP_CADR)
v = FL(stack)[FL(sp)-1];
if(__likely(iscons(v))){
v = cdr_(v);
if(__likely(iscons(v)))
v = car_(v);
else
goto LABEL(cadr_nil);
}else{
LABEL(cadr_nil):
if(__unlikely(v != FL_nil)){
FL(stack)[ipd] = (uintptr_t)ip;
type_error("cons", v);
}
}
FL(stack)[FL(sp)-1] = v;
NEXT_OP;
OP(OP_NEG)
LABEL(do_neg):
FL(stack)[ipd] = (uintptr_t)ip;
FL(stack)[FL(sp)-1] = fl_neg(FL(stack)[FL(sp)-1]);
NEXT_OP;
OP(OP_NANP)
{
value_t q = FL(stack)[FL(sp)-1];
v = FL_f;
if(iscprim(q)){
void *data = cp_data(ptr(q));
switch(cp_numtype(ptr(q))){
case T_DOUBLE:
if(isnan(*(double*)data))
v = FL_t;
break;
case T_FLOAT:
if(isnan(*(float*)data))
v = FL_t;
break;
default:
break;
}
}
FL(stack)[FL(sp)-1] = v;
}
NEXT_OP;
OP(OP_NULLP)
FL(stack)[FL(sp)-1] = FL(stack)[FL(sp)-1] == FL_nil ? FL_t : FL_f;
NEXT_OP;
OP(OP_BOOLEANP)
v = FL(stack)[FL(sp)-1];
FL(stack)[FL(sp)-1] = (v == FL_t || v == FL_f) ? FL_t : FL_f;
NEXT_OP;
OP(OP_NUMBERP)
v = FL(stack)[FL(sp)-1];
FL(stack)[FL(sp)-1] = fl_isnumber(v) ? FL_t : FL_f;
NEXT_OP;
OP(OP_FIXNUMP)
FL(stack)[FL(sp)-1] = isfixnum(FL(stack)[FL(sp)-1]) ? FL_t : FL_f;
NEXT_OP;
OP(OP_BOUNDP)
FL(stack)[ipd] = (uintptr_t)ip;
sym = tosymbol(FL(stack)[FL(sp)-1]);
FL(stack)[FL(sp)-1] = sym->binding == UNBOUND ? FL_f : FL_t;
NEXT_OP;
OP(OP_BUILTINP)
v = FL(stack)[FL(sp)-1];
FL(stack)[FL(sp)-1] = (isbuiltin(v) || iscbuiltin(v)) ? FL_t : FL_f;
NEXT_OP;
OP(OP_FUNCTIONP)
v = FL(stack)[FL(sp)-1];
FL(stack)[FL(sp)-1] =
((tag(v) == TAG_FUNCTION &&
(isbuiltin(v) || v>(N_BUILTINS<<3))) ||
iscbuiltin(v)) ? FL_t : FL_f;
NEXT_OP;
OP(OP_VECTORP)
FL(stack)[FL(sp)-1] = isvector(FL(stack)[FL(sp)-1]) ? FL_t : FL_f;
NEXT_OP;
OP(OP_JMPL)
ip += GET_INT32(ip);
NEXT_OP;
OP(OP_BRFL)
ip += POP() == FL_f ? GET_INT32(ip) : 4;
NEXT_OP;
OP(OP_BRTL)
ip += POP() != FL_f ? GET_INT32(ip) : 4;
NEXT_OP;
OP(OP_BRNEL)
ip += FL(stack)[FL(sp)-2] != FL(stack)[FL(sp)-1] ? GET_INT32(ip) : 4;
POPN(2);
NEXT_OP;
OP(OP_BRNNL)
ip += POP() != FL_nil ? GET_INT32(ip) : 4;
NEXT_OP;
OP(OP_BRN)
ip += POP() == FL_nil ? GET_INT16(ip) : 2;
NEXT_OP;
OP(OP_BRNL)
ip += POP() == FL_nil ? GET_INT32(ip) : 4;
NEXT_OP;
OP(OP_EQV)
if(FL(stack)[FL(sp)-2] == FL(stack)[FL(sp)-1])
v = FL_t;
else if(!leafp(FL(stack)[FL(sp)-2]) || !leafp(FL(stack)[FL(sp)-1]))
v = FL_f;
else
v = compare_(FL(stack)[FL(sp)-2], FL(stack)[FL(sp)-1], 1) == 0 ? FL_t : FL_f;
FL(stack)[FL(sp)-2] = v;
POPN(1);
NEXT_OP;
OP(OP_EQUAL)
if(FL(stack)[FL(sp)-2] == FL(stack)[FL(sp)-1])
v = FL_t;
else
v = compare_(FL(stack)[FL(sp)-2], FL(stack)[FL(sp)-1], 1) == 0 ? FL_t : FL_f;
FL(stack)[FL(sp)-2] = v;
POPN(1);
NEXT_OP;
OP(OP_SETCAR)
v = FL(stack)[FL(sp)-2];
if(__unlikely(!iscons(v))){
FL(stack)[ipd] = (uintptr_t)ip;
type_error("cons", v);
}
car_(v) = FL(stack)[FL(sp)-1];
POPN(1);
NEXT_OP;
OP(OP_LIST)
n = *ip++;
LABEL(apply_list):
if(n > 0){
v = list(&FL(stack)[FL(sp)-n], n, 0);
POPN(n);
PUSH(v);
}else{
PUSH(FL_nil);
}
NEXT_OP;
OP(OP_TAPPLY)
tail = true;
if(0){
OP(OP_APPLY)
tail = false;
}
n = *ip++;
LABEL(apply_apply):
v = POP(); // arglist
n = FL(sp)-(n-2); // n-2 == # leading arguments not in the list
while(iscons(v)){
if(FL(sp) >= FL(nstack))
grow_stack();
PUSH(car_(v));
v = cdr_(v);
}
if(v != FL_nil){
FL(stack)[ipd] = (uintptr_t)ip;
lerrorf(FL_ArgError, "apply: last argument: not a list");
}
n = FL(sp)-n;
goto LABEL(do_call);
OP(OP_ADD)
n = *ip++;
if(n == 2)
goto LABEL(do_add2);
LABEL(apply_add):
FL(stack)[ipd] = (uintptr_t)ip;
v = fl_add_any(&FL(stack)[FL(sp)-n], n);
POPN(n);
PUSH(v);
NEXT_OP;
OP(OP_SUB)
n = *ip++;
LABEL(apply_sub):
if(n == 2)
goto LABEL(do_sub2);
if(n == 1)
goto LABEL(do_neg);
FL(stack)[ipd] = (uintptr_t)ip;
i = FL(sp)-n;
// we need to pass the full arglist on to fl_add_any
// so it can handle rest args properly
PUSH(FL(stack)[i]);
FL(stack)[i] = fixnum(0);
FL(stack)[i+1] = fl_neg(fl_add_any(&FL(stack)[i], n));
FL(stack)[i] = POP();
v = fl_add_any(&FL(stack)[i], 2);
POPN(n);
PUSH(v);
NEXT_OP;
OP(OP_MUL)
n = *ip++;
LABEL(apply_mul):
FL(stack)[ipd] = (uintptr_t)ip;
v = fl_mul_any(&FL(stack)[FL(sp)-n], n);
POPN(n);
PUSH(v);
NEXT_OP;
OP(OP_DIV)
n = *ip++;
LABEL(apply_div):
FL(stack)[ipd] = (uintptr_t)ip;
i = FL(sp)-n;
if(n == 1){
FL(stack)[FL(sp)-1] = fl_div2(fixnum(1), FL(stack)[i]);
}else{
if(n > 2){
PUSH(FL(stack)[i]);
FL(stack)[i] = fixnum(1);
FL(stack)[i+1] = fl_mul_any(&FL(stack)[i], n);
FL(stack)[i] = POP();
}
v = fl_div2(FL(stack)[i], FL(stack)[i+1]);
POPN(n);
PUSH(v);
}
NEXT_OP;
OP(OP_IDIV)
{
value_t a = FL(stack)[FL(sp)-2];
value_t b = FL(stack)[FL(sp)-1];
if(bothfixnums(a, b)){
if(b == 0){
FL(stack)[ipd] = (uintptr_t)ip;
DivideByZeroError();
}
v = fixnum(numval(a) / numval(b));
}else{
FL(stack)[ipd] = (uintptr_t)ip;
v = fl_idiv2(a, b);
}
POPN(1);
FL(stack)[FL(sp)-1] = v;
}
NEXT_OP;
OP(OP_NUMEQ)
n = *ip++;
LABEL(apply_numeq):
{
i = n;
value_t a = FL(stack)[FL(sp)-i], b;
for(v = FL_t; i > 1; a = b){
i--;
b = FL(stack)[FL(sp)-i];
if(bothfixnums(a, b)){
if((fixnum_t)a != (fixnum_t)b){
v = FL_f;
break;
}
}else{
x = numeric_compare(a, b, false, false, false);
if(x > 1)
x = numval(fl_compare(a, b));
if(x != 0){
v = FL_f;
break;
}
}
}
POPN(n);
PUSH(v);
}
NEXT_OP;
OP(OP_COMPARE)
FL(stack)[FL(sp)-2] = compare_(FL(stack)[FL(sp)-2], FL(stack)[FL(sp)-1], 0);
POPN(1);
NEXT_OP;
OP(OP_ARGC)
n = *ip++;
if(0){
OP(OP_LARGC)
n = GET_INT32(ip);
ip += 4;
}
FL(stack)[ipd] = (uintptr_t)ip;
argcount(nargs, n);
NEXT_OP;
OP(OP_VECTOR)
n = *ip++;
LABEL(apply_vector):
v = alloc_vector(n, 0);
if(n){
memcpy(&vector_elt(v, 0), &FL(stack)[FL(sp)-n], n*sizeof(value_t));
POPN(n);
}
PUSH(v);
NEXT_OP;
OP(OP_ASET)
FL(stack)[ipd] = (uintptr_t)ip;
v = FL(stack)[FL(sp)-3];
n = 3;
if(0){
LABEL(apply_aset):
v = FL(stack)[FL(sp)-n];
for(i = n-1; i >= 3; i--){
if(isarray(v)){
FL(stack)[FL(sp)-i-1] = v;
v = cvalue_array_aref(&FL(stack)[FL(sp)-i-1]);
continue;
}
e = FL(stack)[FL(sp)-i];
isz = tosize(e);
if(isvector(v)){
if(__unlikely(isz >= vector_size(v)))
bounds_error(v, e);
v = vector_elt(v, isz);
continue;
}
if(!iscons(v) && v != FL_nil)
type_error("sequence", v);
for(value_t v0 = v;; isz--){
if(isz == 0){
v = car_(v);
break;
}
v = cdr_(v);
if(__unlikely(!iscons(v)))
bounds_error(v0, e);
}
}
FL(stack)[FL(sp)-3] = v;
}
e = FL(stack)[FL(sp)-2];
isz = tosize(e);
if(isvector(v)){
if(__unlikely(isz >= vector_size(v)))
bounds_error(v, e);
vector_elt(v, isz) = (e = FL(stack)[FL(sp)-1]);
}else if(iscons(v) || v == FL_nil){
for(value_t v0 = v;; isz--){
if(isz == 0){
car_(v) = (e = FL(stack)[FL(sp)-1]);
break;
}
v = cdr_(v);
if(__unlikely(!iscons(v)))
bounds_error(v0, e);
}
}else if(isarray(v)){
e = cvalue_array_aset(&FL(stack)[FL(sp)-3]);
}else{
type_error("sequence", v);
}
POPN(n);
PUSH(e);
NEXT_OP;
OP(OP_FOR)
FL(stack)[ipd] = (uintptr_t)ip;
s = tofixnum(FL(stack)[FL(sp)-3]);
hi = tofixnum(FL(stack)[FL(sp)-2]);
v = FL_void;
FL(sp) += 2;
n = FL(sp);
for(; s <= hi; s++){
FL(stack)[FL(sp)-2] = FL(stack)[FL(sp)-3];
FL(stack)[FL(sp)-1] = fixnum(s);
v = _applyn(1);
FL(sp) = n;
}
POPN(4);
FL(stack)[FL(sp)-1] = v;
NEXT_OP;
OP(OP_LOADNIL)
PUSH(FL_nil);
NEXT_OP;
OP(OP_LOADI8)
s = (int8_t)*ip++;
PUSH(fixnum(s));
NEXT_OP;
OP(OP_LOADVL)
v = fn_vals(FL(stack)[bp-1]);
v = vector_elt(v, GET_INT32(ip));
ip += 4;
PUSH(v);
NEXT_OP;
OP(OP_SETGL)
v = fn_vals(FL(stack)[bp-1]);
v = vector_elt(v, GET_INT32(ip));
ip += 4;
if(0){
OP(OP_SETG)
v = fn_vals(FL(stack)[bp-1]);
assert(*ip < vector_size(v));
v = vector_elt(v, *ip);
ip++;
}
assert(issymbol(v));
sym = (symbol_t*)ptr(v);
v = FL(stack)[FL(sp)-1];
if(!isconstant(sym))
sym->binding = v;
NEXT_OP;
OP(OP_LOADAL)
assert(nargs > 0);
i = GET_INT32(ip);
ip += 4;
v = FL(stack)[bp+i];
PUSH(v);
NEXT_OP;
OP(OP_SETAL)
v = FL(stack)[FL(sp)-1];
i = GET_INT32(ip);
ip += 4;
FL(stack)[bp+i] = v;
NEXT_OP;
OP(OP_LOADCL)
i = GET_INT32(ip);
ip += 4;
v = FL(stack)[bp+nargs];
PUSH(vector_elt(v, i));
NEXT_OP;
OP(OP_VARGC)
i = *ip++;
if(0){
OP(OP_LVARGC)
i = GET_INT32(ip);
ip += 4;
}
s = (fixnum_t)nargs - (fixnum_t)i;
if(s > 0){
v = list(&FL(stack)[bp+i], s, 0);
FL(stack)[bp+i] = v;
if(s > 1){
FL(stack)[bp+i+1] = FL(stack)[bp+nargs+0];
FL(stack)[bp+i+2] = FL(stack)[bp+nargs+1];
FL(stack)[bp+i+3] = i+1;
FL(stack)[bp+i+4] = 0;
FL(sp) = bp+i+5;
FL(curr_frame) = FL(sp);
}
}else if(__unlikely(s < 0)){
FL(stack)[ipd] = (uintptr_t)ip;
lerrorf(FL_ArgError, "too few arguments");
}else{
FL(sp)++;
FL(stack)[FL(sp)-2] = i+1;
FL(stack)[FL(sp)-3] = FL(stack)[FL(sp)-4];
FL(stack)[FL(sp)-4] = FL(stack)[FL(sp)-5];
FL(stack)[FL(sp)-5] = FL_nil;
FL(curr_frame) = FL(sp);
}
ipd = FL(sp)-1;
nargs = i+1;
NEXT_OP;
OP(OP_TRYCATCH)
FL(stack)[ipd] = (uintptr_t)ip;
v = do_trycatch();
POPN(1);
FL(stack)[FL(sp)-1] = v;
NEXT_OP;
OP(OP_OPTARGS)
i = GET_INT32(ip);
ip += 4;
n = GET_INT32(ip);
ip += 4;
if(__unlikely(nargs < i)){
FL(stack)[ipd] = (uintptr_t)ip;
lerrorf(FL_ArgError, "too few arguments");
}
if((int32_t)n > 0){
if(__unlikely(nargs > n)){
FL(stack)[ipd] = (uintptr_t)ip;
lerrorf(FL_ArgError, "too many arguments");
}
}else
n = -n;
if(__likely(n > nargs)){
n -= nargs;
FL(sp) += n;
FL(stack)[FL(sp)-1] = FL(stack)[FL(sp)-n-1];
FL(stack)[FL(sp)-2] = nargs+n;
FL(stack)[FL(sp)-3] = FL(stack)[FL(sp)-n-3];
FL(stack)[FL(sp)-4] = FL(stack)[FL(sp)-n-4];
FL(curr_frame) = FL(sp);
ipd = FL(sp)-1;
for(i = 0; i < n; i++)
FL(stack)[bp+nargs+i] = UNBOUND;
nargs += n;
}
NEXT_OP;
OP(OP_BRBOUND)
i = GET_INT32(ip);
ip += 4;
v = FL(stack)[bp+i];
PUSH(v != UNBOUND ? FL_t : FL_f);
NEXT_OP;
OP(OP_KEYARGS)
v = fn_vals(FL(stack)[bp-1]);
v = vector_elt(v, 0);
i = GET_INT32(ip);
ip += 4;
n = GET_INT32(ip);
ip += 4;
s = GET_INT32(ip);
ip += 4;
FL(stack)[ipd] = (uintptr_t)ip;
nargs = process_keys(v, i, n, labs(s)-(i+n), bp, nargs, s<0);
ipd = FL(sp)-1;
NEXT_OP;