global stack
This commit is contained in:
parent
d3eadf1d10
commit
6f63fcd92a
1
src/h.h
1
src/h.h
@ -118,6 +118,7 @@ typedef struct Arr {
|
|||||||
void* mm_allocN(usz sz, u8 type);
|
void* mm_allocN(usz sz, u8 type);
|
||||||
void mm_free(Value* x);
|
void mm_free(Value* x);
|
||||||
void mm_visit(B x);
|
void mm_visit(B x);
|
||||||
|
u64 mm_round(usz x);
|
||||||
B mm_alloc(usz sz, u8 type, u64 tag) {
|
B mm_alloc(usz sz, u8 type, u64 tag) {
|
||||||
assert(tag>1LL<<16 || tag==0); // make sure it's `ftag`ged :|
|
assert(tag>1LL<<16 || tag==0); // make sure it's `ftag`ged :|
|
||||||
return b((u64)mm_allocN(sz,type) | tag);
|
return b((u64)mm_allocN(sz,type) | tag);
|
||||||
|
|||||||
@ -14,6 +14,7 @@ struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else ca
|
|||||||
EmptyValue* buckets[64];
|
EmptyValue* buckets[64];
|
||||||
|
|
||||||
#define BSZ(x) (1ull<<(x))
|
#define BSZ(x) (1ull<<(x))
|
||||||
|
#define BSZI(x) (64-__builtin_clzl((x)-1ull))
|
||||||
|
|
||||||
EmptyValue* makeEmpty(u8 bucket) { // result->next is garbage
|
EmptyValue* makeEmpty(u8 bucket) { // result->next is garbage
|
||||||
u8 cb = bucket;
|
u8 cb = bucket;
|
||||||
@ -38,15 +39,15 @@ EmptyValue* makeEmpty(u8 bucket) { // result->next is garbage
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
c->mmInfo = bucket;
|
||||||
while (cb != bucket) {
|
while (cb != bucket) {
|
||||||
cb--;
|
cb--;
|
||||||
EmptyValue* b = (EmptyValue*) (((char*)c)+BSZ(cb));
|
EmptyValue* b = (EmptyValue*) (BSZ(cb) + (char*)c);
|
||||||
b->type = t_empty;
|
b->type = t_empty;
|
||||||
b->mmInfo = cb;
|
b->mmInfo = cb;
|
||||||
b->next = 0; assert(buckets[cb]==0);
|
b->next = 0; assert(buckets[cb]==0);
|
||||||
buckets[cb] = b;
|
buckets[cb] = b;
|
||||||
}
|
}
|
||||||
c->mmInfo = bucket;
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ void mm_free(Value* x) {
|
|||||||
|
|
||||||
void* mm_allocN(usz sz, u8 type) {
|
void* mm_allocN(usz sz, u8 type) {
|
||||||
assert(sz>8);
|
assert(sz>8);
|
||||||
u8 bucket = 64-__builtin_clzl(sz-1ull); // inverse of BSZ
|
u8 bucket = BSZI(sz); // inverse of BSZ
|
||||||
EmptyValue* x = buckets[bucket];
|
EmptyValue* x = buckets[bucket];
|
||||||
if (x==NULL) x = makeEmpty(bucket);
|
if (x==NULL) x = makeEmpty(bucket);
|
||||||
else buckets[bucket] = x->next;
|
else buckets[bucket] = x->next;
|
||||||
@ -72,6 +73,10 @@ void* mm_allocN(usz sz, u8 type) {
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 mm_round(usz sz) {
|
||||||
|
return BSZ(BSZI(sz));
|
||||||
|
}
|
||||||
|
|
||||||
void mm_visit(B x) {
|
void mm_visit(B x) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,11 @@ void* mm_allocN(usz sz, u8 type) {
|
|||||||
x->type = type;
|
x->type = type;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 mm_round(usz sz) {
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
void mm_visit(B x) {
|
void mm_visit(B x) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
78
src/vm.c
78
src/vm.c
@ -249,6 +249,23 @@ i32 bcDepth=-2;
|
|||||||
i32* vmStack;
|
i32* vmStack;
|
||||||
i32 bcCtr = 0;
|
i32 bcCtr = 0;
|
||||||
#endif
|
#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) {
|
B evalBC(Body* b, Scope* sc) {
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
bcDepth+= 2;
|
bcDepth+= 2;
|
||||||
@ -260,11 +277,11 @@ B evalBC(Body* b, Scope* sc) {
|
|||||||
B* objs = b->comp->objs->a;
|
B* objs = b->comp->objs->a;
|
||||||
Block** blocks = b->comp->blocks;
|
Block** blocks = b->comp->blocks;
|
||||||
i32* bc = b->bc;
|
i32* bc = b->bc;
|
||||||
B stack[b->maxStack];
|
allocStack(b->maxStack);
|
||||||
i32 sh = 0;
|
#define POP (*--gStack)
|
||||||
#define POP stack[--sh]
|
|
||||||
#define P(N) B N=POP;
|
#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) {
|
while(true) {
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
i32* sbc = bc;
|
i32* sbc = bc;
|
||||||
@ -279,24 +296,24 @@ B evalBC(Body* b, Scope* sc) {
|
|||||||
switch(*bc++) {
|
switch(*bc++) {
|
||||||
case POPS: dec(POP); break;
|
case POPS: dec(POP); break;
|
||||||
case PUSH: {
|
case PUSH: {
|
||||||
ADD inci(objs[*bc++]);
|
ADD(inci(objs[*bc++]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FN1C: { P(f)P(x)
|
case FN1C: { P(f)P(x)
|
||||||
ADD c1(f, x); dec(f);
|
ADD(c1(f, x); dec(f));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FN1O: { P(f)P(x)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case FN2C: { P(w)P(f)P(x)
|
case FN2C: { P(w)P(f)P(x)
|
||||||
ADD c2(f, w, x); dec(f);
|
ADD(c2(f, w, x); dec(f));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FN2O: { P(w)P(f)P(x)
|
case FN2O: { P(w)P(f)P(x)
|
||||||
if (isNothing(x)) { dec(w); ADD x; }
|
if (isNothing(x)) { dec(w); ADD(x); }
|
||||||
else ADD isNothing(w)? c1(f, x) : c2(f, w, x);
|
else ADD(isNothing(w)? c1(f, x) : c2(f, w, x));
|
||||||
dec(f);
|
dec(f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -304,43 +321,43 @@ B evalBC(Body* b, Scope* sc) {
|
|||||||
i32 sz = *bc++;
|
i32 sz = *bc++;
|
||||||
HArr_p r = m_harrv(sz);
|
HArr_p r = m_harrv(sz);
|
||||||
for (i32 i = 0; i < sz; i++) r.a[sz-i-1] = POP;
|
for (i32 i = 0; i < sz; i++) r.a[sz-i-1] = POP;
|
||||||
ADD r.b;
|
ADD(r.b);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DFND: {
|
case DFND: {
|
||||||
Block* bl = blocks[*bc++];
|
Block* bl = blocks[*bc++];
|
||||||
switch(bl->ty) { default: UD;
|
switch(bl->ty) { default: UD;
|
||||||
case 0: ADD m_funBlock(bl, sc); break;
|
case 0: ADD(m_funBlock(bl, sc)); break;
|
||||||
case 1: ADD m_md1Block(bl, sc); break;
|
case 1: ADD(m_md1Block(bl, sc)); break;
|
||||||
case 2: ADD m_md2Block(bl, sc); break;
|
case 2: ADD(m_md2Block(bl, sc)); break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP1D: { P(f)P(m) ADD m1_d (m,f ); 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 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 OP2H: { P(m)P(g) ADD(m2_h (m, g)); break; }
|
||||||
case TR2D: { P(g)P(h) ADD m_atop( g,h); 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 TR3D: { P(f)P(g)P(h) ADD(m_fork(f,g,h)); break; }
|
||||||
case TR3O: { P(f)P(g)P(h)
|
case TR3O: { P(f)P(g)P(h)
|
||||||
if (isNothing(f)) { ADD m_atop(g,h); dec(f); }
|
if (isNothing(f)) { ADD(m_atop(g,h)); dec(f); }
|
||||||
else ADD m_fork(f,g,h);
|
else ADD(m_fork(f,g,h));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LOCM: { i32 d = *bc++; i32 p = *bc++;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case LOCO: { i32 d = *bc++; i32 p = *bc++;
|
case LOCO: { i32 d = *bc++; i32 p = *bc++;
|
||||||
ADD inci(scd(sc,d)->vars[p]);
|
ADD(inci(scd(sc,d)->vars[p]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SETN: { P(s) P(x) v_set(sc, s, inci(x), false); 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 SETU: { P(s) P(x) v_set(sc, s, inci(x), true ); ADD(x); break; }
|
||||||
case SETM: { P(s)P(f)P(x)
|
case SETM: { P(s)P(f)P(x)
|
||||||
B w = v_get(sc, s);
|
B w = v_get(sc, s);
|
||||||
B r = c2(f,w,x); dec(f);
|
B r = c2(f,w,x); dec(f);
|
||||||
v_set(sc, s, inci(r), true);
|
v_set(sc, s, inci(r), true);
|
||||||
ADD r;
|
ADD(r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// not implemented: VARO VARM CHKV VFYM SETH FLDO FLDM NSPM RETD SYSV
|
// 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);
|
for (i32 i = 0; i < sh; i++) { if(i)printf(" ⋄ "); print(stack[i]); } puts(""); fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#undef P
|
|
||||||
#undef ADD
|
|
||||||
#undef POP
|
|
||||||
end:;
|
end:;
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
bcDepth-= 2;
|
bcDepth-= 2;
|
||||||
#endif
|
#endif
|
||||||
assert(sh==1);
|
return POP;
|
||||||
return stack[0];
|
#undef P
|
||||||
|
#undef ADD
|
||||||
|
#undef POP
|
||||||
}
|
}
|
||||||
|
|
||||||
B actualExec(Block* bl, Scope* psc, u32 ga, B* svar) {
|
B actualExec(Block* bl, Scope* psc, u32 ga, B* svar) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user