Simplify frame logic.
This commit is contained in:
1 parent
e0524644f8
commit
5f5c1dc5a6
3 files changed
+47
-85
No files matched your search
+31
-54
@@ -7,88 +7,65 @@ struct closure {
|
||||
stack_ptr env;
|
||||
};
|
||||
|
||||
struct continuation {
|
||||
union frame_entry {
|
||||
struct closure closure;
|
||||
jv localvar;
|
||||
};
|
||||
|
||||
struct frame {
|
||||
struct bytecode* bc;
|
||||
stack_ptr env;
|
||||
stack_ptr retdata;
|
||||
uint16_t* retaddr;
|
||||
/* bc->nclosures closures followed by bc->nlocals local variables */
|
||||
union frame_entry entries[0];
|
||||
};
|
||||
|
||||
typedef union frame_elem {
|
||||
struct continuation cont;
|
||||
struct closure closure;
|
||||
jv jsonval;
|
||||
} *frame_ptr;
|
||||
|
||||
/*
|
||||
* Frame layout
|
||||
* fr[0] - FORKABLE_STACK_HEADER (next pointer)
|
||||
* fr[1] - self (used to store return addresses, etc)
|
||||
* fr[2...nclosures+2] - closure params
|
||||
* fr[nclosures+2..nclosures+nlocals+2] - local variables
|
||||
*/
|
||||
|
||||
static int frame_size(struct bytecode* bc) {
|
||||
return sizeof(union frame_elem) * (bc->nclosures + bc->nlocals + 2);
|
||||
return sizeof(struct frame) + sizeof(union frame_entry) * (bc->nclosures + bc->nlocals);
|
||||
}
|
||||
|
||||
static struct continuation* frame_self(frame_ptr fr) {
|
||||
return &fr[1].cont;
|
||||
}
|
||||
|
||||
static struct closure* frame_closure_arg(frame_ptr fr, int closure) {
|
||||
static struct closure* frame_closure_arg(struct frame* fr, int closure) {
|
||||
assert(closure >= 0);
|
||||
assert(closure < frame_self(fr)->bc->nclosures);
|
||||
return &fr[2+closure].closure;
|
||||
assert(closure < fr->bc->nclosures);
|
||||
return &fr->entries[closure].closure;
|
||||
}
|
||||
|
||||
static jv* frame_local_var(frame_ptr fr, int var) {
|
||||
static jv* frame_local_var(struct frame* fr, int var) {
|
||||
assert(var >= 0);
|
||||
assert(var < frame_self(fr)->bc->nlocals);
|
||||
return &fr[2 + frame_self(fr)->bc->nclosures + var].jsonval;
|
||||
assert(var < fr->bc->nlocals);
|
||||
return &fr->entries[fr->bc->nclosures + var].localvar;
|
||||
}
|
||||
|
||||
|
||||
static frame_ptr frame_current(struct stack* stk, stack_ptr idx) {
|
||||
frame_ptr fp = stack_block(stk, idx);
|
||||
static struct frame* frame_current(struct stack* stk, stack_ptr idx) {
|
||||
struct frame* fp = stack_block(stk, idx);
|
||||
|
||||
stack_ptr next = *stack_block_next(stk, idx);
|
||||
if (next) {
|
||||
frame_ptr fpnext = stack_block(stk, next);
|
||||
struct bytecode* bc = frame_self(fpnext)->bc;
|
||||
assert(frame_self(fp)->retaddr >= bc->code && frame_self(fp)->retaddr < bc->code + bc->codelen);
|
||||
struct frame* fpnext = stack_block(stk, next);
|
||||
struct bytecode* bc = fpnext->bc;
|
||||
assert(fp->retaddr >= bc->code && fp->retaddr < bc->code + bc->codelen);
|
||||
} else {
|
||||
assert(frame_self(fp)->retaddr == 0);
|
||||
assert(fp->retaddr == 0);
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
static struct bytecode* frame_current_bytecode(struct stack* stk, stack_ptr curr) {
|
||||
return frame_self(frame_current(stk, curr))->bc;
|
||||
}
|
||||
static uint16_t** frame_current_retaddr(struct stack* stk, stack_ptr curr) {
|
||||
return &frame_self(frame_current(stk, curr))->retaddr;
|
||||
}
|
||||
|
||||
static stack_ptr frame_get_parent(struct stack* stk, stack_ptr fr) {
|
||||
return frame_self(stack_block(stk, fr))->env;
|
||||
}
|
||||
|
||||
static stack_ptr frame_get_level(struct stack* stk, stack_ptr fr, int level) {
|
||||
for (int i=0; i<level; i++) {
|
||||
fr = frame_get_parent(stk, fr);
|
||||
struct frame* fp = stack_block(stk, fr);
|
||||
fr = fp->env;
|
||||
}
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stack_ptr frame_push(struct stack* stk, stack_ptr curr, struct closure cl, uint16_t* retaddr, stack_ptr datastk) {
|
||||
stack_ptr fpidx = stack_push_block(stk, curr, frame_size(cl.bc));
|
||||
frame_ptr fp = stack_block(stk, fpidx);
|
||||
struct continuation* cc = frame_self(fp);
|
||||
cc->bc = cl.bc;
|
||||
cc->env = cl.env;
|
||||
cc->retdata = datastk;
|
||||
cc->retaddr = retaddr;
|
||||
struct frame* fp = stack_block(stk, fpidx);
|
||||
fp->bc = cl.bc;
|
||||
fp->env = cl.env;
|
||||
fp->retdata = datastk;
|
||||
fp->retaddr = retaddr;
|
||||
for (int i=0; i<cl.bc->nlocals; i++) {
|
||||
*frame_local_var(fp, i) = jv_invalid();
|
||||
}
|
||||
@@ -96,14 +73,14 @@ static stack_ptr frame_push(struct stack* stk, stack_ptr curr, struct closure cl
|
||||
}
|
||||
|
||||
static stack_ptr frame_pop(struct stack* stk, stack_ptr curr) {
|
||||
frame_ptr fp = frame_current(stk, curr);
|
||||
struct frame* fp = frame_current(stk, curr);
|
||||
if (stack_pop_will_free(stk, curr)) {
|
||||
int nlocals = frame_self(fp)->bc->nlocals;
|
||||
int nlocals = fp->bc->nlocals;
|
||||
for (int i=0; i<nlocals; i++) {
|
||||
jv_free(*frame_local_var(fp, i));
|
||||
}
|
||||
}
|
||||
return stack_pop_block(stk, curr, frame_size(frame_self(fp)->bc));
|
||||
return stack_pop_block(stk, curr, frame_size(fp->bc));
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user