ref: d170d141ad95660edfdd8dca4bebe9d7b4485197
parent: da7de7d9c3f9c66468e4d988cc6b23bc961ed742
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sat Nov 9 11:56:04 EST 2024
vm loop: update current frame's instruction pointer before any exceptions may be raised
--- a/cvalues.c
+++ b/cvalues.c
@@ -978,7 +978,7 @@
int64_t Saccum = carryIn;
int64_t Sresult;
double Faccum = 0;
- int32_t inexact = 0;
+ bool inexact = false;
uint32_t i;
int64_t i64;
value_t arg;
@@ -1039,8 +1039,8 @@
Maccum = mpnew(0);
mpadd(Maccum, *(mpint**)a, Maccum);
break;
- case T_FLOAT: Faccum += *(float*)a; inexact = 1; break;
- case T_DOUBLE: Faccum += *(double*)a; inexact = 1; break;
+ case T_FLOAT: Faccum += *(float*)a; inexact = true; break;
+ case T_DOUBLE: Faccum += *(double*)a; inexact = true; break;
default:
goto add_type_error;
}
@@ -1152,11 +1152,12 @@
}
value_t
-fl_mul_any(value_t *args, uint32_t nargs, int64_t Saccum)
+fl_mul_any(value_t *args, uint32_t nargs)
{
+ int64_t Saccum = 1;
uint64_t Uaccum = 1;
double Faccum = 1;
- int32_t inexact = 0;
+ bool inexact = false;
int64_t i64;
uint32_t i;
value_t arg;
@@ -1191,8 +1192,8 @@
Maccum = mpcopy(mpone);
mpmul(Maccum, *(mpint**)a, Maccum);
break;
- case T_FLOAT: Faccum *= *(float*)a; inexact = 1; break;
- case T_DOUBLE: Faccum *= *(double*)a; inexact = 1; break;
+ case T_FLOAT: Faccum *= *(float*)a; inexact = true; break;
+ case T_DOUBLE: Faccum *= *(double*)a; inexact = true; break;
default:
goto mul_type_error;
}
--- a/cvalues.h
+++ b/cvalues.h
@@ -48,7 +48,7 @@
value_t return_from_int64(int64_t Saccum);
value_t fl_add_any(value_t *args, uint32_t nargs, fixnum_t carryIn);
value_t fl_neg(value_t n);
-value_t fl_mul_any(value_t *args, uint32_t nargs, int64_t Saccum);
+value_t fl_mul_any(value_t *args, uint32_t nargs);
int num_to_ptr(value_t a, fixnum_t *pi, numerictype_t *pt, void **pp);
int numeric_compare(value_t a, value_t b, int eq, int eqnans, int typeerr);
_Noreturn void DivideByZeroError(void);
--- a/flisp.c
+++ b/flisp.c
@@ -148,7 +148,7 @@
#define SAFECAST_OP(type, ctype, cnvt) \
ctype to##type(value_t v) \
{ \
- if(is##type(v)) \
+ if(__likely(is##type(v))) \
return (ctype)cnvt(v); \
type_error(#type, v); \
}
@@ -318,7 +318,7 @@
void
fl_gc_handle(value_t *pv)
{
- if(fl->N_GCHND >= N_GC_HANDLES)
+ if(__unlikely(fl->N_GCHND >= N_GC_HANDLES))
lerrorf(fl->MemoryError, "out of gc handles");
fl->GCHandleStack[fl->N_GCHND++] = pv;
}
@@ -509,13 +509,13 @@
// grow the other half of the heap this time to catch up.
if(fl->grew || ((fl->lim-fl->curheap) < (int)(fl->heapsize/5)) || mustgrow){
temp = LLT_REALLOC(fl->tospace, fl->heapsize*2);
- if(temp == nil)
+ if(__unlikely(temp == nil))
fl_raise(fl->memory_exception_value);
fl->tospace = temp;
if(fl->grew){
fl->heapsize *= 2;
temp = bitvector_resize(fl->consflags, 0, fl->heapsize/sizeof(cons_t), 1);
- if(temp == nil)
+ if(__unlikely(temp == nil))
fl_raise(fl->memory_exception_value);
fl->consflags = (uint32_t*)temp;
}
@@ -530,7 +530,7 @@
{
size_t newsz = fl->N_STACK * 2;
value_t *ns = LLT_REALLOC(fl->Stack, newsz*sizeof(value_t));
- if(ns == nil)
+ if(__unlikely(ns == nil))
lerrorf(fl->MemoryError, "stack overflow");
fl->Stack = ns;
fl->N_STACK = newsz;
@@ -549,9 +549,9 @@
v = ((builtin_t*)ptr(f))[3](&fl->Stack[fl->SP-n], n);
}else if(isfunction(f)){
v = apply_cl(n);
- }else if(isbuiltin(f)){
+ }else if(__likely(isbuiltin(f))){
value_t tab = symbol_value(fl->builtins_table_sym);
- if(ptr(tab) == nil)
+ if(__unlikely(ptr(tab) == nil))
unbound_error(tab);
fl->Stack[fl->SP-n-1] = vector_elt(tab, uintval(f));
v = apply_cl(n);
@@ -589,7 +589,7 @@
size_t i;
PUSH(f);
- while(fl->SP+n > fl->N_STACK)
+ while(fl->SP+n >= fl->N_STACK)
grow_stack();
for(i = 0; i < n; i++){
value_t a = va_arg(ap, value_t);
@@ -609,7 +609,7 @@
uint32_t si = fl->SP;
size_t i;
- while(fl->SP+n > fl->N_STACK)
+ while(fl->SP+n >= fl->N_STACK)
grow_stack();
for(i = 0; i < n; i++){
value_t a = va_arg(ap, value_t);
@@ -687,9 +687,9 @@
c++;
}
if(star)
- (c-2)->cdr = (c-1)->car;
+ c[-2].cdr = c[-1].car;
else
- (c-1)->cdr = fl->NIL;
+ c[-1].cdr = fl->NIL;
return v;
}
@@ -758,9 +758,9 @@
value_t s2 = fl->Stack[fl->SP-2];
value_t s4 = fl->Stack[fl->SP-4];
value_t s5 = fl->Stack[fl->SP-5];
- if(nargs < nreq)
+ if(__unlikely(nargs < nreq))
lerrorf(fl->ArgError, "too few arguments");
- if(extr > nelem(args))
+ if(__unlikely(extr > nelem(args)))
lerrorf(fl->ArgError, "too many arguments");
for(i = 0; i < extr; i++)
args[i] = UNBOUND;
@@ -778,12 +778,12 @@
uintptr_t n = vector_size(kwtable)/2;
do{
i++;
- if(i >= nargs)
+ if(__unlikely(i >= nargs))
lerrorf(fl->ArgError, "keyword %s requires an argument", symbol_name(v));
value_t hv = fixnum(((symbol_t*)ptr(v))->hash);
lltint_t lx = numval(hv);
uintptr_t x = 2*((lx < 0 ? -lx : lx) % n);
- if(vector_elt(kwtable, x) == v){
+ if(__likely(vector_elt(kwtable, x) == v)){
uintptr_t idx = numval(vector_elt(kwtable, x+1));
assert(idx < nkw);
idx += nopt;
@@ -801,7 +801,7 @@
}while(issymbol(v) && iskeyword((symbol_t*)ptr(v)));
no_kw:
nrestargs = nargs - i;
- if(!va && nrestargs > 0)
+ if(__unlikely(!va && nrestargs > 0))
lerrorf(fl->ArgError, "too many arguments");
nargs = ntot + nrestargs;
if(nrestargs)
@@ -864,11 +864,10 @@
int tail, x;
// temporary variables (not necessary to preserve across calls)
- uint32_t op, i;
+ uint32_t op, i, ipd;
symbol_t *sym;
cons_t *c;
value_t *pv;
- int64_t accum;
value_t func, v, e;
n = 0;
@@ -880,7 +879,8 @@
func = fl->Stack[fl->SP-nargs-1];
ip = cv_data((cvalue_t*)ptr(fn_bcode(func)));
assert(!ismanaged((uintptr_t)ip));
- while(fl->SP+GET_INT32(ip) > fl->N_STACK)
+ i = fl->SP+GET_INT32(ip);
+ while(i >= fl->N_STACK)
grow_stack();
ip += 4;
@@ -888,8 +888,9 @@
PUSH(fn_env(func));
PUSH(fl->curr_frame);
PUSH(nargs);
- fl->SP++;//PUSH(0); //ip
- PUSH(0); //captured?
+ ipd = fl->SP;
+ fl->SP++; // ip
+ PUSH(0); // captured?
fl->curr_frame = fl->SP;
op = *ip++;
@@ -935,6 +936,7 @@
n = *ip++; // nargs
}
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)){
@@ -943,8 +945,6 @@
for(s = -1; s < (fixnum_t)n; s++)
fl->Stack[bp+s] = fl->Stack[fl->SP-n+s];
fl->SP = bp+n;
- }else{
- fl->Stack[fl->curr_frame-2] = (uintptr_t)ip;
}
nargs = n;
goto apply_cl_top;
@@ -974,7 +974,7 @@
}
}
}
- }else if(iscbuiltin(func)){
+ }else if(__likely(iscbuiltin(func))){
s = fl->SP;
v = (((builtin_t*)ptr(func))[3])(&fl->Stack[fl->SP-n], n);
fl->SP = s-n;
@@ -996,8 +996,10 @@
}
assert(issymbol(v));
sym = (symbol_t*)ptr(v);
- if(sym->binding == UNBOUND)
+ if(__unlikely(sym->binding == UNBOUND)){
+ fl->Stack[ipd] = (uintptr_t)ip;
unbound_error(v);
+ }
PUSH(sym->binding);
NEXT_OP;
@@ -1034,7 +1036,8 @@
return v;
fl->SP -= 5+nargs;
captured = fl->Stack[fl->curr_frame-1];
- ip = (uint8_t*)fl->Stack[fl->curr_frame-2];
+ ipd = fl->curr_frame-2;
+ ip = (uint8_t*)fl->Stack[ipd];
nargs = fl->Stack[fl->curr_frame-3];
bp = fl->curr_frame - 5 - nargs;
fl->Stack[fl->SP-1] = v;
@@ -1047,15 +1050,19 @@
OP(OP_CAR)
v = fl->Stack[fl->SP-1];
- if(!iscons(v))
+ if(__unlikely(!iscons(v))){
+ fl->Stack[ipd] = (uintptr_t)ip;
type_error("cons", v);
+ }
fl->Stack[fl->SP-1] = car_(v);
NEXT_OP;
OP(OP_CDR)
v = fl->Stack[fl->SP-1];
- if(!iscons(v))
+ if(__unlikely(!iscons(v))){
+ fl->Stack[ipd] = (uintptr_t)ip;
type_error("cons", v);
+ }
fl->Stack[fl->SP-1] = cdr_(v);
NEXT_OP;
@@ -1082,7 +1089,7 @@
if(fl->curheap > fl->lim-2)
gc(0);
pv = (value_t*)fl->curheap;
- fl->curheap += (4*sizeof(value_t));
+ 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];
@@ -1137,14 +1144,15 @@
NEXT_OP;
OP(OP_AREF)
+ fl->Stack[ipd] = (uintptr_t)ip;
v = fl->Stack[fl->SP-2];
if(isvector(v)){
e = fl->Stack[fl->SP-1];
i = isfixnum(e) ? numval(e) : (uint32_t)toulong(e);
- if(i >= vector_size(v))
+ if(__unlikely(i >= vector_size(v)))
bounds_error(v, e);
v = vector_elt(v, i);
- }else if(isarray(v)){
+ }else if(__likely(isarray(v))){
v = cvalue_array_aref(&fl->Stack[fl->SP-2]);
}else{
type_error("sequence", v);
@@ -1178,6 +1186,7 @@
NEXT_OP;
OP(OP_ADD2)
+ fl->Stack[ipd] = (uintptr_t)ip;
if(bothfixnums(fl->Stack[fl->SP-1], fl->Stack[fl->SP-2])){
s = numval(fl->Stack[fl->SP-1]) + numval(fl->Stack[fl->SP-2]);
v = fits_fixnum(s) ? fixnum(s) : mk_xlong(s);
@@ -1189,7 +1198,12 @@
NEXT_OP;
OP(OP_SETCDR)
- cdr(fl->Stack[fl->SP-2]) = fl->Stack[fl->SP-1];
+ 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;
@@ -1205,7 +1219,8 @@
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;
+ POPN(1);
+ NEXT_OP;
OP(OP_EQ)
fl->Stack[fl->SP-2] = fl->Stack[fl->SP-2] == fl->Stack[fl->SP-1] ? fl->FL_T : fl->FL_F;
@@ -1222,16 +1237,21 @@
OP(OP_CADR)
v = fl->Stack[fl->SP-1];
- if(!iscons(v))
+ if(__unlikely(!iscons(v))){
+ fl->Stack[ipd] = (uintptr_t)ip;
type_error("cons", v);
+ }
v = cdr_(v);
- if(!iscons(v))
+ if(__unlikely(!iscons(v))){
+ fl->Stack[ipd] = (uintptr_t)ip;
type_error("cons", v);
+ }
fl->Stack[fl->SP-1] = car_(v);
NEXT_OP;
OP(OP_NEG)
do_neg:
+ fl->Stack[ipd] = (uintptr_t)ip;
fl->Stack[fl->SP-1] = fl_neg(fl->Stack[fl->SP-1]);
NEXT_OP;
@@ -1254,6 +1274,7 @@
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->FL_F : fl->FL_T;
NEXT_OP;
@@ -1265,9 +1286,10 @@
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->FL_T : fl->FL_F;
+ fl->Stack[fl->SP-1] =
+ ((tag(v) == TAG_FUNCTION &&
+ (isbuiltin(v) || v>(N_BUILTINS<<3))) ||
+ iscbuiltin(v)) ? fl->FL_T : fl->FL_F;
NEXT_OP;
OP(OP_VECTORP)
@@ -1324,7 +1346,12 @@
NEXT_OP;
OP(OP_SETCAR)
- car(fl->Stack[fl->SP-2]) = fl->Stack[fl->SP-1];
+ 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;
@@ -1367,12 +1394,13 @@
for(; i < fl->SP; i++){
if(isfixnum(fl->Stack[i])){
s += numval(fl->Stack[i]);
- if(!fits_fixnum(s)){
+ if(__unlikely(!fits_fixnum(s))){
i++;
goto add_ovf;
}
}else{
add_ovf:
+ fl->Stack[ipd] = (uintptr_t)ip;
v = fl_add_any(&fl->Stack[i], fl->SP-i, s);
break;
}
@@ -1390,6 +1418,7 @@
goto do_sub2;
if(n == 1)
goto 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
@@ -1408,6 +1437,7 @@
s = numval(fl->Stack[fl->SP-2]) - numval(fl->Stack[fl->SP-1]);
v = fits_fixnum(s) ? fixnum(s) : mk_xlong(s);
}else{
+ fl->Stack[ipd] = (uintptr_t)ip;
fl->Stack[fl->SP-1] = fl_neg(fl->Stack[fl->SP-1]);
v = fl_add_any(&fl->Stack[fl->SP-2], 2, 0);
}
@@ -1418,17 +1448,8 @@
OP(OP_MUL)
n = *ip++;
apply_mul:
- accum = 1;
- for(i = fl->SP-n; i < fl->SP; i++){
- if(isfixnum(fl->Stack[i])){
- accum *= numval(fl->Stack[i]);
- }else{
- v = fl_mul_any(&fl->Stack[i], fl->SP-i, accum);
- break;
- }
- }
- if(i == fl->SP)
- v = fits_fixnum(accum) ? fixnum(accum) : return_from_int64(accum);
+ fl->Stack[ipd] = (uintptr_t)ip;
+ v = fl_mul_any(&fl->Stack[fl->SP-n], n);
POPN(n);
PUSH(v);
NEXT_OP;
@@ -1436,6 +1457,7 @@
OP(OP_DIV)
n = *ip++;
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]);
@@ -1443,7 +1465,7 @@
if(n > 2){
PUSH(fl->Stack[i]);
fl->Stack[i] = fixnum(1);
- fl->Stack[i+1] = fl_mul_any(&fl->Stack[i], n, 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]);
@@ -1453,13 +1475,16 @@
NEXT_OP;
OP(OP_IDIV)
- v = fl->Stack[fl->SP-2]; e = fl->Stack[fl->SP-1];
+ fl->Stack[ipd] = (uintptr_t)ip;
+ v = fl->Stack[fl->SP-2];
+ e = fl->Stack[fl->SP-1];
if(bothfixnums(v, e)){
if(e == 0)
DivideByZeroError();
v = fixnum(numval(v) / numval(e));
- }else
+ }else{
v = fl_idiv2(v, e);
+ }
POPN(1);
fl->Stack[fl->SP-1] = v;
NEXT_OP;
@@ -1468,8 +1493,10 @@
v = fl->Stack[fl->SP-2]; e = fl->Stack[fl->SP-1];
if(bothfixnums(v, e))
v = v == e ? fl->FL_T : fl->FL_F;
- else
+ else{
+ fl->Stack[ipd] = (uintptr_t)ip;
v = numeric_compare(v, e, 1, 0, 1) == 0 ? fl->FL_T : fl->FL_F;
+ }
POPN(1);
fl->Stack[fl->SP-1] = v;
NEXT_OP;
@@ -1486,6 +1513,7 @@
n = GET_INT32(ip);
ip += 4;
}
+ fl->Stack[ipd] = (uintptr_t)ip;
argcount(nargs, n);
NEXT_OP;
@@ -1502,12 +1530,13 @@
OP(OP_ASET)
e = fl->Stack[fl->SP-3];
+ fl->Stack[ipd] = (uintptr_t)ip;
if(isvector(e)){
i = tofixnum(fl->Stack[fl->SP-2]);
- if(i >= vector_size(e))
+ if(__unlikely(i >= vector_size(e)))
bounds_error(v, fl->Stack[fl->SP-1]);
vector_elt(e, i) = (v = fl->Stack[fl->SP-1]);
- }else if(isarray(e)){
+ }else if(__likely(isarray(e))){
v = cvalue_array_aset(&fl->Stack[fl->SP-3]);
}else{
type_error("sequence", e);
@@ -1517,9 +1546,9 @@
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]);
- //f = fl->Stack[fl->SP-1];
v = fl->FL_UNSPECIFIED;
fl->SP += 2;
n = fl->SP;
@@ -1640,7 +1669,8 @@
fl->SP = bp+i+6;
fl->curr_frame = fl->SP;
}
- }else if(s < 0){
+ }else if(__unlikely(s < 0)){
+ fl->Stack[ipd] = (uintptr_t)ip;
lerrorf(fl->ArgError, "too few arguments");
}else{
PUSH(0);
@@ -1650,10 +1680,12 @@
fl->Stack[fl->SP-6] = fl->NIL;
fl->curr_frame = fl->SP;
}
+ ipd = fl->SP-2;
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;
@@ -1664,14 +1696,18 @@
ip += 4;
n = GET_INT32(ip);
ip += 4;
- if(nargs < i)
+ if(__unlikely(nargs < i)){
+ fl->Stack[ipd] = (uintptr_t)ip;
lerrorf(fl->ArgError, "too few arguments");
+ }
if((int32_t)n > 0){
- if(nargs > n)
+ if(__unlikely(nargs > n)){
+ fl->Stack[ipd] = (uintptr_t)ip;
lerrorf(fl->ArgError, "too many arguments");
+ }
}else
n = -n;
- if(n > nargs){
+ if(__likely(n > nargs)){
n -= nargs;
fl->SP += n;
fl->Stack[fl->SP-1] = fl->Stack[fl->SP-n-1];
@@ -1680,6 +1716,7 @@
fl->Stack[fl->SP-4] = fl->Stack[fl->SP-n-4];
fl->Stack[fl->SP-5] = fl->Stack[fl->SP-n-5];
fl->curr_frame = fl->SP;
+ ipd = fl->SP-2;
for(i = 0; i < n; i++)
fl->Stack[bp+nargs+i] = UNBOUND;
nargs += n;
@@ -1702,6 +1739,7 @@
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);
NEXT_OP;
}
@@ -1754,8 +1792,7 @@
memmove(&vector_elt(v, 1),
&vector_elt(fl->Stack[bp+1], 0), (sz-1)*sizeof(value_t));
}else{
- uint32_t i;
- for(i = 0; i < sz; i++){
+ for(uint32_t i = 0; i < sz; i++){
value_t si = fl->Stack[bp+i];
// if there's an error evaluating argument defaults some slots
// might be left set to UNBOUND (issue #22)
@@ -1785,9 +1822,9 @@
return fn_builtin_builtin(args, nargs);
if(nargs < 2 || nargs > 4)
argcount(nargs, 2);
- if(!fl_isstring(args[0]))
+ if(__unlikely(!fl_isstring(args[0])))
type_error("string", args[0]);
- if(!isvector(args[1]))
+ if(__unlikely(!isvector(args[1])))
type_error("vector", args[1]);
cvalue_t *arr = (cvalue_t*)ptr(args[0]);
cv_pin(arr);
@@ -1822,12 +1859,12 @@
}else{
fn->env = args[2];
if(nargs > 3){
- if(!issymbol(args[3]))
+ if(__unlikely(!issymbol(args[3])))
type_error("symbol", args[3]);
fn->name = args[3];
}
}
- if(isgensym(fn->name))
+ if(__unlikely(isgensym(fn->name)))
lerrorf(fl->ArgError, "name should not be a gensym");
}
return fv;
@@ -1837,7 +1874,7 @@
{
argcount(nargs, 1);
value_t v = args[0];
- if(!isclosure(v))
+ if(__unlikely(!isclosure(v)))
type_error("function", v);
return fn_bcode(v);
}
@@ -1846,7 +1883,7 @@
{
argcount(nargs, 1);
value_t v = args[0];
- if(!isclosure(v))
+ if(__unlikely(!isclosure(v)))
type_error("function", v);
return fn_vals(v);
}
@@ -1855,7 +1892,7 @@
{
argcount(nargs, 1);
value_t v = args[0];
- if(!isclosure(v))
+ if(__unlikely(!isclosure(v)))
type_error("function", v);
return fn_env(v);
}
@@ -1864,7 +1901,7 @@
{
argcount(nargs, 1);
value_t v = args[0];
- if(!isclosure(v))
+ if(__unlikely(!isclosure(v)))
type_error("function", v);
return fn_name(v);
}
@@ -1918,7 +1955,7 @@
BUILTIN("map", map)
{
- if(nargs < 2)
+ if(__unlikely(nargs < 2))
lerrorf(fl->ArgError, "too few arguments");
if(!iscons(args[1]))
return fl->NIL;
--- a/flisp.h
+++ b/flisp.h
@@ -326,7 +326,6 @@
typedef struct Fl Fl;
struct Fl {
- const uint8_t *ip;
value_t *Stack;
uint32_t SP;
uint32_t N_STACK;