inline scope variable setting
This commit is contained in:
parent
4eb2ef8c5c
commit
8ad686ab1b
4
build
4
build
@ -1,3 +1,3 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
clang -std=gnu11 -O3 -Wall -Wno-microsoft-anon-tag -Wno-unused-function -fms-extensions $@ -o BQN src/opt/single.c -lm
|
clang -std=gnu11 -O3 -Wall -Wno-microsoft-anon-tag -Wno-unused-function -fms-extensions -no-pie $@ -o BQN src/opt/single.c -lm
|
||||||
# gcc -std=gnu11 -O3 -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions $@ -o BQN src/opt/single.c -lm
|
# gcc -std=gnu11 -O3 -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions -no-pie $@ -o BQN src/opt/single.c -lm
|
||||||
|
|||||||
4
buildg
4
buildg
@ -1,3 +1,3 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
clang -std=gnu11 -O3 -g -Wall -Wno-microsoft-anon-tag -fms-extensions -Wno-unused-function -fno-omit-frame-pointer $@ -o BQN src/opt/single.c -lm
|
clang -std=gnu11 -O3 -g -Wall -Wno-microsoft-anon-tag -fms-extensions -no-pie -Wno-unused-function -fno-omit-frame-pointer $@ -o BQN src/opt/single.c -lm
|
||||||
# gcc -std=gnu11 -O3 -g -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions -fno-omit-frame-pointer $@ -o BQN src/opt/single.c -lm
|
# gcc -std=gnu11 -O3 -g -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions -no-pie -fno-omit-frame-pointer $@ -o BQN src/opt/single.c -lm
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
clang -DDEBUG -std=gnu11 -g -Wall -Wno-microsoft-anon-tag -Wno-unused-function -fms-extensions $@ -o BQN src/opt/single.c -lm
|
clang -DDEBUG -std=gnu11 -g -Wall -Wno-microsoft-anon-tag -Wno-unused-function -fms-extensions -no-pie $@ -o BQN src/opt/single.c -lm
|
||||||
# gcc -DDEBUG -std=gnu11 -g -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions $@ -o BQN src/opt/single.c -lm
|
# gcc -DDEBUG -std=gnu11 -g -Wall -Wno-parentheses -Wno-misleading-indentation -Wno-unused-function -fms-extensions -no-pie $@ -o BQN src/opt/single.c -lm
|
||||||
|
|||||||
37
src/h.h
37
src/h.h
@ -101,8 +101,9 @@
|
|||||||
#define CHR_MAX 1114111
|
#define CHR_MAX 1114111
|
||||||
#define U16_MAX ((u16)~(u16)0)
|
#define U16_MAX ((u16)~(u16)0)
|
||||||
#define U32_MAX ((u32)~(u32)0)
|
#define U32_MAX ((u32)~(u32)0)
|
||||||
#define NOINLINE __attribute__ ((noinline))
|
#define NOINLINE __attribute__((noinline))
|
||||||
#define NORETURN __attribute__ ((noreturn))
|
#define FORCE_INLINE __attribute__((always_inline)) static inline
|
||||||
|
#define NORETURN __attribute__((noreturn))
|
||||||
#define AUTO __auto_type
|
#define AUTO __auto_type
|
||||||
#define LIKELY(X) __builtin_expect(X,1)
|
#define LIKELY(X) __builtin_expect(X,1)
|
||||||
#define RARE(X) __builtin_expect(X,0)
|
#define RARE(X) __builtin_expect(X,0)
|
||||||
@ -125,22 +126,22 @@ CTR_FOR(F)
|
|||||||
#define fsizeof(T,F,E,N) (offsetof(T, F) + sizeof(E)*(N)) // type, flexible array member name, flexible array member type, item amount
|
#define fsizeof(T,F,E,N) (offsetof(T, F) + sizeof(E)*(N)) // type, flexible array member name, flexible array member type, item amount
|
||||||
#define ftag(x) ((u64)(x) << 48)
|
#define ftag(x) ((u64)(x) << 48)
|
||||||
#define tag(v, t) b(((u64)(v)) | ftag(t))
|
#define tag(v, t) b(((u64)(v)) | ftag(t))
|
||||||
// .111111111110000000000000000000000000000000000000000000000000000 infinity
|
// .FF0 .111111111110000000000000000000000000000000000000000000000000000 infinity
|
||||||
// .111111111111000000000000000000000000000000000000000000000000000 qNaN
|
// .FF8 .111111111111000000000000000000000000000000000000000000000000000 qNaN
|
||||||
// .111111111110nnn................................................ sNaN aka tagged aka not f64, if nnn≠0
|
// .FF. .111111111110nnn................................................ sNaN aka tagged aka not f64, if nnn≠0
|
||||||
// 0111111111110................................................... direct value with no need of refcounting
|
// 7FF. 0111111111110................................................... direct value with no need of refcounting
|
||||||
static const u16 C32_TAG = 0b0111111111110001; // 0111111111110001................00000000000ccccccccccccccccccccc char
|
static const u16 C32_TAG = 0b0111111111110001; // 7FF1 0111111111110001................00000000000ccccccccccccccccccccc char
|
||||||
static const u16 TAG_TAG = 0b0111111111110010; // 0111111111110010................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn special value (0=nothing, 1=undefined var, 2=bad header; 3=optimized out; 4=error?; 5=no fill)
|
static const u16 TAG_TAG = 0b0111111111110010; // 7FF2 0111111111110010................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn special value (0=nothing, 1=undefined var, 2=bad header; 3=optimized out; 4=error?; 5=no fill)
|
||||||
static const u16 VAR_TAG = 0b0111111111110011; // 0111111111110011ddddddddddddddddnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn variable reference
|
static const u16 VAR_TAG = 0b0111111111110011; // 7FF3 0111111111110011ddddddddddddddddnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn variable reference
|
||||||
static const u16 EXT_TAG = 0b0111111111110100; // 0111111111110100ddddddddddddddddnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn extended variable reference
|
static const u16 EXT_TAG = 0b0111111111110100; // 7FF4 0111111111110100ddddddddddddddddnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn extended variable reference
|
||||||
static const u16 I32_TAG = 0b0111111111110111; // 0111111111110111................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn 32-bit int; unused
|
static const u16 I32_TAG = 0b0111111111110111; // 7FF7 0111111111110111................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn 32-bit int; unused
|
||||||
static const u16 MD1_TAG = 0b1111111111110010; // 1111111111110010ppppppppppppppppppppppppppppppppppppppppppppp000 1-modifier
|
static const u16 MD1_TAG = 0b1111111111110010; // FFF2 1111111111110010ppppppppppppppppppppppppppppppppppppppppppppp000 1-modifier
|
||||||
static const u16 MD2_TAG = 0b1111111111110011; // 1111111111110011ppppppppppppppppppppppppppppppppppppppppppppp000 2-modifier
|
static const u16 MD2_TAG = 0b1111111111110011; // FFF3 1111111111110011ppppppppppppppppppppppppppppppppppppppppppppp000 2-modifier
|
||||||
static const u16 FUN_TAG = 0b1111111111110100; // 1111111111110100ppppppppppppppppppppppppppppppppppppppppppppp000 function
|
static const u16 FUN_TAG = 0b1111111111110100; // FFF4 1111111111110100ppppppppppppppppppppppppppppppppppppppppppppp000 function
|
||||||
static const u16 NSP_TAG = 0b1111111111110101; // 1111111111110101ppppppppppppppppppppppppppppppppppppppppppppp000 namespace maybe?
|
static const u16 NSP_TAG = 0b1111111111110101; // FFF5 1111111111110101ppppppppppppppppppppppppppppppppppppppppppppp000 namespace maybe?
|
||||||
static const u16 OBJ_TAG = 0b1111111111110110; // 1111111111110110ppppppppppppppppppppppppppppppppppppppppppppp000 custom object (e.g. bigints)
|
static const u16 OBJ_TAG = 0b1111111111110110; // FFF6 1111111111110110ppppppppppppppppppppppppppppppppppppppppppppp000 custom object (e.g. bigints)
|
||||||
static const u16 ARR_TAG = 0b1111111111110111; // 1111111111110111ppppppppppppppppppppppppppppppppppppppppppppp000 array (everything else is an atom)
|
static const u16 ARR_TAG = 0b1111111111110111; // FFF7 1111111111110111ppppppppppppppppppppppppppppppppppppppppppppp000 array (everything else is an atom)
|
||||||
static const u16 VAL_TAG = 0b1111111111110 ; // 1111111111110................................................... pointer to Value, needs refcounting
|
static const u16 VAL_TAG = 0b1111111111110 ; // FFF. 1111111111110................................................... pointer to Value, needs refcounting
|
||||||
|
|
||||||
void cbqn_init();
|
void cbqn_init();
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ static void repl_init() {
|
|||||||
cbqn_init();
|
cbqn_init();
|
||||||
replPath = m_str32(U"REPL"); gc_add(replPath);
|
replPath = m_str32(U"REPL"); gc_add(replPath);
|
||||||
Block* initBlock = bqn_comp(m_str32(U"\"(REPL initializer)\""), inc(replPath), m_f64(0));
|
Block* initBlock = bqn_comp(m_str32(U"\"(REPL initializer)\""), inc(replPath), m_f64(0));
|
||||||
gsc = m_scope(initBlock->body, NULL, 0); gc_add(tag(gsc,OBJ_TAG));
|
gsc = m_scope(initBlock->body, NULL, 0, 0, NULL); gc_add(tag(gsc,OBJ_TAG));
|
||||||
ptr_dec(initBlock);
|
ptr_dec(initBlock);
|
||||||
init = true;
|
init = true;
|
||||||
}
|
}
|
||||||
|
|||||||
75
src/vm.c
75
src/vm.c
@ -564,39 +564,22 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
|||||||
#undef GS_UPD
|
#undef GS_UPD
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope* m_scope(Body* body, Scope* psc, u16 varAm) { // doesn't consume
|
Scope* m_scope(Body* body, Scope* psc, u16 varAm, i32 initVarAm, B* initVars) { // doesn't consume
|
||||||
Scope* sc = mm_allocN(fsizeof(Scope, vars, B, varAm), t_scope);
|
Scope* sc = mm_allocN(fsizeof(Scope, vars, B, varAm), t_scope);
|
||||||
sc->body = body; ptr_inc(body);
|
sc->body = body; ptr_inc(body);
|
||||||
sc->psc = psc; if(psc) ptr_inc(psc);
|
sc->psc = psc; if(psc) ptr_inc(psc);
|
||||||
sc->varAm = varAm;
|
sc->varAm = varAm;
|
||||||
sc->ext = NULL;
|
sc->ext = NULL;
|
||||||
|
i32 i = 0;
|
||||||
|
while (i<initVarAm) { sc->vars[i] = initVars[i]; i++; }
|
||||||
|
while (i<varAm) sc->vars[i++] = bi_noVar;
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
static void scope_dec(Scope* sc) {
|
||||||
B actualExec(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents
|
i32 varAm = sc->varAm;
|
||||||
Body* body = bl->body;
|
|
||||||
u16 varAm = body->varAm;
|
|
||||||
assert(varAm>=ga);
|
|
||||||
Scope* sc = m_scope(body, psc, varAm);
|
|
||||||
i32 i = 0;
|
|
||||||
while (i<ga) { sc->vars[i] = svar[i]; i++; }
|
|
||||||
while (i<varAm) sc->vars[i++] = bi_noVar;
|
|
||||||
bool jit = USE_JIT;
|
|
||||||
// jit = body->bc[2]==m_f64(123456).u>>32; // enable JIT just for blocks starting with `123456⋄`
|
|
||||||
B r;
|
|
||||||
if (jit) {
|
|
||||||
if (!body->nvm) {
|
|
||||||
Nvm_res r = m_nvm(body);
|
|
||||||
body->nvm = r.p;
|
|
||||||
body->nvmRefs = r.refs;
|
|
||||||
}
|
|
||||||
r = evalJIT(body, sc, body->nvm);
|
|
||||||
} else {
|
|
||||||
r = evalBC(body, sc);
|
|
||||||
}
|
|
||||||
if (sc->refc>1) {
|
if (sc->refc>1) {
|
||||||
usz innerRef = 1;
|
usz innerRef = 1;
|
||||||
for (i = 0; i < varAm; i++) {
|
for (i32 i = 0; i < varAm; i++) {
|
||||||
B c = sc->vars[i];
|
B c = sc->vars[i];
|
||||||
if (isVal(c) && v(c)->refc==1) {
|
if (isVal(c) && v(c)->refc==1) {
|
||||||
u8 t = v(c)->type;
|
u8 t = v(c)->type;
|
||||||
@ -608,21 +591,45 @@ B actualExec(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents
|
|||||||
assert(innerRef<=sc->refc);
|
assert(innerRef<=sc->refc);
|
||||||
if (innerRef==sc->refc) {
|
if (innerRef==sc->refc) {
|
||||||
value_free((Value*)sc);
|
value_free((Value*)sc);
|
||||||
return r;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ptr_dec(sc);
|
ptr_dec(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
B execBodyInline(Body* body, Scope* sc) {
|
||||||
|
bool jit = USE_JIT;
|
||||||
|
// jit = body->bc[2]==m_f64(123456).u>>32; // enable JIT just for blocks starting with `123456⋄`
|
||||||
|
if (jit) {
|
||||||
|
if (!body->nvm) {
|
||||||
|
Nvm_res r = m_nvm(body);
|
||||||
|
body->nvm = r.p;
|
||||||
|
body->nvmRefs = r.refs;
|
||||||
|
}
|
||||||
|
return evalJIT(body, sc, body->nvm);
|
||||||
|
} else {
|
||||||
|
return evalBC(body, sc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE B execBlock(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents
|
||||||
|
Body* body = bl->body;
|
||||||
|
u16 varAm = body->varAm;
|
||||||
|
assert(varAm>=ga);
|
||||||
|
Scope* sc = m_scope(body, psc, varAm, ga, svar);
|
||||||
|
B r = execBodyInline(body, sc);
|
||||||
|
scope_dec(sc);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
B funBl_c1(B t, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return actualExec(b->bl, b->sc, 3, (B[]){t, x, bi_N }); }
|
B funBl_c1(B t, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return execBlock(b->bl, b->sc, 3, (B[]){t, x, bi_N }); }
|
||||||
B funBl_c2(B t, B w, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return actualExec(b->bl, b->sc, 3, (B[]){t, x, w }); }
|
B funBl_c2(B t, B w, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return execBlock(b->bl, b->sc, 3, (B[]){t, x, w }); }
|
||||||
B md1Bl_c1(B D, B x) { Md1D* d=c(Md1D,D); Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); return actualExec(b->bl, b->sc, 5, (B[]){D, x, bi_N, inc(d->m1), inc(d->f) }); }
|
B md1Bl_c1(B D, B x) { Md1D* d=c(Md1D,D); Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); return execBlock(b->bl, b->sc, 5, (B[]){D, x, bi_N, inc(d->m1), inc(d->f) }); }
|
||||||
B md1Bl_c2(B D, B w, B x) { Md1D* d=c(Md1D,D); Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); return actualExec(b->bl, b->sc, 5, (B[]){D, x, w , inc(d->m1), inc(d->f) }); }
|
B md1Bl_c2(B D, B w, B x) { Md1D* d=c(Md1D,D); Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); return execBlock(b->bl, b->sc, 5, (B[]){D, x, w , inc(d->m1), inc(d->f) }); }
|
||||||
B md2Bl_c1(B D, B x) { Md2D* d=c(Md2D,D); Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return actualExec(b->bl, b->sc, 6, (B[]){D, x, bi_N, inc(d->m2), inc(d->f), inc(d->g)}); }
|
B md2Bl_c1(B D, B x) { Md2D* d=c(Md2D,D); Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return execBlock(b->bl, b->sc, 6, (B[]){D, x, bi_N, inc(d->m2), inc(d->f), inc(d->g)}); }
|
||||||
B md2Bl_c2(B D, B w, B x) { Md2D* d=c(Md2D,D); Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return actualExec(b->bl, b->sc, 6, (B[]){D, x, w , inc(d->m2), inc(d->f), inc(d->g)}); }
|
B md2Bl_c2(B D, B w, B x) { Md2D* d=c(Md2D,D); Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return execBlock(b->bl, b->sc, 6, (B[]){D, x, w , inc(d->m2), inc(d->f), inc(d->g)}); }
|
||||||
B m_funBlock(Block* bl, Scope* psc) { // doesn't consume anything
|
B m_funBlock(Block* bl, Scope* psc) { // doesn't consume anything
|
||||||
if (bl->imm) return actualExec(bl, psc, 0, NULL);
|
if (bl->imm) return execBlock(bl, psc, 0, NULL);
|
||||||
B r = mm_alloc(sizeof(FunBlock), t_fun_block, ftag(FUN_TAG));
|
B r = mm_alloc(sizeof(FunBlock), t_fun_block, ftag(FUN_TAG));
|
||||||
c(FunBlock, r)->bl = bl; ptr_inc(bl);
|
c(FunBlock, r)->bl = bl; ptr_inc(bl);
|
||||||
c(FunBlock, r)->sc = psc; ptr_inc(psc);
|
c(FunBlock, r)->sc = psc; ptr_inc(psc);
|
||||||
@ -720,8 +727,8 @@ void md2Bl_print(B x) { printf("{2-modifier block}"); }
|
|||||||
|
|
||||||
B block_decompose(B x) { return m_v2(m_i32(1), x); }
|
B block_decompose(B x) { return m_v2(m_i32(1), x); }
|
||||||
|
|
||||||
B bl_m1d(B m, B f ) { Md1Block* c = c(Md1Block,m); return c->bl->imm? actualExec(c(Md1Block, m)->bl, c(Md1Block, m)->sc, 2, (B[]){m, f }) : m_md1D(m,f ); }
|
B bl_m1d(B m, B f ) { Md1Block* c = c(Md1Block,m); return c->bl->imm? execBlock(c(Md1Block, m)->bl, c(Md1Block, m)->sc, 2, (B[]){m, f }) : m_md1D(m,f ); }
|
||||||
B bl_m2d(B m, B f, B g) { Md2Block* c = c(Md2Block,m); return c->bl->imm? actualExec(c(Md2Block, m)->bl, c(Md2Block, m)->sc, 3, (B[]){m, f, g}) : m_md2D(m,f,g); }
|
B bl_m2d(B m, B f, B g) { Md2Block* c = c(Md2Block,m); return c->bl->imm? execBlock(c(Md2Block, m)->bl, c(Md2Block, m)->sc, 3, (B[]){m, f, g}) : m_md2D(m,f,g); }
|
||||||
|
|
||||||
void allocStack(void** curr, void** start, void** end, i32 elSize, i32 count) {
|
void allocStack(void** curr, void** start, void** end, i32 elSize, i32 count) {
|
||||||
usz pageSize = sysconf(_SC_PAGESIZE);
|
usz pageSize = sysconf(_SC_PAGESIZE);
|
||||||
|
|||||||
2
src/vm.h
2
src/vm.h
@ -104,7 +104,7 @@ struct Scope {
|
|||||||
Block* bqn_comp(B str, B path, B args);
|
Block* bqn_comp(B str, B path, B args);
|
||||||
Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl);
|
Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl);
|
||||||
Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src, Scope* sc);
|
Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src, Scope* sc);
|
||||||
Scope* m_scope(Body* body, Scope* psc, u16 varAm);
|
Scope* m_scope(Body* body, Scope* psc, u16 varAm, i32 initVarAm, B* initVars);
|
||||||
B evalBC(Body* b, Scope* sc); // doesn't consume; executes bytecode of the body directly in the scope
|
B evalBC(Body* b, Scope* sc); // doesn't consume; executes bytecode of the body directly in the scope
|
||||||
|
|
||||||
u32* nextBC(u32* p);
|
u32* nextBC(u32* p);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user