global stack

This commit is contained in:
dzaima 2021-04-05 14:51:34 +03:00
parent d3eadf1d10
commit 6f63fcd92a
4 changed files with 61 additions and 34 deletions

View File

@ -118,6 +118,7 @@ typedef struct Arr {
void* mm_allocN(usz sz, u8 type);
void mm_free(Value* x);
void mm_visit(B x);
u64 mm_round(usz x);
B mm_alloc(usz sz, u8 type, u64 tag) {
assert(tag>1LL<<16 || tag==0); // make sure it's `ftag`ged :|
return b((u64)mm_allocN(sz,type) | tag);

View File

@ -14,6 +14,7 @@ struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else ca
EmptyValue* buckets[64];
#define BSZ(x) (1ull<<(x))
#define BSZI(x) (64-__builtin_clzl((x)-1ull))
EmptyValue* makeEmpty(u8 bucket) { // result->next is garbage
u8 cb = bucket;
@ -38,15 +39,15 @@ EmptyValue* makeEmpty(u8 bucket) { // result->next is garbage
break;
}
}
c->mmInfo = bucket;
while (cb != bucket) {
cb--;
EmptyValue* b = (EmptyValue*) (((char*)c)+BSZ(cb));
EmptyValue* b = (EmptyValue*) (BSZ(cb) + (char*)c);
b->type = t_empty;
b->mmInfo = cb;
b->next = 0; assert(buckets[cb]==0);
buckets[cb] = b;
}
c->mmInfo = bucket;
return c;
}
@ -61,7 +62,7 @@ void mm_free(Value* x) {
void* mm_allocN(usz sz, u8 type) {
assert(sz>8);
u8 bucket = 64-__builtin_clzl(sz-1ull); // inverse of BSZ
u8 bucket = BSZI(sz); // inverse of BSZ
EmptyValue* x = buckets[bucket];
if (x==NULL) x = makeEmpty(bucket);
else buckets[bucket] = x->next;
@ -72,6 +73,10 @@ void* mm_allocN(usz sz, u8 type) {
return x;
}
u64 mm_round(usz sz) {
return BSZ(BSZI(sz));
}
void mm_visit(B x) {
}

View File

@ -14,6 +14,11 @@ void* mm_allocN(usz sz, u8 type) {
x->type = type;
return x;
}
u64 mm_round(usz sz) {
return sz;
}
void mm_visit(B x) {
}

View File

@ -249,6 +249,23 @@ i32 bcDepth=-2;
i32* vmStack;
i32 bcCtr = 0;
#endif
B* gStack;
B* gStackStart;
B* gStackEnd;
void allocStack(u64 am) {
u64 left = gStackEnd-gStack;
if (am>left) {
u64 n = gStackEnd-gStackStart + am + 500;
u64 d = gStackStart-gStack;
if (gStack==NULL) gStackStart = malloc(n*sizeof(B));
else gStackStart = realloc(gStackStart, n*sizeof(B));
gStack = gStackStart+d;
gStackEnd = gStackStart+n;
}
}
B evalBC(Body* b, Scope* sc) {
#ifdef DEBUG_VM
bcDepth+= 2;
@ -260,11 +277,11 @@ B evalBC(Body* b, Scope* sc) {
B* objs = b->comp->objs->a;
Block** blocks = b->comp->blocks;
i32* bc = b->bc;
B stack[b->maxStack];
i32 sh = 0;
#define POP stack[--sh]
allocStack(b->maxStack);
#define POP (*--gStack)
#define P(N) B N=POP;
#define ADD stack[sh++] =
#define ADD(X) { B tr=X; *(gStack++) = tr; } // if ordering is needed
// #define ADD(X) *(gStack++) = X; } // if ordering is not needed
while(true) {
#ifdef DEBUG_VM
i32* sbc = bc;
@ -279,24 +296,24 @@ B evalBC(Body* b, Scope* sc) {
switch(*bc++) {
case POPS: dec(POP); break;
case PUSH: {
ADD inci(objs[*bc++]);
ADD(inci(objs[*bc++]));
break;
}
case FN1C: { P(f)P(x)
ADD c1(f, x); dec(f);
ADD(c1(f, x); dec(f));
break;
}
case FN1O: { P(f)P(x)
ADD isNothing(x)? x : c1(f, x); dec(f);
ADD(isNothing(x)? x : c1(f, x); dec(f));
break;
}
case FN2C: { P(w)P(f)P(x)
ADD c2(f, w, x); dec(f);
ADD(c2(f, w, x); dec(f));
break;
}
case FN2O: { P(w)P(f)P(x)
if (isNothing(x)) { dec(w); ADD x; }
else ADD isNothing(w)? c1(f, x) : c2(f, w, x);
if (isNothing(x)) { dec(w); ADD(x); }
else ADD(isNothing(w)? c1(f, x) : c2(f, w, x));
dec(f);
break;
}
@ -304,43 +321,43 @@ B evalBC(Body* b, Scope* sc) {
i32 sz = *bc++;
HArr_p r = m_harrv(sz);
for (i32 i = 0; i < sz; i++) r.a[sz-i-1] = POP;
ADD r.b;
ADD(r.b);
break;
}
case DFND: {
Block* bl = blocks[*bc++];
switch(bl->ty) { default: UD;
case 0: ADD m_funBlock(bl, sc); break;
case 1: ADD m_md1Block(bl, sc); break;
case 2: ADD m_md2Block(bl, sc); break;
case 0: ADD(m_funBlock(bl, sc)); break;
case 1: ADD(m_md1Block(bl, sc)); break;
case 2: ADD(m_md2Block(bl, sc)); break;
}
break;
}
case OP1D: { P(f)P(m) ADD m1_d (m,f ); break; }
case OP2D: { P(f)P(m)P(g) ADD m2_d (m,f,g); break; }
case OP2H: { P(m)P(g) ADD m2_h (m, g); break; }
case TR2D: { P(g)P(h) ADD m_atop( g,h); break; }
case TR3D: { P(f)P(g)P(h) ADD m_fork(f,g,h); break; }
case OP1D: { P(f)P(m) ADD(m1_d (m,f )); break; }
case OP2D: { P(f)P(m)P(g) ADD(m2_d (m,f,g)); break; }
case OP2H: { P(m)P(g) ADD(m2_h (m, g)); break; }
case TR2D: { P(g)P(h) ADD(m_atop( g,h)); break; }
case TR3D: { P(f)P(g)P(h) ADD(m_fork(f,g,h)); break; }
case TR3O: { P(f)P(g)P(h)
if (isNothing(f)) { ADD m_atop(g,h); dec(f); }
else ADD m_fork(f,g,h);
if (isNothing(f)) { ADD(m_atop(g,h)); dec(f); }
else ADD(m_fork(f,g,h));
break;
}
case LOCM: { i32 d = *bc++; i32 p = *bc++;
ADD tag((u64)d<<32 | p, VAR_TAG);
ADD(tag((u64)d<<32 | p, VAR_TAG));
break;
}
case LOCO: { i32 d = *bc++; i32 p = *bc++;
ADD inci(scd(sc,d)->vars[p]);
ADD(inci(scd(sc,d)->vars[p]));
break;
}
case SETN: { P(s) P(x) v_set(sc, s, inci(x), false); ADD x; break; }
case SETU: { P(s) P(x) v_set(sc, s, inci(x), true ); ADD x; break; }
case SETN: { P(s) P(x) v_set(sc, s, inci(x), false); ADD(x); break; }
case SETU: { P(s) P(x) v_set(sc, s, inci(x), true ); ADD(x); break; }
case SETM: { P(s)P(f)P(x)
B w = v_get(sc, s);
B r = c2(f,w,x); dec(f);
v_set(sc, s, inci(r), true);
ADD r;
ADD(r);
break;
}
// not implemented: VARO VARM CHKV VFYM SETH FLDO FLDM NSPM RETD SYSV
@ -358,15 +375,14 @@ B evalBC(Body* b, Scope* sc) {
for (i32 i = 0; i < sh; i++) { if(i)printf(""); print(stack[i]); } puts(""); fflush(stdout);
#endif
}
#undef P
#undef ADD
#undef POP
end:;
#ifdef DEBUG_VM
bcDepth-= 2;
#endif
assert(sh==1);
return stack[0];
return POP;
#undef P
#undef ADD
#undef POP
}
B actualExec(Block* bl, Scope* psc, u32 ga, B* svar) {