wrap non-native builtins in cases that they exist

This commit is contained in:
dzaima 2022-01-01 15:33:41 +02:00
parent 2602a6499d
commit 0690ae114a
3 changed files with 159 additions and 114 deletions

15
src/h.h
View File

@ -85,8 +85,13 @@
#define EACH_FILLS 0 #define EACH_FILLS 0
#define PROPER_FILLS 0 #define PROPER_FILLS 0
#endif #endif
#if defined(ALL_R0) || defined (ALL_R1)
#define WRAP_NNBI 1
#endif
#if defined(RT_PERF) || defined(RT_VERIFY) #if defined(RT_PERF) || defined(RT_VERIFY)
#define RT_WRAP #define RT_WRAP 1
#if defined(RT_PERF) && defined(RT_VERIFY) #if defined(RT_PERF) && defined(RT_VERIFY)
#error "can't have both RT_PERF and RT_VERIFY" #error "can't have both RT_PERF and RT_VERIFY"
#endif #endif
@ -176,10 +181,10 @@ typedef union B {
} B; } B;
#define b(x) ((B)(x)) #define b(x) ((B)(x))
#ifdef RT_WRAP #if defined(RT_WRAP) || defined(WRAP_NNBI)
#define IF_RT_WRAP(X) X #define IF_WRAP(X) X
#else #else
#define IF_RT_WRAP(X) #define IF_WRAP(X)
#endif #endif
#define FOR_TYPE(F) \ #define FOR_TYPE(F) \
@ -202,7 +207,7 @@ typedef union B {
/*48*/ F(fun_invReg ) F(md1_invReg ) F(md2_invReg ) \ /*48*/ F(fun_invReg ) F(md1_invReg ) F(md2_invReg ) \
/*51*/ F(fun_invSwap) F(md1_invSwap) F(md2_invSwap) \ /*51*/ F(fun_invSwap) F(md1_invSwap) F(md2_invSwap) \
\ \
/*54*/ IF_RT_WRAP(F(funWrap) F(md1Wrap) F(md2Wrap)) /*54*/ IF_WRAP(F(funWrap) F(md1Wrap) F(md2Wrap))
enum Type { enum Type {
#define F(X) t_##X, #define F(X) t_##X,

View File

@ -92,7 +92,7 @@ char* pm2_repr(u8 u) {
#undef F #undef F
B r1Objs[rtLen]; B r1Objs[rtLen];
B rtWrap_wrap(B x); // consumes B rtWrap_wrap(B x, bool nnbi); // consumes
void rtWrap_print(void); void rtWrap_print(void);
@ -326,7 +326,7 @@ void load_init() { // very last init function
/* ⎉⚇⍟⎊ */ bi_rank , bi_depth , bi_repeat, bi_catch /* ⎉⚇⍟⎊ */ bi_rank , bi_depth , bi_repeat, bi_catch
}; };
bool rtComplete[] = { bool rtComplete[] = { // if you unset any of these, also define WRAP_NNBI
/* +-×÷⋆√⌊⌈|¬ */ 1,1,1,1,1,1,1,1,1,1, /* +-×÷⋆√⌊⌈|¬ */ 1,1,1,1,1,1,1,1,1,1,
/* ∧∨<>≠=≤≥≡≢ */ 1,1,1,1,1,1,1,1,1,1, /* ∧∨<>≠=≤≥≡≢ */ 1,1,1,1,1,1,1,1,1,1,
/* ⊣⊢⥊∾≍⋈↑↓↕« */ 1,1,1,1,1,1,1,1,1,1, /* ⊣⊢⥊∾≍⋈↑↓↕« */ 1,1,1,1,1,1,1,1,1,1,
@ -400,14 +400,19 @@ void load_init() { // very last init function
r1Objs[i] = Get(rtObjRaw, i); gc_add(r1Objs[i]); r1Objs[i] = Get(rtObjRaw, i); gc_add(r1Objs[i]);
#endif #endif
#ifdef ALL_R1 #ifdef ALL_R1
bool nnbi = true;
B r = Get(rtObjRaw, i); B r = Get(rtObjRaw, i);
#else #else
B r = rtComplete[i]? inc(fruntime[i]) : Get(rtObjRaw, i); bool nnbi = !rtComplete[i];
#if !defined(WRAP_NNBI)
if (nnbi) err("Refusing to load non-native builtin into runtime without -DWRAP_NNBI");
#endif
B r = nnbi? Get(rtObjRaw, i) : inc(fruntime[i]);
#endif #endif
if (q_N(r)) err("· in runtime!\n"); if (q_N(r)) err("· in runtime!\n");
if (isVal(r)) v(r)->flags|= i+1; if (isVal(r)) v(r)->flags|= i+1;
#ifdef RT_WRAP #if defined(RT_WRAP) || defined(WRAP_NNBI)
r = rtWrap_wrap(r); r = rtWrap_wrap(r, nnbi);
if (isVal(r)) v(r)->flags|= i+1; if (isVal(r)) v(r)->flags|= i+1;
#endif #endif
runtimeH.a[i] = r; runtimeH.a[i] = r;

View File

@ -1,33 +1,61 @@
#include "core.h" #include "core.h"
#include "vm.h" #include "vm.h"
#ifdef RT_PERF #if RT_PERF
#include "builtins.h" #include "builtins.h"
#endif #endif
#include "utils/time.h" #include "utils/time.h"
#ifdef RT_WRAP #if defined(RT_WRAP) || defined(WRAP_NNBI)
typedef struct WFun WFun; typedef struct WFun WFun;
typedef struct WMd1 WMd1;
typedef struct WMd2 WMd2;
struct WFun { struct WFun {
struct Fun; struct Fun;
B v; B v;
WFun* prev; WFun* prev;
#ifdef RT_PERF #if RT_PERF
u64 c1t, c2t; u64 c1t, c2t;
u32 c1a, c2a; u32 c1a, c2a;
#else #elif RT_VERIFY
B r1; B r1;
#endif #endif
}; };
struct WMd1 {
struct Md1;
u64 c1t, c2t;
u32 c1a, c2a;
B v;
WMd1* prev;
};
struct WMd2 {
struct Md2;
u64 c1t, c2t;
u32 c1a, c2a;
B v;
WMd2* prev;
};
WFun* lastWF; WFun* lastWF;
void wf_visit(Value* x) { mm_visit(((WFun*)x)->v); } WMd1* lastWM1;
B wf_identity(B x) { WMd2* lastWM2;
void wfn_visit(Value* x) { mm_visit(((WFun*)x)->v); }
void wm1_visit(Value* x) { mm_visit(((WMd1*)x)->v); }
void wm2_visit(Value* x) { mm_visit(((WMd2*)x)->v); }
B wfn_identity(B x) {
B f = c(WFun,x)->v; B f = c(WFun,x)->v;
return inc(TI(f,identity)(f)); return inc(TI(f,identity)(f));
} }
// rtverify
#ifndef RT_VERIFY_ARGS #ifndef RT_VERIFY_ARGS
#define RT_VERIFY_ARGS 1 #define RT_VERIFY_ARGS 1
#endif #endif
#if RT_VERIFY
B info_c1(B t, B x); B info_c1(B t, B x);
#define CHK(EXP,GOT,W,X) { if (!eequal(EXP,GOT)) { \ #define CHK(EXP,GOT,W,X) { if (!eequal(EXP,GOT)) { \
print(f); printf(": failed RT_VERIFY\n"); fflush(stdout); \ print(f); printf(": failed RT_VERIFY\n"); fflush(stdout); \
@ -39,19 +67,24 @@ B info_c1(B t, B x);
} \ } \
vm_pstLive(); exit(1); \ vm_pstLive(); exit(1); \
}} }}
#endif
// rtperf
u64 fwTotal; u64 fwTotal;
B wf_c1(B t, B x) {
B wfn_c1(B t, B x) {
WFun* c = c(WFun,t); WFun* c = c(WFun,t);
B f = c->v; B f = c->v;
BB2B fi = c(Fun,f)->c1; BB2B fi = c(Fun,f)->c1;
#ifdef RT_PERF #if RT_PERF
u64 s = nsTime(); u64 s = nsTime();
B r = fi(f, x); B r = fi(f, x);
u64 e = nsTime(); u64 e = nsTime();
c->c1a++; c->c1a++;
c->c1t+= e-s; c->c1t+= e-s;
fwTotal+= e-s+20; fwTotal+= e-s+20;
#else #elif RT_VERIFY
B exp = c1(c->r1, inc(x)); B exp = c1(c->r1, inc(x));
#if RT_VERIFY_ARGS #if RT_VERIFY_ARGS
B r = fi(f, inc(x)); B r = fi(f, inc(x));
@ -62,21 +95,23 @@ B wf_c1(B t, B x) {
CHK(exp, r, bi_N, x); CHK(exp, r, bi_N, x);
#endif #endif
dec(exp); dec(exp);
#else
B r = fi(f, inc(x));
#endif #endif
return r; return r;
} }
B wf_c2(B t, B w, B x) { B wfn_c2(B t, B w, B x) {
WFun* c = c(WFun,t); WFun* c = c(WFun,t);
B f = c->v; B f = c->v;
BBB2B fi = c(Fun,f)->c2; BBB2B fi = c(Fun,f)->c2;
#ifdef RT_PERF #if RT_PERF
u64 s = nsTime(); u64 s = nsTime();
B r = fi(f, w, x); B r = fi(f, w, x);
u64 e = nsTime(); u64 e = nsTime();
c->c2a++; c->c2a++;
c->c2t+= e-s; c->c2t+= e-s;
fwTotal+= e-s+20; fwTotal+= e-s+20;
#else #elif RT_VERIFY
B exp = c2(c->r1, inc(w), inc(x)); B exp = c2(c->r1, inc(w), inc(x));
#if RT_VERIFY_ARGS #if RT_VERIFY_ARGS
B r = fi(f, inc(w), inc(x)); B r = fi(f, inc(w), inc(x));
@ -87,83 +122,80 @@ B wf_c2(B t, B w, B x) {
CHK(exp, r, w, x); CHK(exp, r, w, x);
#endif #endif
dec(exp); dec(exp);
#else
B r = fi(f, w, x);
#endif #endif
return r; return r;
} }
#undef CHK #undef CHK
typedef struct WMd1 WMd1;
struct WMd1 {
struct Md1;
u64 c1t, c2t;
u32 c1a, c2a;
B v;
WMd1* prev;
};
WMd1* lastWM1;
void wm1_visit(Value* x) { mm_visit(((WMd1*)x)->v); }
typedef struct WMd2 WMd2;
struct WMd2 {
struct Md2;
u64 c1t, c2t;
u32 c1a, c2a;
B v;
WMd2* prev;
};
WMd2* lastWM2;
void wm2_visit(Value* x) { mm_visit(((WMd2*)x)->v); }
B wm1_c1(Md1D* d, B x) { B f = d->f; WMd1* t = (WMd1*)d->m1; B wm1_c1(Md1D* d, B x) { B f = d->f; WMd1* t = (WMd1*)d->m1;
#if RT_PERF
u64 pfwt=fwTotal; fwTotal = 0; u64 pfwt=fwTotal; fwTotal = 0;
B om = t->v;
u64 s = nsTime(); u64 s = nsTime();
#endif
B om = t->v;
B fn = m1_d(inc(om), inc(f)); B fn = m1_d(inc(om), inc(f));
B r = c1(fn, x); B r = c1(fn, x);
u64 e = nsTime();
dec(fn); dec(fn);
#if RT_PERF
u64 e = nsTime();
t->c1a++; t->c1a++;
t->c1t+= e-s - fwTotal; t->c1t+= e-s - fwTotal;
fwTotal = pfwt + e-s + 30; fwTotal = pfwt + e-s + 30;
#endif
return r; return r;
} }
B wm1_c2(Md1D* d, B w, B x) { B f = d->f; WMd1* t = (WMd1*)d->m1; B wm1_c2(Md1D* d, B w, B x) { B f = d->f; WMd1* t = (WMd1*)d->m1;
#if RT_PERF
u64 pfwt=fwTotal; fwTotal = 0; u64 pfwt=fwTotal; fwTotal = 0;
B om = t->v;
u64 s = nsTime(); u64 s = nsTime();
#endif
B om = t->v;
B fn = m1_d(inc(om), inc(f)); B fn = m1_d(inc(om), inc(f));
B r = c2(fn, w, x); B r = c2(fn, w, x);
u64 e = nsTime();
dec(fn); dec(fn);
#if RT_PERF
u64 e = nsTime();
t->c2a++; t->c2a++;
t->c2t+= e-s - fwTotal; t->c2t+= e-s - fwTotal;
fwTotal = pfwt + e-s + 30; fwTotal = pfwt + e-s + 30;
#endif
return r; return r;
} }
B wm2_c1(Md2D* d, B x) { B f = d->f; B g = d->g; WMd2* t = (WMd2*)d->m2; B wm2_c1(Md2D* d, B x) { B f = d->f; B g = d->g; WMd2* t = (WMd2*)d->m2;
#if RT_PERF
u64 pfwt=fwTotal; fwTotal = 0; u64 pfwt=fwTotal; fwTotal = 0;
B om = t->v;
u64 s = nsTime(); u64 s = nsTime();
#endif
B om = t->v;
B fn = m2_d(inc(om), inc(f), inc(g)); B fn = m2_d(inc(om), inc(f), inc(g));
B r = c1(fn, x); B r = c1(fn, x);
u64 e = nsTime();
dec(fn); dec(fn);
#if RT_PERF
u64 e = nsTime();
t->c1a++; t->c1a++;
t->c1t+= e-s - fwTotal; t->c1t+= e-s - fwTotal;
fwTotal = pfwt + e-s + 30; fwTotal = pfwt + e-s + 30;
#endif
return r; return r;
} }
B wm2_c2(Md2D* d, B w, B x) { B f = d->f; B g = d->g; WMd2* t = (WMd2*)d->m2; B wm2_c2(Md2D* d, B w, B x) { B f = d->f; B g = d->g; WMd2* t = (WMd2*)d->m2;
#if RT_PERF
u64 pfwt=fwTotal; fwTotal = 0; u64 pfwt=fwTotal; fwTotal = 0;
B om = t->v;
u64 s = nsTime(); u64 s = nsTime();
#endif
B om = t->v;
B fn = m2_d(inc(om), inc(f), inc(g)); B fn = m2_d(inc(om), inc(f), inc(g));
B r = c2(fn, w, x); B r = c2(fn, w, x);
u64 e = nsTime();
dec(fn); dec(fn);
#if RT_PERF
u64 e = nsTime();
t->c2a++; t->c2a++;
t->c2t+= e-s - fwTotal; t->c2t+= e-s - fwTotal;
fwTotal = pfwt + e-s + 30; fwTotal = pfwt + e-s + 30;
#endif
return r; return r;
} }
@ -171,28 +203,31 @@ B wm2_c2(Md2D* d, B w, B x) { B f = d->f; B g = d->g; WMd2* t = (WMd2*)d->m2;
B rtWrap_wrap(B t) { B rtWrap_wrap(B t, bool nnbi) {
#if !defined(RT_WRAP)
if (!nnbi) return t;
#endif
if (isFun(t)) { if (isFun(t)) {
#ifdef RT_VERIFY #if RT_VERIFY
if(v(t)->flags==0) return t; if(v(t)->flags==0) return t;
#endif #endif
WFun* r = mm_alloc(sizeof(WFun), t_funWrap); WFun* r = mm_alloc(sizeof(WFun), t_funWrap);
r->extra = v(t)->extra; r->extra = v(t)->extra;
r->flags = v(t)->flags; r->flags = v(t)->flags;
r->c1 = wf_c1; r->c1 = wfn_c1;
r->c2 = wf_c2; r->c2 = wfn_c2;
r->v = t; r->v = t;
r->prev = lastWF; r->prev = lastWF;
lastWF = r; lastWF = r;
#ifdef RT_VERIFY #if RT_VERIFY
r->r1 = r1Objs[v(t)->flags-1]; r->r1 = r1Objs[v(t)->flags-1];
#else #elif RT_PERF
r->c1t = 0; r->c1a = 0; r->c1t = 0; r->c1a = 0;
r->c2t = 0; r->c2a = 0; r->c2t = 0; r->c2a = 0;
#endif #endif
return tag(r,FUN_TAG); return tag(r,FUN_TAG);
} }
#ifdef RT_PERF #if RT_PERF || WRAP_NNBI
if (isMd1(t)) { if (isMd1(t)) {
WMd1* r = mm_alloc(sizeof(WMd1), t_md1Wrap); WMd1* r = mm_alloc(sizeof(WMd1), t_md1Wrap);
r->extra = v(t)->extra; r->extra = v(t)->extra;
@ -242,7 +277,7 @@ B wm2_ucw(Md2* t, B o, B f, B g, B w, B x) { B t2 = ((WMd2*)t)->v; return TI(t2,
static B m1BI_d(B t, B f ) { return m_md1D(c(Md1,t), f ); } static B m1BI_d(B t, B f ) { return m_md1D(c(Md1,t), f ); }
static B m2BI_d(B t, B f, B g) { return m_md2D(c(Md2,t), f, g); } static B m2BI_d(B t, B f, B g) { return m_md2D(c(Md2,t), f, g); }
void rtWrap_init() { void rtWrap_init() {
TIi(t_funWrap,visit) = wf_visit; TIi(t_funWrap,identity) = wf_identity; TIi(t_funWrap,visit) = wfn_visit; TIi(t_funWrap,identity) = wfn_identity;
TIi(t_md1Wrap,visit) = wm1_visit; TIi(t_md1Wrap,m1_d) = m1BI_d; TIi(t_md1Wrap,visit) = wm1_visit; TIi(t_md1Wrap,m1_d) = m1BI_d;
TIi(t_md2Wrap,visit) = wm2_visit; TIi(t_md2Wrap,m2_d) = m2BI_d; TIi(t_md2Wrap,visit) = wm2_visit; TIi(t_md2Wrap,m2_d) = m2BI_d;
TIi(t_funWrap,fn_uc1) = wfn_uc1; TIi(t_funWrap,fn_uc1) = wfn_uc1;
@ -256,7 +291,7 @@ void rtWrap_init() {
void rtWrap_init() { } void rtWrap_init() { }
#endif #endif
void rtWrap_print() { void rtWrap_print() {
#ifdef RT_PERF #if RT_PERF
WFun* cf = lastWF; WFun* cf = lastWF;
while (cf) { while (cf) {
printRaw(c1(bi_glyph, tag(cf,FUN_TAG))); printRaw(c1(bi_glyph, tag(cf,FUN_TAG)));