ref: f4933d23cf33c130b28616804b4ddde32018f3d8
parent: b42fcc3ec951c1b3db0760f25ea5d9eb0b518659
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Apr 8 18:50:13 EDT 2025
report instruction pointer of C builtins in the stack trace
--- a/boot/sl.boot
+++ b/boot/sl.boot
@@ -269,16 +269,16 @@
NIL NIL NIL NIL :from-end 3) identity #0# #fn("n10S;J;04AF0<51513500<:92<0=61:" #() find-if-)
list-tail list-head reverse!) find-if)
fits-i8 #fn("n10Y;3<0470r\xaf0r\xb063:" #(>=) fits-i8) fn-disasm
- #fn("\x871000.///W1000J60q?14z20[3:07060:@30q482JG07101E534725047060:@30q482<2305124051II252687>1?:5142527187>2?;514E288851b<I8<<8=L23\x8a24292:888<>2q7;53E8<<L23907250@30q4E87K~2<|48<8<<KM_48>2=8?2>523[08;8>8<<r45348:897?888<<52G5148<8<<r4M_@\x1912=8?2@523V08;8>8<<K5348:89888<<GG5148<8<<KM_@\xea12=8?2A523e08;8>8<<K5347B2C888<<G8>2DC70r3@30EM515148<8<<KM_@\xac12=8?2E523\\08;8>8<<r45347B2C7?888<<52515148<8<<r4M_@w12=8?2F523\xb808;8>8<<r88>2GC70r4@30EM5347B2C7?888<<52512H5248<8<<r4M_47B2C7?888<<52515148<8<<r4M_48>2GCY07B2H5147B2C7?888<<52512H5248<8<<r4M_@30q@\xe608?2Ic3^08;8>8<<r45347B2C7?888<<52512H5248<8<<r4M_@\xb202=8?2J523b08;8>8<<r25347B2K7L8<<7M888<<52M515248<8<<r2M_@w02=8?2N523b08;8>8<<r45347B2K7L8<<7?888<<52M515248<8<<r4M_@<08;8>8<<E53^1^1@\xd0-:" #(void
- fn-disasm newline #fn(fn-code) #fn(fn-vals) #1# #fn("n10\\3F00[JA070504710qAKM63:72061:" #(newline
- fn-disasm print) print-val) #fn("n370A3U0FEl23N071A72151523A0A182ML237023@4024751K~512602765:" #(princ
- >= 1- " >" " " hex5 ": " " ") print-inst) #fn(length)
- #fn(table-foldl) #fn("n382;J@041AF<Gl2;34040:") Instructions #fn("n1702161:" #(princ "\t"))
- #fn(memq) (loadv.l loadg.l setg.l) ref-s32-LE (loadv loadg setg)
+ #fn("\x871000.///W1000J60q?14z20[3I07021122534735047460:@30q482JG07501E534735047460:@30q482<2605127051II282987>1?:514282:187>2?;514E2;8851b<I8<<8=L23\x8a242<2=888<>2q7>53E8<<L23907350@30q4E87K~2?|48<8<<KM_48>2@8?2A523[08;8>8<<r45348:897B888<<52G5148<8<<r4M_@\x1912@8?2C523V08;8>8<<K5348:89888<<GG5148<8<<KM_@\xea12@8?2D523e08;8>8<<K534702E888<<G8>2FC70r3@30EM515148<8<<KM_@\xac12@8?2G523\\08;8>8<<r4534702E7B888<<52515148<8<<r4M_@w12@8?2H523\xb808;8>8<<r88>2IC70r4@30EM534702E7B888<<52512J5248<8<<r4M_4702E7B888<<52515148<8<<r4M_48>2ICY0702J514702E7B888<<52512J5248<8<<r4M_@30q@\xe608?2Kc3^08;8>8<<r4534702E7B888<<52512J5248<8<<r4M_@\xb202@8?2L523b08;8>8<<r2534702M7N8<<7O888<<52M515248<8<<r2M_@w02@8?2P523b08;8>8<<r4534702M7N8<<7B888<<52M515248<8<<r4M_@<08;8>8<<E53^1^1@\xd0-:" #(princ
+ " > " " // PC" newline void fn-disasm #fn(fn-code)
+ #fn(fn-vals) #1# #fn("n10\\3F00[JA070504710qAKM63:72061:" #(newline fn-disasm print) print-val)
+ #fn("n370A3U0FEl23N071A72151523A0A182ML237023@4024751K~512602765:" #(princ >= 1- " >" " " hex5
+ ": " " ") print-inst)
+ #fn(length) #fn(table-foldl) #fn("n382;J@041AF<Gl2;34040:") Instructions #fn("n1702161:" #(princ
+ "\t")) #fn(memq) (loadv.l loadg.l setg.l) ref-s32-LE (loadv loadg setg)
(loada seta loadc call tcall list + - * / < = vec argc vargc loadi8 apply tapply closure box
- shift aref) princ #fn(num->str) aref (loada.l seta.l loadc.l argc.l vargc.l call.l tcall.l box.l)
- (optargs keyargs) keyargs " " brbound (jmp brne brnn brn) "@" hex5 ref-s16-LE (jmp.l brne.l
- brnn.l brn.l)) fn-disasm)
+ shift aref) #fn(num->str) aref (loada.l seta.l loadc.l argc.l vargc.l call.l tcall.l box.l) (optargs
+ keyargs) keyargs " " brbound (jmp brne brnn brn) "@" hex5 ref-s16-LE (jmp.l brne.l brnn.l brn.l)) fn-disasm)
foldl #fn("n382J401:700082<15282=63:" #(foldl) foldl) foldr
#fn("n382J401:082<700182=5362:" #(foldr) foldr) get-defined-vars #fn("n170A<05161:" #(delete-duplicates) #(#2=(#fn("n10H340q:0<20Cd00=B3^00TR;37040Te1;JM040TB;3E0471051R;3:0471051e1:0<22C?07324A<0=52}2:q:" #(def
caadr begin nconc #fn(map)) #(#2#)))))
--- a/src/builtins.c
+++ b/src/builtins.c
@@ -39,8 +39,9 @@
while(iscons(c->cdr))
c = ptr(c->cdr);
pcdr = &c->cdr;
- }else if(lst != sl_nil)
- type_error("cons", lst);
+ }else if(lst != sl_nil){
+ bthrow(type_error("cons", lst));
+ }
}
*pcdr = lst;
return first;
@@ -117,7 +118,7 @@
}
if(a == sl_nil)
return fixnum(0);
- type_error("sequence", a);
+ bthrow(type_error("sequence", a));
}
_Noreturn
@@ -124,7 +125,7 @@
BUILTIN("raise", raise)
{
argcount(nargs, 1);
- sl_raise(args[0]);
+ bthrow(sl_raise(args[0]));
}
_Noreturn
@@ -160,7 +161,7 @@
argcount(nargs, 1);
sl_sym *sym = tosym(args[0]);
if(sym->binding == UNBOUND)
- unbound_error(args[0]);
+ bthrow(unbound_error(args[0]));
return sym->binding;
}
@@ -169,7 +170,7 @@
argcount(nargs, 2);
sl_sym *sym = tosym(args[0]);
if(sl_unlikely(isconst(sym)))
- const_error(sym);
+ bthrow(const_error(sym));
sym->binding = args[1];
return args[1];
}
@@ -179,7 +180,7 @@
argcount(nargs, 1);
sl_sym *sym = tosym(args[0]);
if(sl_unlikely(isconst(sym)))
- const_error(sym);
+ bthrow(const_error(sym));
sym->binding = UNBOUND;
return sl_void;
}
@@ -273,7 +274,7 @@
sl_cv *p = ptr(v);
return fixnum(conv_to_s64(v, cv_data(p), cv_numtype(p)));
}
- type_error("num", v);
+ bthrow(type_error("num", v));
}
BUILTIN("truncate", truncate)
@@ -305,7 +306,7 @@
return return_from_s64((s64int)d);
}
}
- type_error("num", v);
+ bthrow(type_error("num", v));
}
BUILTIN("vec-alloc", vec_alloc)
@@ -350,7 +351,7 @@
sl_numtype nt = cv_numtype(cv);
return conv_to_double(a, cv_data(cv), nt);
}
- type_error("num", a);
+ bthrow(type_error("num", a));
}
BUILTIN("time->str", time_str)
@@ -380,12 +381,12 @@
if(nargs == 0){
char buf[4096];
if(getcwd(buf, sizeof(buf)) == nil)
- lerrorf(sl_errio, "could not get current dir");
+ bthrow(lerrorf(sl_errio, "could not get current dir"));
return str_from_cstr(buf);
}
char *ptr = tostr(args[0]);
if(chdir(ptr) != 0)
- lerrorf(sl_errio, "could not cd to %s", ptr);
+ bthrow(lerrorf(sl_errio, "could not cd to %s", ptr));
return sl_void;
}
@@ -401,7 +402,7 @@
argcount(nargs, 1);
const char *path = tostr(args[0]);
if(remove(path) != 0)
- lerrorf(sl_errio, "could not remove %s", path);
+ bthrow(lerrorf(sl_errio, "could not remove %s", path));
return sl_void;
}
@@ -427,6 +428,6 @@
result = setenv(name, val, 1);
}
if(result != 0)
- lerrorf(sl_errarg, "invalid environment variable");
+ bthrow(lerrorf(sl_errarg, "invalid environment variable"));
return sl_t;
}
--- a/src/compiler.sl
+++ b/src/compiler.sl
@@ -763,6 +763,8 @@
(def (fn-disasm f (ip NIL) . lev?)
(when (builtin? f)
+ (princ " > " ip " // PC")
+ (newline)
(return (void)))
(when (not lev?)
(fn-disasm f ip 0)
--- a/src/compress.c
+++ b/src/compress.c
@@ -14,7 +14,7 @@
argcount(nargs, 2);
if(!isarr(args[0]))
- type_error("arr", args[0]);
+ bthrow(type_error("arr", args[0]));
u8int *in;
usize insz;
uintptr u;
@@ -37,7 +37,7 @@
: blz_pack(in, out, insz, work);
MEM_FREE(work);
if(n == BLZ_ERROR)
- lerrorf(sl_errarg, "blz error");
+ bthrow(lerrorf(sl_errarg, "blz error"));
cvalue_len(v) = n;
return v;
}
@@ -51,7 +51,7 @@
uintptr u;
to_sized_ptr(args[0], &in, &insz, &u);
if(!isarr(args[0]))
- type_error("arr", args[0]);
+ bthrow(type_error("arr", args[0]));
usize outsz;
u8int *out;
sl_v v;
@@ -63,11 +63,11 @@
v = args[2];
to_sized_ptr(v, &out, &outsz, &u);
}else{
- lerrorf(sl_errarg, "either :size or :to must be specified");
+ bthrow(lerrorf(sl_errarg, "either :size or :to must be specified"));
}
unsigned long n = blz_depack_safe(in, insz, out, outsz);
if(n == BLZ_ERROR)
- lerrorf(sl_errarg, "blz error");
+ bthrow(lerrorf(sl_errarg, "blz error"));
cvalue_len(v) = n;
return v;
}
--- a/src/cvalues.c
+++ b/src/cvalues.c
@@ -203,7 +203,7 @@
sl_fx v = ubnumval(a);
r = conv_to_u32(a, &v, ubnumtype(a));
}else
- type_error("num", a);
+ cthrow(type_error("num", a), type);
*((Rune*)dest) = r;
}
@@ -221,7 +221,7 @@
}else if(iscvalue(a)){ \
n = (ctype)conv_to_##cnvt(a, cv_data(ptr(a)), cv_numtype(ptr(a))); \
}else \
- type_error("num", a); \
+ cthrow(type_error("num", a), type); \
*((ctype*)dest) = n; \
}
@@ -346,7 +346,7 @@
void *p = cv_data(cv);
n = conv_to_bignum(a, p, cv_numtype(cv));
}else
- type_error("num", a);
+ cthrow(type_error("num", a), type);
*((mpint**)dest) = n;
}
@@ -404,7 +404,7 @@
return conv_to_u64(n, cv_data(cv), cv_numtype(cv));
return conv_to_u32(n, cv_data(cv), cv_numtype(cv));
}
- type_error("num", n);
+ cthrow(type_error("num", n), n);
}
soffset
@@ -420,7 +420,7 @@
return conv_to_s64(n, cv_data(cv), cv_numtype(cv));
return conv_to_s32(n, cv_data(cv), cv_numtype(cv));
}
- type_error("num", n);
+ cthrow(type_error("num", n), n);
}
bool
@@ -456,7 +456,7 @@
if(iscons(cdr_(cdr_(type)))){
usize tc = tosize(car_(cdr_(cdr_(type))));
if(tc != cnt)
- lerrorf(sl_errarg, "size mismatch");
+ cthrow(lerrorf(sl_errarg, "size mismatch"), ft);
}
sz = elsize * cnt;
@@ -482,7 +482,7 @@
arg = cdr_(arg);
}
if(i != cnt)
- lerrorf(sl_errarg, "size mismatch");
+ cthrow(lerrorf(sl_errarg, "size mismatch"), ft);
return;
}
if(iscvalue(arg)){
@@ -493,17 +493,17 @@
if(cv_len(cv) == sz)
memcpy(dest, cv_data(cv), sz);
else
- lerrorf(sl_errarg, "size mismatch");
+ cthrow(lerrorf(sl_errarg, "size mismatch"), ft);
return;
}else{
// TODO: initialize array from different type elements
- lerrorf(sl_errarg, "element type mismatch");
+ cthrow(lerrorf(sl_errarg, "element type mismatch"), ft);
}
}
}
if(cnt == 1)
cvalue_init(eltype, arg, dest);
- type_error("sequence", arg);
+ cthrow(type_error("sequence", arg), ft);
}
BUILTIN("arr", arr)
@@ -524,7 +524,7 @@
int i;
FOR_ARGS(i, 1, arg, args){
if(!sl_isnum(arg) && type->eltype != sl_runetype)
- type_error("num", arg);
+ bthrow(type_error("num", arg));
cvalue_init(type->eltype, arg, dest);
dest += elsize;
}
@@ -540,7 +540,7 @@
argcount(nargs, 3);
cnt = tosize(args[1]);
if(cnt < 0)
- lerrorf(sl_errarg, "invalid size: %"PRIu64, (u64int)cnt);
+ bthrow(lerrorf(sl_errarg, "invalid size: %"PRIu64, (u64int)cnt));
sl_type *type = get_arr_type(args[0]);
elsize = type->elsz;
@@ -552,7 +552,7 @@
for(i = 0; i < cnt; i++){
sl_v arg = args[a];
if(!sl_isnum(arg))
- type_error("num", arg);
+ bthrow(type_error("num", arg));
cvalue_init(type->eltype, arg, dest);
dest += elsize;
if((a = (a + 1) % nargs) < 2)
@@ -584,7 +584,7 @@
if(hed == sl_arrsym){
sl_v t = car(cdr_(type));
if(!iscons(cdr_(cdr_(type))))
- lerrorf(sl_errarg, "incomplete type");
+ cthrow(lerrorf(sl_errarg, "incomplete type"), type);
sl_v n = car_(cdr_(cdr_(type)));
usize sz = tosize(n);
return sz * ctype_sizeof(t);
@@ -591,7 +591,7 @@
}
}
- lerrorf(sl_errarg, "invalid c type");
+ cthrow(lerrorf(sl_errarg, "invalid c type"), type);
}
// get pointer and size for any plain-old-data value
@@ -624,7 +624,7 @@
return;
}
}
- type_error("plain-old-data", v);
+ cthrow(type_error("plain-old-data", v), v);
}
BUILTIN("sizeof", sizeof)
@@ -723,11 +723,11 @@
{
argcount(nargs, 1);
if(iscons(args[0]) || isvec(args[0]))
- lerrorf(sl_errarg, "argument must be a leaf atom");
+ bthrow(lerrorf(sl_errarg, "argument must be a leaf atom"));
if(!iscvalue(args[0]))
return args[0];
if(!cv_isPOD(ptr(args[0])))
- lerrorf(sl_errarg, "argument must be a plain-old-data type");
+ bthrow(lerrorf(sl_errarg, "argument must be a plain-old-data type"));
return cvalue_copy(args[0]);
}
@@ -747,7 +747,7 @@
{
cvinitfunc_t f = type->init;
if(f == nil)
- lerrorf(sl_errarg, "invalid c type");
+ cthrow(lerrorf(sl_errarg, "invalid c type"), type);
f(type, v, dest);
}
@@ -816,7 +816,7 @@
numel = cv_len(cv)/cv_class(cv)->elsz;
*index = tosize(ind);
if(*index < 0 || *index >= numel)
- bounds_error(arr, ind);
+ cthrow(bounds_error(arr, ind), arr);
}
sl_v
@@ -868,7 +868,7 @@
argcount(nargs, 1);
sl_sym *s = tosym(args[0]);
if(!iscbuiltin(s->binding))
- lerrorf(sl_errarg, "function \"%s\" not found", s->name);
+ bthrow(lerrorf(sl_errarg, "function \"%s\" not found", s->name));
return s->binding;
}
@@ -1015,7 +1015,7 @@
}
}
- type_error("num", n);
+ cthrow(type_error("num", n), n);
}
bool
@@ -1065,12 +1065,12 @@
}
if(!num_to_ptr(a, &ai, &ta, &aptr)){
if(typeerr)
- type_error("num", a);
+ cthrow(type_error("num", a), a);
return 2;
}
if(!num_to_ptr(b, &bi, &tb, &bptr)){
if(typeerr)
- type_error("num", b);
+ cthrow(type_error("num", b), a);
return 2;
}
if(eq && eqnans && ((ta >= T_FLOAT) != (tb >= T_FLOAT)))
@@ -1099,20 +1099,20 @@
void *aptr, *bptr;
if(!num_to_ptr(a, &ai, &ta, &aptr))
- type_error("num", a);
+ cthrow(type_error("num", a), a);
if(!num_to_ptr(b, &bi, &tb, &bptr))
- type_error("num", b);
+ cthrow(type_error("num", b), a);
// a pointer is not exactly a number
if(ta == T_PTR)
- type_error("num", a);
+ cthrow(type_error("num", a), a);
if(tb == T_PTR)
- type_error("num", b);
+ cthrow(type_error("num", b), a);
da = conv_to_double(a, aptr, ta);
db = conv_to_double(b, bptr, tb);
if(db == 0 && tb < T_FLOAT) // exact 0
- divide_by_0_error();
+ cthrow(divide_by_0_error(), a);
da = da/db;
@@ -1131,19 +1131,19 @@
mpint *x;
if(!num_to_ptr(a, &ai, &ta, &aptr))
- type_error("num", a);
+ cthrow(type_error("num", a), a);
if(!num_to_ptr(b, &bi, &tb, &bptr))
- type_error("num", b);
+ cthrow(type_error("num", b), a);
// a pointer is not exactly a number
if(ta == T_PTR)
- type_error("num", a);
+ cthrow(type_error("num", a), a);
if(tb == T_PTR)
- type_error("num", b);
+ cthrow(type_error("num", b), a);
if(ta == T_BIGNUM){
if(tb == T_BIGNUM){
if(mpsignif(*(mpint**)bptr) == 0)
- goto div_error;
+ cthrow(divide_by_0_error(), a);
x = mpnew(0);
mpdiv(*(mpint**)aptr, *(mpint**)bptr, x, nil);
return mk_bignum(x);
@@ -1150,7 +1150,7 @@
}else{
b64 = conv_to_s64(b, bptr, tb);
if(b64 == 0)
- goto div_error;
+ cthrow(divide_by_0_error(), a);
x = tb == T_U64 ? uvtomp(b64, nil) : vtomp(b64, nil);
mpdiv(*(mpint**)aptr, x, x, nil);
return mk_bignum(x);
@@ -1159,7 +1159,7 @@
if(ta == T_U64){
if(tb == T_U64){
if(*(u64int*)bptr == 0)
- goto div_error;
+ cthrow(divide_by_0_error(), a);
return return_from_u64(*(u64int*)aptr / *(u64int*)bptr);
}
b64 = conv_to_s64(b, bptr, tb);
@@ -1166,12 +1166,12 @@
if(b64 < 0)
return return_from_s64(-(s64int)(*(u64int*)aptr / (u64int)(-b64)));
if(b64 == 0)
- goto div_error;
+ cthrow(divide_by_0_error(), a);
return return_from_u64(*(u64int*)aptr / (u64int)b64);
}
if(tb == T_U64){
if(*(u64int*)bptr == 0)
- goto div_error;
+ cthrow(divide_by_0_error(), a);
a64 = conv_to_s64(a, aptr, ta);
if(a64 < 0)
return return_from_s64(-((s64int)((u64int)(-a64) / *(u64int*)bptr)));
@@ -1180,11 +1180,9 @@
b64 = conv_to_s64(b, bptr, tb);
if(b64 == 0)
- goto div_error;
+ cthrow(divide_by_0_error(), a);
return return_from_s64(conv_to_s64(a, aptr, ta) / b64);
-div_error:
- divide_by_0_error();
}
static sl_v
@@ -1197,9 +1195,9 @@
s64int b64;
if(!num_to_ptr(a, &ai, &ta, &aptr) || ta >= T_FLOAT)
- type_error("int", a);
+ cthrow(type_error("int", a), a);
if(!num_to_ptr(b, &bi, &tb, &bptr) || tb >= T_FLOAT)
- type_error("int", b);
+ cthrow(type_error("int", b), a);
if(ta < tb){
itmp = ta; ta = tb; tb = itmp;
@@ -1341,7 +1339,7 @@
default: abort();
}
}
- type_error("int", a);
+ bthrow(type_error("int", a));
}
#define sash_overflow_64(a, b, c) ( \
@@ -1407,7 +1405,7 @@
assert(fits_fixnum(accum));
return fixnum((sl_fx)accum);
}
- type_error("int", a);
+ bthrow(type_error("int", a));
}
void
--- a/src/dos/platform.h
+++ b/src/dos/platform.h
@@ -43,6 +43,9 @@
exit(1); \
}while(0)
+#define sys_setcallpc(arg) do{}while(0)
+#define sys_setcurrpc(dummy) do{}while(0)
+
#define PATHSEP '\\'
#define PATHSEPSTRING "\\"
#define PATHLISTSEP ':'
--- a/src/io.c
+++ b/src/io.c
@@ -71,7 +71,7 @@
toio(sl_v v)
{
if(sl_unlikely(!isio(v)))
- type_error("io", v);
+ cthrow(type_error("io", v), v);
return value2c(sl_ios*, v);
}
@@ -98,7 +98,7 @@
char *fname = tostr(args[0]);
sl_ios *s = value2c(sl_ios*, f);
if(ios_file(s, fname, r, w, c, t) == nil)
- lerrorf(sl_errio, "could not open \"%s\"", fname);
+ bthrow(lerrorf(sl_errio, "could not open \"%s\"", fname));
if(a)
ios_seek_end(s);
return f;
@@ -129,7 +129,7 @@
else if(a == sl_memorysym)
bm = bm_mem;
if(bm < 0 || ios_bufmode(s, bm) != 0)
- lerrorf(sl_errarg, "invalid buffer mode");
+ bthrow(lerrorf(sl_errarg, "invalid buffer mode"));
return sl_void;
}
@@ -140,7 +140,7 @@
sl_v f = cvalue(sl_iotype, sizeof(sl_ios));
sl_ios *s = value2c(sl_ios*, f);
if(ios_mem(s, 0) == nil)
- lerrorf(sl_errmem, "could not allocate in-memory io");
+ bthrow(lerrorf(sl_errmem, "could not allocate in-memory io"));
return f;
}
@@ -171,10 +171,10 @@
Rune r;
int res;
if((res = ios_peekrune(s, &r)) == IOS_EOF)
- //lerrorf(sl_errio, "end of file reached");
+ //bthrow(lerrorf(sl_errio, "end of file reached"));
return sl_eof;
if(res == 0)
- lerrorf(sl_errio, "invalid UTF-8 sequence");
+ bthrow(lerrorf(sl_errio, "invalid UTF-8 sequence"));
return mk_rune(r);
}
@@ -185,10 +185,10 @@
Rune r;
int res;
if((res = ios_getrune(s, &r)) == IOS_EOF)
- //lerrorf(sl_errio, "end of file reached");
+ //bthrow(lerrorf(sl_errio, "end of file reached"));
return sl_eof;
if(res == 0)
- lerrorf(sl_errio, "invalid UTF-8 sequence");
+ bthrow(lerrorf(sl_errio, "invalid UTF-8 sequence"));
return mk_rune(r);
}
@@ -197,7 +197,7 @@
argcount(nargs, 2);
sl_ios *s = toio(args[0]);
if(!isrune(args[1]))
- type_error("rune", args[1]);
+ bthrow(type_error("rune", args[1]));
return fixnum(ios_putrune(s, torune(args[1])));
}
@@ -230,7 +230,7 @@
argcount(nargs, 2);
sl_ios *s = toio(args[0]);
if(ios_trunc(s, tooffset(args[1])) < 0)
- lerrorf(sl_errio, "truncation failed");
+ bthrow(lerrorf(sl_errio, "truncation failed"));
return sl_void;
}
@@ -293,7 +293,7 @@
}else{
ft = get_type(args[1]);
if(ft->eltype != nil && !iscons(cdr_(cdr_(args[1]))))
- lerrorf(sl_errarg, "incomplete type");
+ bthrow(lerrorf(sl_errarg, "incomplete type"));
n = ft->size;
}
sl_v cv = cvalue(ft, n);
@@ -300,7 +300,7 @@
u8int *data = cvalue_data(cv);
usize got = ios_read(s, data, n);
if(got < n)
- //lerrorf(sl_errio, "end of input reached");
+ //bthrow(lerrorf(sl_errio, "end of input reached"));
return sl_eof;
return cv;
}
@@ -313,7 +313,7 @@
*offs = tosize(args[1]);
*nb = nargs > 2 ? tosize(args[2]) : sz - *offs;
if(*offs >= sz || *offs + *nb > sz)
- bounds_error(args[0], args[1]);
+ cthrow(bounds_error(args[0], args[1]), args);
}
}
@@ -325,7 +325,7 @@
sl_v v = args[1];
if(isrune(v)){
if(nargs > 2)
- lerrorf(sl_errarg, "offset argument not supported for characters");
+ bthrow(lerrorf(sl_errarg, "offset argument not supported for characters"));
return fixnum(ios_putrune(s, torune(v)));
}
u8int *data;
@@ -347,7 +347,7 @@
if(uldelim > 0x7f){
// runes > 0x7f, or anything else > 0xff, are out of range
if(isrune(arg) || uldelim > 0xff)
- lerrorf(sl_errarg, "delimiter out of range");
+ cthrow(lerrorf(sl_errarg, "delimiter out of range"), arg);
}
return (u8int)uldelim;
}
@@ -468,7 +468,7 @@
argcount(nargs, 1);
sl_ios *src = toio(args[0]);
if(src->bm != bm_mem)
- lerrorf(sl_errarg, "requires in-memory io");
+ bthrow(lerrorf(sl_errarg, "requires in-memory io"));
bool eof = ios_eof(src);
sl_v v = io_to_str(&args[0]);
if(eof && v == sl_emptystr)
--- a/src/macos/platform.h
+++ b/src/macos/platform.h
@@ -46,6 +46,9 @@
exit(1); \
}while(0)
+#define sys_setcallpc(arg) do{}while(0)
+#define sys_setcurrpc(dummy) do{}while(0)
+
#define PATHSEP '/'
#define PATHSEPSTRING "/"
#define PATHLISTSEP ':'
--- a/src/operators.c
+++ b/src/operators.c
@@ -18,7 +18,7 @@
case T_FLOAT: return dtomp(*(float*)data, nil);
case T_DOUBLE: return dtomp(*(double*)data, nil);
}
- type_error("num", v);
+ cthrow(type_error("num", v), v);
}
sl_purefn
@@ -44,7 +44,7 @@
case T_FLOAT: return *(float*)data;
case T_DOUBLE: return *(double*)data;
}
- type_error("num", v);
+ cthrow(type_error("num", v), v);
}
// FIXME sign with mpint
@@ -67,7 +67,7 @@
case T_FLOAT: return (ctype)*(float*)data; \
case T_DOUBLE: return (ctype)*(double*)data; \
} \
- type_error("num", v); \
+ cthrow(type_error("num", v), v); \
}
CONV_TO_INTTYPE(s64, s64int)
@@ -104,7 +104,7 @@
s = *(double*)data;
return s;
}
- type_error("num", v);
+ cthrow(type_error("num", v), v);
}
sl_purefn
--- a/src/plan9/lsd.c
+++ b/src/plan9/lsd.c
@@ -42,7 +42,7 @@
rp = rname(name);
if(rp == nil)
- lerrorf(sl_errio, "invalid register name %s", name);
+ cthrow(lerrorf(sl_errio, "invalid register name %s", name), map);
switch(rp->rformat){
default:
@@ -54,7 +54,7 @@
break;
}
if(r < 0)
- lerrorf(sl_errio, "could not get register %s: %r", name);
+ cthrow(lerrorf(sl_errio, "could not get register %s: %r", name), map);
return v;
}
@@ -123,7 +123,7 @@
}
static void
-load(void)
+load(int dummy)
{
int fd;
long nsym;
@@ -131,21 +131,21 @@
fd = open(aout, OREAD);
if(fd < 0)
- lerrorf(sl_errio, "could not open \"%s\"", aout);
+ cthrow(lerrorf(sl_errio, "could not open \"%s\"", aout), dummy);
if(!crackhdr(fd, &fhdr)){
close(fd);
- lerrorf(sl_errio, "could not decode file header for \"%s\"", aout);
+ cthrow(lerrorf(sl_errio, "could not decode file header for \"%s\"", aout), dummy);
}
machbytype(fhdr.type);
symmap = loadmap(nil, fd, &fhdr);
if(symmap == nil){
close(fd);
- lerrorf(sl_errio, "could not load segments for \"%s\"", aout);
+ cthrow(lerrorf(sl_errio, "could not load segments for \"%s\"", aout), dummy);
}
nsym = syminit(fd, &fhdr);
if(nsym < 0){
close(fd);
- lerrorf(sl_errio, "could not initialize the symbol table for \"%s\"", aout);
+ cthrow(lerrorf(sl_errio, "could not initialize the symbol table for \"%s\"", aout), dummy);
}
close(fd);
ios_printf(ios_stdout, "%s:%s\n", aout, fhdr.name);
@@ -177,12 +177,12 @@
snprint(buf, sizeof(buf), "/proc/%d/mem", pid);
fd = open(buf, ORDWR);
if(fd < 0)
- lerrorf(sl_errio, "could not open \"%s\"", buf);
+ cthrow(lerrorf(sl_errio, "could not open \"%s\"", buf), pid);
freecore();
coremap = attachproc(pid, 0, fd, &fhdr);
if(coremap == nil)
- lerrorf(sl_errio, "could not make coremap: %r");
+ cthrow(lerrorf(sl_errio, "could not make coremap: %r"), pid);
}
static int
@@ -192,11 +192,11 @@
char buf[128];
if(pipe(p) < 0)
- lerrorf(sl_errio, "could not create a pipe");
+ cthrow(lerrorf(sl_errio, "could not create a pipe"), argv);
pid = rfork(RFPROC|RFFDG|RFREND|RFNAMEG|RFNOTEG);
switch(pid){
case -1:
- lerrorf(sl_errio, "could not fork");
+ cthrow(lerrorf(sl_errio, "could not fork"), argv);
case 0:
snprint(buf, sizeof(buf), "/proc/%d/ctl", getpid());
fd = open(buf, ORDWR);
@@ -221,7 +221,7 @@
static void
trlist(Map *map, uvlong retpc, uvlong sp, Symbol *fn)
{
- sl_v v;
+ sl_v v;
USED(map);
v = alloc_vec(5, 0);
@@ -243,7 +243,7 @@
argcount(nargs, 3);
for(a = args; a < args+3; a++)
if(sl_unlikely(!sl_isnum(*a)))
- type_error("num", *a);
+ bthrow(type_error("num", *a));
pc = tosize(args[0]);
sp = tosize(args[1]);
@@ -252,7 +252,7 @@
sl_gc_handle(&tracelist);
if(machdata->ctrace(coremap, pc, sp, res, trlist) <= 0){
sl_free_gc_handles(1);
- lerrorf(sl_errio, "could not retrieve stack frame: %r");
+ bthrow(lerrorf(sl_errio, "could not retrieve stack frame: %r"));
}
sl_free_gc_handles(1);
return tracelist;
@@ -275,7 +275,7 @@
pid = -1;
argcount(nargs, 1);
if(sl_unlikely(!sl_isstr(args[0]) && !sl_isnum(args[0])))
- type_error("str|num", args[0]);
+ bthrow(type_error("str|num", args[0]));
if(sl_isnum(args[0])){
pid = tosize(args[0]);
@@ -283,11 +283,11 @@
}else{
len = cv_len(ptr(args[0]));
if(len+1 > sizeof(aout))
- lerrorf(sl_errio, "path too long");
+ bthrow(lerrorf(sl_errio, "path too long"));
strecpy(aout, aout+sizeof(aout), cvalue_data(args[0]));
}
- load();
+ load(0);
attach(pid);
registers = sl_nil;
@@ -332,11 +332,11 @@
static char *argv[512];
if(nargs+2 >= nelem(argv))
- lerrorf(sl_errio, "too many arguments");
+ bthrow(lerrorf(sl_errio, "too many arguments"));
argv[0] = aout;
for(i = 0; i < nargs; i++){
if(sl_unlikely(!sl_isstr(args[i])))
- type_error("str", args[i]);
+ bthrow(type_error("str", args[i]));
argv[i+1] = cvalue_data(args[i]);
}
argv[i+1] = nil;
@@ -365,12 +365,12 @@
argcount(nargs, 1);
if(sl_unlikely(!sl_isnum(args[0])))
- type_error("num", args[0]);
+ bthrow(type_error("num", args[0]));
addr = tosize(args[0]);
n = machdata->foll(coremap, addr, rget, f);
if(n < 0)
- lerrorf(sl_errio, "follow(%ux): %r", addr);
+ bthrow(lerrorf(sl_errio, "follow(%ux): %r", addr));
foll = sl_nil;
sl_gc_handle(&foll);
@@ -387,11 +387,11 @@
argcount(nargs, 1);
if(sl_unlikely(!sl_isnum(args[0])))
- type_error("num", args[0]);
+ bthrow(type_error("num", args[0]));
addr = tosize(args[0]);
if(machdata->das(coremap, addr, 'i', buf, sizeof(buf)) < 0)
- lerrorf(sl_errio, "could not disassemble at %ud", addr);
+ bthrow(lerrorf(sl_errio, "could not disassemble at %ud", addr));
return str_from_cstr(buf);
}
@@ -402,12 +402,12 @@
argcount(nargs, 1);
if(sl_unlikely(!sl_isnum(args[0])))
- type_error("num", args[0]);
+ bthrow(type_error("num", args[0]));
addr = tosize(args[0]);
sz = machdata->instsize(coremap, addr);
if(sz < 0)
- lerrorf(sl_errio, "could not get instruction size at %ud", addr);
+ bthrow(lerrorf(sl_errio, "could not get instruction size at %ud", addr));
return size_wrap(sz);
}
@@ -418,11 +418,11 @@
argcount(nargs, 1);
if(sl_unlikely(!sl_isnum(args[0])))
- type_error("num", args[0]);
+ bthrow(type_error("num", args[0]));
addr = tosize(args[0]);
if(!fileline(buf, sizeof(buf), addr))
- lerrorf(sl_errio, "could not locate source code line at %ud", addr);
+ bthrow(lerrorf(sl_errio, "could not locate source code line at %ud", addr));
return str_from_cstr(buf);
}
@@ -434,15 +434,15 @@
argcount(nargs, 2);
if(sl_unlikely(!sl_isstr(args[0])))
- type_error("str", args[0]);
+ bthrow(type_error("str", args[0]));
if(sl_unlikely(!isfixnum(args[1])))
- type_error("num", args[1]);
+ bthrow(type_error("num", args[1]));
file = cvalue_data(args[0]);
line = numval(args[1]);
addr = file2pc(file, line);
if(addr == ~0)
- lerrorf(sl_errio, "could not find address of %s:%d", file, line);
+ bthrow(lerrorf(sl_errio, "could not find address of %s:%d", file, line));
return size_wrap(addr);
}
@@ -453,10 +453,10 @@
argcount(nargs, 1);
if(sl_unlikely(!sl_isnum(args[0])))
- type_error("num", args[0]);
+ bthrow(type_error("num", args[0]));
addr = tosize(args[0]);
if(!findsym(addr, CTEXT, &s))
- lerrorf(sl_errio, "could not locate sym near %ud", addr);
+ bthrow(lerrorf(sl_errio, "could not locate sym near %ud", addr));
return mk_symbol(&s);
}
--- a/src/plan9/lsd.sl
+++ b/src/plan9/lsd.sl
@@ -477,7 +477,7 @@
(lsd-file2pc (car s) line)))))
(def (global-symbol s (:text NIL) (:data NIL))
- «Return a symbol from the attached proc's symbol table or `NIL`.
+ «Return a symbol from the attached proc's symbol table or `NIL`.
Input is a `str`. Optionally specify whether to search only text
symbols or data symbols. The default is to search both.
--- a/src/plan9/platform.h
+++ b/src/plan9/platform.h
@@ -29,6 +29,9 @@
#define sl_setjmp(e) setjmp((e))
#define sl_longjmp(e, v) longjmp((e), (v))
+#define sys_setcallpc(arg) do{sl.cpc = getcallerpc(&arg);}while(0)
+void sys_setcurrpc(int dummy);
+
extern double D_PNAN, D_PINF;
#if defined(__amd64__) || \
--- a/src/plan9/sys.c
+++ b/src/plan9/sys.c
@@ -103,6 +103,13 @@
}
void
+sys_setcurrpc(int dummy)
+{
+ USED(dummy);
+ sys_setcallpc(dummy);
+}
+
+void
sys_init(void)
{
lsd_init();
--- a/src/posix/platform.h
+++ b/src/posix/platform.h
@@ -73,6 +73,10 @@
exit(1); \
}while(0)
+#define getcallerpc(a) (uintptr)__builtin_extract_return_addr(__builtin_return_address(0))
+#define sys_setcallpc(arg) do{sl.cpc = getcallerpc(&arg);}while(0)
+void sys_setcurrpc(int dummy);
+
#define nil NULL
#define USED(x) ((void)(x))
#define nelem(x) (int)(sizeof(x)/sizeof((x)[0]))
--- a/src/posix/sys.c
+++ b/src/posix/sys.c
@@ -101,8 +101,17 @@
}
}
+void __attribute__((noinline))
+sys_setcurrpc(int dummy)
+{
+ USED(dummy);
+ sys_setcallpc(dummy);
+}
+
void
-sys_init(void){}
+sys_init(void)
+{
+}
static const u8int boot[] = {
#include "sl.boot.h"
--- a/src/sl.c
+++ b/src/sl.c
@@ -197,7 +197,7 @@
{ \
if(sl_likely(is##type(v))) \
return (ctype)cnvt(v); \
- type_error(#type, v); \
+ cthrow(type_error(#type, v), v); \
}
SAFECAST_OP(cons, sl_cons*, ptr)
SAFECAST_OP(sym, sl_sym*, ptr)
@@ -369,7 +369,7 @@
sl_gc_handle(sl_v *pv)
{
if(sl_unlikely(slg.ngchandles >= N_GC_HANDLES))
- lerrorf(sl_errmem, "out of gc handles");
+ cthrow(lerrorf(sl_errmem, "out of gc handles"), pv);
slg.gchandles[slg.ngchandles++] = pv;
}
@@ -583,11 +583,11 @@
else if(sl_likely(isbuiltin(f))){
sl_v tab = sym_value(sl_builtinssym);
if(sl_unlikely(ptr(tab) == nil))
- unbound_error(tab);
+ cthrow(unbound_error(tab), n);
saveSP[-n-1] = vec_elt(tab, uintval(f));
v = apply_cl(n);
}else{
- type_error("fn", f);
+ cthrow(type_error("fn", f), n);
}
sl.sp = saveSP;
return v;
@@ -605,7 +605,7 @@
v = cdr_(v);
}
if(v != sl_nil)
- lerrorf(sl_errarg, "apply: last argument: not a list");
+ cthrow(lerrorf(sl_errarg, "apply: last argument: not a list"), f);
v = _applyn(n);
sl.sp = saveSP;
return v;
@@ -780,9 +780,9 @@
sl_v s3 = sl.sp[-3];
sl_v s4 = sl.sp[-4];
if(sl_unlikely(nargs < nreq))
- lerrorf(sl_errarg, "too few arguments");
+ cthrow(lerrorf(sl_errarg, "too few arguments"), kwtable);
if(sl_unlikely(extr > nelem(args)))
- lerrorf(sl_errarg, "too many arguments");
+ cthrow(lerrorf(sl_errarg, "too many arguments"), kwtable);
for(i = 0; i < extr; i++)
args[i] = UNBOUND;
for(i = nreq; i < nargs; i++){
@@ -800,7 +800,7 @@
do{
i++;
if(sl_unlikely(i >= nargs))
- lerrorf(sl_errarg, "keyword %s requires an argument", sym_name(v));
+ cthrow(lerrorf(sl_errarg, "keyword %s requires an argument", sym_name(v)), kwtable);
sl_v hv = fixnum(((sl_sym*)ptr(v))->hash);
sl_fx lx = numval(hv);
uintptr x = 2*((lx < 0 ? -lx : lx) % n);
@@ -813,7 +813,7 @@
args[idx] = bp[i];
}
}else{
- lerrorf(sl_errarg, "unsupported keyword %s", sym_name(v));
+ cthrow(lerrorf(sl_errarg, "unsupported keyword %s", sym_name(v)), kwtable);
}
i++;
if(i >= nargs)
@@ -823,7 +823,7 @@
no_kw:
nrestargs = nargs - i;
if(sl_unlikely(!va && nrestargs > 0))
- lerrorf(sl_errarg, "too many arguments");
+ cthrow(lerrorf(sl_errarg, "too many arguments"), kwtable);
nargs = ntot + nrestargs;
if(nrestargs)
memmove(bp+ntot, bp+i, nrestargs*sizeof(sl_v));
@@ -917,9 +917,9 @@
sl_v *bp = top-4-sz;
sl_v fn = bp[0];
sl_v v = alloc_vec(sz+1, 0);
- if(iscbuiltin(fn))
- vec_elt(v, 0) = fn;
- else{
+ if(iscbuiltin(fn)){
+ vec_elt(v, 0) = lst == sl_nil ? mk_ptr(sl.cpc) : fn; mk_ptr((uintptr)ip1);
+ }else{
/* -1: ip1 is *after* the one that was being executed */
intptr ip = ip1 - (const u8int*)cvalue_data(fn_bcode(fn)) - 1;
vec_elt(v, 0) = fixnum(ip);
@@ -955,12 +955,12 @@
if(nargs < 1 || nargs > 4)
argcount(nargs, 1);
if(sl_unlikely(!sl_isstr(args[0])))
- type_error("str", args[0]);
+ bthrow(type_error("str", args[0]));
sl_v vals = sl_emptyvec;
if(nargs > 1){
vals = args[1];
if(sl_unlikely(!isvec(vals)))
- type_error("vec", vals);
+ bthrow(type_error("vec", vals));
}
sl_cv *arr = ptr(args[0]);
cv_pin(arr);
@@ -986,12 +986,12 @@
fn->env = args[2];
if(nargs > 3){
if(sl_unlikely(!issym(args[3])))
- type_error("sym", args[3]);
+ bthrow(type_error("sym", args[3]));
fn->name = args[3];
}
}
if(sl_unlikely(isgensym(fn->name)))
- lerrorf(sl_errarg, "name should not be a gensym");
+ bthrow(lerrorf(sl_errarg, "name should not be a gensym"));
}
return fv;
}
@@ -1004,7 +1004,7 @@
if(sl_unlikely(iscbuiltin(v)))
return v;
if(sl_unlikely(!isfn(v)))
- type_error("fn", v);
+ bthrow(type_error("fn", v));
return fn_bcode(v);
}
@@ -1016,7 +1016,7 @@
if(sl_unlikely(iscbuiltin(v)))
return sl_emptyvec;
if(sl_unlikely(!isfn(v)))
- type_error("fn", v);
+ bthrow(type_error("fn", v));
return fn_vals(v);
}
@@ -1028,7 +1028,7 @@
if(sl_unlikely(iscbuiltin(v)))
return sl_nil;
if(sl_unlikely(!isfn(v)))
- type_error("fn", v);
+ bthrow(type_error("fn", v));
return fn_env(v);
}
@@ -1046,7 +1046,7 @@
return sl_nil;
return v;
}
- type_error("fn", v);
+ bthrow(type_error("fn", v));
}
BUILTIN("copy-list", copy_list)
@@ -1073,7 +1073,7 @@
cdr_(lastcons) = lst;
lastcons = tagptr((((sl_cons*)slg.curheap)-1), TAG_CONS);
}else if(lst != sl_nil){
- type_error("cons", lst);
+ bthrow(type_error("cons", lst));
}
}
sl_free_gc_handles(2);
@@ -1099,7 +1099,7 @@
BUILTIN("map", map)
{
if(sl_unlikely(nargs < 2))
- lerrorf(sl_errarg, "too few arguments");
+ argcount(nargs, 2);
sl_v *k = sl.sp;
PUSH(sl_nil);
PUSH(sl_nil);
@@ -1130,7 +1130,7 @@
BUILTIN("for-each", for_each)
{
if(sl_unlikely(nargs < 2))
- lerrorf(sl_errarg, "too few arguments");
+ argcount(nargs, 2);
for(usize n = 0;; n++){
PUSH(args[0]);
int pargs = 0;
--- a/src/sl.h
+++ b/src/sl.h
@@ -290,10 +290,13 @@
_Noreturn void unbound_error(sl_v sym);
_Noreturn void arity_error(int nargs, int c);
+#define bthrow(stmt) do{ sys_setcurrpc(0); stmt; }while(1)
+#define cthrow(stmt, a) do{ sys_setcallpc(a); stmt; }while(1)
+
#define argcount(nargs, c) \
do{ \
if(sl_unlikely(nargs != c)) \
- arity_error(nargs, c); \
+ bthrow(arity_error(nargs, c)); \
}while(0)
typedef struct {
@@ -393,6 +396,7 @@
sl_fx p_level;
int scr_width;
ssize hpos, vpos;
+ uintptr cpc;
};
struct Slg {
--- a/src/str.c
+++ b/src/str.c
@@ -22,17 +22,17 @@
if(nargs < 1 || nargs > 3)
argcount(nargs, 1);
if(!sl_isstr(args[0]))
- type_error("str", args[0]);
+ bthrow(type_error("str", args[0]));
usize len = cv_len(ptr(args[0]));
usize stop = len;
if(nargs > 1){
start = tosize(args[1]);
if(start > len)
- bounds_error(args[0], args[1]);
+ bthrow(bounds_error(args[0], args[1]));
if(nargs > 2){
stop = tosize(args[2]);
if(stop > len)
- bounds_error(args[0], args[2]);
+ bthrow(bounds_error(args[0], args[2]));
if(stop <= start)
return fixnum(0);
}
@@ -49,7 +49,7 @@
return w < 0 ? sl_nil : fixnum(w);
}
if(!sl_isstr(args[0]))
- type_error("str", args[0]);
+ bthrow(type_error("str", args[0]));
char *str = tostr(args[0]);
usize len = cv_len(ptr(args[0]));
ssize w = u8_strwidth(str, len);
@@ -60,7 +60,7 @@
{
argcount(nargs, 1);
if(!sl_isstr(args[0]))
- type_error("str", args[0]);
+ bthrow(type_error("str", args[0]));
usize len = cv_len(ptr(args[0]));
sl_v ns = cvalue_str(len);
u8_reverse(cvalue_data(ns), cvalue_data(args[0]), len);
@@ -110,7 +110,7 @@
// it can only be a :trim X now
if(nargs > n){
if(args[n] != sl_trimsym)
- lerrorf(sl_errarg, "invalid argument at position %d", n);
+ bthrow(lerrorf(sl_errarg, "invalid argument at position %d", n));
n++;
if(nargs <= n)
argcount(nargs, n+1);
@@ -167,7 +167,7 @@
for(startbytes = n = 0; n < startrune && startbytes < lenbytes; n++)
startbytes += u8_seqlen(s+startbytes);
if(n != startrune)
- bounds_error(args[0], args[1]);
+ bthrow(bounds_error(args[0], args[1]));
usize endbytes = lenbytes;
if(nargs == 3){
usize endrune = tosize(args[2]);
@@ -174,7 +174,7 @@
for(endbytes = startbytes; n < endrune && endbytes < lenbytes; n++)
endbytes += u8_seqlen(s+endbytes);
if(n != endrune)
- bounds_error(args[0], args[2]);
+ bthrow(bounds_error(args[0], args[2]));
}
sl_v ns = cvalue_str(endbytes-startbytes);
s = cvalue_data(args[0]); // reload after alloc
@@ -191,7 +191,7 @@
for(startbytes = n = 0; n < startrune && startbytes < lenbytes; n++)
startbytes += u8_seqlen(s+startbytes);
if(n != startrune || startbytes >= lenbytes)
- bounds_error(args[0], args[1]);
+ bthrow(bounds_error(args[0], args[1]));
Rune r;
chartorune(&r, s+startbytes);
return mk_rune(r);
@@ -202,7 +202,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- type_error("rune", args[0]);
+ bthrow(type_error("rune", args[0]));
return mk_rune(toupperrune(torune(args[0])));
}
@@ -211,7 +211,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- type_error("rune", args[0]);
+ bthrow(type_error("rune", args[0]));
return mk_rune(tolowerrune(torune(args[0])));
}
@@ -220,7 +220,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- type_error("rune", args[0]);
+ bthrow(type_error("rune", args[0]));
return mk_rune(totitlerune(torune(args[0])));
}
@@ -229,7 +229,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- type_error("rune", args[0]);
+ bthrow(type_error("rune", args[0]));
return isalpharune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -238,7 +238,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- type_error("rune", args[0]);
+ bthrow(type_error("rune", args[0]));
return islowerrune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -247,7 +247,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- type_error("rune", args[0]);
+ bthrow(type_error("rune", args[0]));
return isupperrune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -256,7 +256,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- type_error("rune", args[0]);
+ bthrow(type_error("rune", args[0]));
return istitlerune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -265,7 +265,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- type_error("rune", args[0]);
+ bthrow(type_error("rune", args[0]));
return isdigitrune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -274,7 +274,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- type_error("rune", args[0]);
+ bthrow(type_error("rune", args[0]));
return isspacerune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -305,7 +305,7 @@
ndbytes = cv_len(cv);
nd = (char*)cv_data(cv);
}else{
- type_error("str or rune", args[1]);
+ bthrow(type_error("str or rune", args[1]));
}
if(ndbytes == 0)
return size_wrap(startrune);
@@ -317,7 +317,7 @@
for(i = n = 0; n < startrune && i < sbytes; n++)
i += u8_seqlen(s+i);
if(n != startrune)
- bounds_error(args[0], fixnum(startrune));
+ bthrow(bounds_error(args[0], fixnum(startrune)));
// now search for the needle
for(; i < sbytes-ndbytes+1; n++){
if(s[i] == nd[0] && memcmp(&s[i+1], nd+1, ndbytes-1) == 0)
@@ -332,7 +332,7 @@
{
unsigned long radix = tosize(arg);
if(radix < 2 || radix > 36)
- lerrorf(sl_errarg, "invalid radix");
+ cthrow(lerrorf(sl_errarg, "invalid radix"), arg);
return radix;
}
@@ -352,7 +352,7 @@
num = ubnumval(n);
else if(isbignum(n)){
if(radix != 16 && radix != 10 && radix != 8 && radix != 4 && radix != 2)
- lerrorf(sl_errarg, "invalid radix with bignum");
+ bthrow(lerrorf(sl_errarg, "invalid radix with bignum"));
mpint *i = tobignum(n);
char *s = mptoa(i, radix, nil, 0);
assert(s != nil);
@@ -368,11 +368,11 @@
if(cv_numtype(data) < T_FLOAT)
num = conv_to_u64(n, cv_data(data), cv_numtype(data));
else if(radix != 10)
- lerrorf(sl_errarg, "invalid radix with floating point");
+ bthrow(lerrorf(sl_errarg, "invalid radix with floating point"));
else
return fn_builtin_str(args, nargs);
}else{
- type_error("int", n);
+ bthrow(type_error("int", n));
}
if(numval(sl_compare(args[0], fixnum(0), false)) < 0){
num = -num;
--- a/src/table.c
+++ b/src/table.c
@@ -85,7 +85,7 @@
totable(sl_v v)
{
if(!ishashtable(v))
- type_error("table", v);
+ cthrow(type_error("table", v), v);
return cvalue_data(v);
}
@@ -93,7 +93,7 @@
{
int cnt = nargs;
if(cnt & 1)
- lerrorf(sl_errarg, "arguments must come in pairs");
+ bthrow(lerrorf(sl_errarg, "arguments must come in pairs"));
sl_v nt;
// prevent small tables from being added to finalizer list
if(cnt <= HT_N_INLINE)
@@ -148,7 +148,7 @@
if(v == (sl_v)HT_NOTFOUND){
if(nargs == 3)
return args[2];
- key_error(args[1]);
+ bthrow(key_error(args[1]));
}
return v;
}
@@ -168,7 +168,7 @@
argcount(nargs, 2);
sl_htable *h = totable(args[0]);
if(!equalhash_remove(h, (void*)args[1]))
- key_error(args[1]);
+ bthrow(key_error(args[1]));
return args[0];
}
--- a/src/vm.h
+++ b/src/vm.h
@@ -86,19 +86,17 @@
#endif
}
}else if(sl_likely(iscbuiltin(v))){
- bp = sp-nargs;
+ builtin_t f = ((sl_cv*)ptr(v))->cbuiltin;
*sp++ = sl_nil; // fn->env;
*sp++ = (sl_v)sl.curr_frame;
*sp++ = n;
- *sp++ = v; // ip
+ *sp++ = (sl_v)f; // ip
sl.curr_frame = sp;
sl.sp = sp;
- v = ((sl_cv*)ptr(v))->cbuiltin(sp-n-4, n);
+ v = f(sp-n-4, n);
sp = sl.curr_frame;
sl.curr_frame = (sl_v*)sp[-3];
sp -= 4+n;
- n = sl.curr_frame[-2];
- bp = sl.curr_frame - 4 - n;
sp[-1] = v;
NEXT_OP;
}