mirror of
https://github.com/janet-lang/janet
synced 2025-01-23 05:36:52 +00:00
Update func env representation to not store envs in function
objects.
This commit is contained in:
parent
e124029ae3
commit
a614816a04
@ -187,17 +187,19 @@ static int32_t dst_asm_addenv(DstAssembler *a, Dst envname) {
|
||||
int32_t envindex;
|
||||
int32_t res;
|
||||
if (dst_equals(a->name, envname)) {
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
/* Check for memoized value */
|
||||
check = dst_table_get(&a->envs, envname);
|
||||
if (dst_checktype(check, DST_INTEGER)) return dst_unwrap_integer(check);
|
||||
if (NULL == a->parent) return -1;
|
||||
if (dst_checktype(check, DST_INTEGER)) {
|
||||
return dst_unwrap_integer(check);
|
||||
}
|
||||
if (NULL == a->parent) return -2;
|
||||
res = dst_asm_addenv(a->parent, envname);
|
||||
if (res < 0)
|
||||
if (res < -1) {
|
||||
return res;
|
||||
}
|
||||
envindex = def->environments_length;
|
||||
if (envindex == 0) envindex = 1;
|
||||
dst_table_put(&a->envs, envname, dst_wrap_integer(envindex));
|
||||
if (envindex >= a->environments_capacity) {
|
||||
int32_t newcap = 2 * envindex;
|
||||
@ -291,7 +293,7 @@ static int32_t doarg_1(
|
||||
if (argtype == DST_OAT_ENVIRONMENT && ret == -1) {
|
||||
/* Add a new env */
|
||||
ret = dst_asm_addenv(a, x);
|
||||
if (ret < 0) {
|
||||
if (ret < -1) {
|
||||
dst_asm_errorv(a, dst_formatc("unknown environment %q", x));
|
||||
}
|
||||
}
|
||||
@ -788,8 +790,7 @@ Dst dst_disasm(DstFuncDef *def) {
|
||||
DstArray *bcode = dst_array(def->bytecode_length);
|
||||
DstArray *constants;
|
||||
DstTable *ret = dst_table(10);
|
||||
if (def->arity)
|
||||
dst_table_put(ret, dst_csymbolv("arity"), dst_wrap_integer(def->arity));
|
||||
dst_table_put(ret, dst_csymbolv("arity"), dst_wrap_integer(def->arity));
|
||||
dst_table_put(ret, dst_csymbolv("bytecode"), dst_wrap_array(bcode));
|
||||
if (NULL != def->sourcepath) {
|
||||
dst_table_put(ret, dst_csymbolv("sourcepath"),
|
||||
@ -871,7 +872,7 @@ int dst_asm_cfun(DstArgs args) {
|
||||
if (args.n < 1) return dst_throw(args, "expected assembly source");
|
||||
res = dst_asm(args.v[0], 0);
|
||||
if (res.status == DST_ASSEMBLE_OK) {
|
||||
return dst_return(args, dst_wrap_function(dst_function(res.funcdef, NULL)));
|
||||
return dst_return(args, dst_wrap_function(dst_thunk(res.funcdef)));
|
||||
} else {
|
||||
return dst_throwv(args, dst_wrap_string(res.error));
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ int32_t dstc_lslotn(DstCompiler *c, int32_t max, int32_t nth) {
|
||||
/* Free a slot */
|
||||
void dstc_freeslot(DstCompiler *c, DstSlot s) {
|
||||
if (s.flags & (DST_SLOT_CONSTANT | DST_SLOT_REF | DST_SLOT_NAMED)) return;
|
||||
if (s.envindex > 0) return;
|
||||
if (s.envindex >= 0) return;
|
||||
dstc_sfreei(c, s.index);
|
||||
}
|
||||
|
||||
@ -208,7 +208,7 @@ void dstc_popscope(DstCompiler *c) {
|
||||
/* Leave a scope but keep a slot allocated. */
|
||||
void dstc_popscope_keepslot(DstCompiler *c, DstSlot retslot) {
|
||||
dstc_popscope(c);
|
||||
if (retslot.envindex == 0 && retslot.index >= 0) {
|
||||
if (retslot.envindex < 0 && retslot.index >= 0) {
|
||||
slotalloci(c, retslot.index);
|
||||
}
|
||||
}
|
||||
@ -219,7 +219,7 @@ DstSlot dstc_cslot(Dst x) {
|
||||
ret.flags = (1 << dst_type(x)) | DST_SLOT_CONSTANT;
|
||||
ret.index = -1;
|
||||
ret.constant = x;
|
||||
ret.envindex = 0;
|
||||
ret.envindex = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -285,7 +285,7 @@ DstSlot dstc_resolve(
|
||||
|
||||
/* Unused references and locals shouldn't add captured envs. */
|
||||
if (unused || foundlocal) {
|
||||
ret.envindex = 0;
|
||||
ret.envindex = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -294,18 +294,17 @@ DstSlot dstc_resolve(
|
||||
while (scope >= c->scopes && !(scope->flags & DST_SCOPE_FUNCTION)) scope--;
|
||||
dst_assert(scope >= c->scopes, "invalid scopes");
|
||||
scope->flags |= DST_SCOPE_ENV;
|
||||
if (!dst_v_count(scope->envs)) dst_v_push(scope->envs, 0);
|
||||
scope++;
|
||||
|
||||
/* Propogate env up to current scope */
|
||||
int32_t envindex = 0;
|
||||
int32_t envindex = -1;
|
||||
while (scope <= top) {
|
||||
if (scope->flags & DST_SCOPE_FUNCTION) {
|
||||
int32_t j, len;
|
||||
int scopefound = 0;
|
||||
/* Check if scope already has env. If so, break */
|
||||
len = dst_v_count(scope->envs);
|
||||
for (j = 1; j < len; j++) {
|
||||
for (j = 0; j < len; j++) {
|
||||
if (scope->envs[j] == envindex) {
|
||||
scopefound = 1;
|
||||
envindex = j;
|
||||
@ -314,7 +313,6 @@ DstSlot dstc_resolve(
|
||||
}
|
||||
/* Add the environment if it is not already referenced */
|
||||
if (!scopefound) {
|
||||
if (!dst_v_count(scope->envs)) dst_v_push(scope->envs, 0);
|
||||
len = dst_v_count(scope->envs);
|
||||
dst_v_push(scope->envs, envindex);
|
||||
envindex = len;
|
||||
@ -418,7 +416,7 @@ int32_t dstc_preread(
|
||||
(ret << 8) |
|
||||
DOP_GET_INDEX);
|
||||
}
|
||||
} else if (s.envindex > 0 || s.index > max) {
|
||||
} else if (s.envindex >= 0 || s.index > max) {
|
||||
ret = dstc_lslotn(c, max, nth);
|
||||
dstc_emit(c, ast,
|
||||
((uint32_t)(s.index) << 24) |
|
||||
@ -440,7 +438,7 @@ int32_t dstc_preread(
|
||||
|
||||
/* Call this to release a read handle after emitting the instruction. */
|
||||
void dstc_postread(DstCompiler *c, DstSlot s, int32_t index) {
|
||||
if (index != s.index || s.envindex > 0 || s.flags & DST_SLOT_CONSTANT) {
|
||||
if (index != s.index || s.envindex >= 0 || s.flags & DST_SLOT_CONSTANT) {
|
||||
/* We need to free the temporary slot */
|
||||
dstc_sfreei(c, index);
|
||||
}
|
||||
@ -495,7 +493,7 @@ void dstc_copy(
|
||||
/* far index */
|
||||
|
||||
/* If dest is a near index, do some optimization */
|
||||
if (dest.envindex == 0 && dest.index >= 0 && dest.index <= 0xFF) {
|
||||
if (dest.envindex < 0 && dest.index >= 0 && dest.index <= 0xFF) {
|
||||
if (src.flags & DST_SLOT_CONSTANT) {
|
||||
dstc_loadconst(c, ast, src.constant, dest.index);
|
||||
} else if (src.flags & DST_SLOT_REF) {
|
||||
@ -504,7 +502,7 @@ void dstc_copy(
|
||||
(dest.index << 16) |
|
||||
(dest.index << 8) |
|
||||
DOP_GET_INDEX);
|
||||
} else if (src.envindex > 0) {
|
||||
} else if (src.envindex >= 0) {
|
||||
dstc_emit(c, ast,
|
||||
(src.index << 24) |
|
||||
(src.envindex << 16) |
|
||||
@ -533,7 +531,7 @@ void dstc_copy(
|
||||
(dstc_const(c, ast, dest.constant) << 16) |
|
||||
(reflocal << 8) |
|
||||
DOP_LOAD_CONSTANT);
|
||||
} else if (dest.envindex > 0) {
|
||||
} else if (dest.envindex >= 0) {
|
||||
writeback = 2;
|
||||
destlocal = srclocal;
|
||||
} else if (dest.index > 0xFF) {
|
||||
@ -597,11 +595,11 @@ DstSlot dstc_return(DstCompiler *c, DstAst *ast, DstSlot s) {
|
||||
DstSlot dstc_gettarget(DstFopts opts) {
|
||||
DstSlot slot;
|
||||
if ((opts.flags & DST_FOPTS_HINT) &&
|
||||
(opts.hint.envindex == 0) &&
|
||||
(opts.hint.envindex < 0) &&
|
||||
(opts.hint.index >= 0 && opts.hint.index <= 0xFF)) {
|
||||
slot = opts.hint;
|
||||
} else {
|
||||
slot.envindex = 0;
|
||||
slot.envindex = -1;
|
||||
slot.constant = dst_wrap_nil();
|
||||
slot.flags = 0;
|
||||
slot.index = dstc_lslotn(opts.compiler, 0xFF, 4);
|
||||
@ -883,7 +881,7 @@ DstFuncDef *dstc_pop_funcdef(DstCompiler *c) {
|
||||
|
||||
/* Copy envs */
|
||||
def->environments_length = dst_v_count(scope.envs);
|
||||
if (def->environments_length > 1) def->environments = dst_v_flatten(scope.envs);
|
||||
def->environments = dst_v_flatten(scope.envs);
|
||||
|
||||
def->constants_length = dst_v_count(scope.consts);
|
||||
def->constants = dst_v_flatten(scope.consts);
|
||||
@ -926,9 +924,6 @@ DstFuncDef *dstc_pop_funcdef(DstCompiler *c) {
|
||||
def->flags = 0;
|
||||
if (scope.flags & DST_SCOPE_ENV) {
|
||||
def->flags |= DST_FUNCDEF_FLAG_NEEDSENV;
|
||||
if (def->environments_length == 0) {
|
||||
def->environments_length = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pop the scope */
|
||||
@ -1001,7 +996,7 @@ int dst_compile_cfun(DstArgs args) {
|
||||
env = dst_unwrap_table(args.v[1]);
|
||||
res = dst_compile(args.v[0], env, 0);
|
||||
if (res.status == DST_COMPILE_OK) {
|
||||
DstFunction *fun = dst_function(res.funcdef, NULL);
|
||||
DstFunction *fun = dst_thunk(res.funcdef);
|
||||
return dst_return(args, dst_wrap_function(fun));
|
||||
} else {
|
||||
t = dst_table(2);
|
||||
|
@ -40,7 +40,7 @@ int dst_dobytes(DstTable *env, const uint8_t *bytes, int32_t len) {
|
||||
Dst form = dst_parser_produce(&parser);
|
||||
DstCompileResult cres = dst_compile(form, env, 0);
|
||||
if (cres.status == DST_COMPILE_OK) {
|
||||
DstFunction *f = dst_function(cres.funcdef, NULL);
|
||||
DstFunction *f = dst_thunk(cres.funcdef);
|
||||
Dst ret;
|
||||
if (dst_run(dst_wrap_function(f), &ret)) {
|
||||
printf("internal runtime error: %s\n", (const char *) dst_to_string(ret));
|
||||
|
@ -90,7 +90,7 @@ static void destructure(DstCompiler *c, Dst left, DstSlot right,
|
||||
dstc_postread(c, islot, locali);
|
||||
}
|
||||
newright.index = localsub;
|
||||
newright.envindex = 0;
|
||||
newright.envindex = -1;
|
||||
newright.constant = dst_wrap_nil();
|
||||
newright.flags = DST_SLOTTYPE_ANY;
|
||||
/* Traverse into the structure */
|
||||
@ -120,7 +120,7 @@ static void destructure(DstCompiler *c, Dst left, DstSlot right,
|
||||
DOP_GET);
|
||||
dstc_postread(c, kslot, localk);
|
||||
newright.index = localsub;
|
||||
newright.envindex = 0;
|
||||
newright.envindex = -1;
|
||||
newright.constant = dst_wrap_nil();
|
||||
newright.flags = DST_SLOTTYPE_ANY;
|
||||
/* Traverse into the structure */
|
||||
@ -197,7 +197,7 @@ static DstSlot dohead(DstCompiler *c, DstFopts opts, DstAst *ast, Dst *head, int
|
||||
static DstSlot namelocal(DstCompiler *c, DstAst *ast, Dst head, int32_t flags, DstSlot ret) {
|
||||
/* Non root scope, bring to local slot */
|
||||
if (ret.flags & DST_SLOT_NAMED ||
|
||||
ret.envindex != 0 ||
|
||||
ret.envindex >= 0 ||
|
||||
ret.index < 0 ||
|
||||
ret.index > 0xFF) {
|
||||
/* Slot is not able to be named */
|
||||
@ -205,7 +205,7 @@ static DstSlot namelocal(DstCompiler *c, DstAst *ast, Dst head, int32_t flags, D
|
||||
localslot.index = dstc_lsloti(c);
|
||||
/* infer type? */
|
||||
localslot.flags = flags;
|
||||
localslot.envindex = 0;
|
||||
localslot.envindex = -1;
|
||||
localslot.constant = dst_wrap_nil();
|
||||
dstc_copy(c, ast, localslot, ret);
|
||||
ret = localslot;
|
||||
@ -546,7 +546,7 @@ DstSlot dstc_fn(DstFopts opts, DstAst *ast, int32_t argn, const Dst *argv) {
|
||||
continue;
|
||||
}
|
||||
slot.flags = DST_SLOT_NAMED;
|
||||
slot.envindex = 0;
|
||||
slot.envindex = -1;
|
||||
slot.constant = dst_wrap_nil();
|
||||
slot.index = dstc_lsloti(c);
|
||||
dstc_nameslot(c, dst_unwrap_symbol(param), slot);
|
||||
@ -564,7 +564,7 @@ DstSlot dstc_fn(DstFopts opts, DstAst *ast, int32_t argn, const Dst *argv) {
|
||||
/* Check for self ref */
|
||||
if (selfref) {
|
||||
DstSlot slot;
|
||||
slot.envindex = 0;
|
||||
slot.envindex = -1;
|
||||
slot.flags = DST_SLOT_NAMED | DST_FUNCTION;
|
||||
slot.constant = dst_wrap_nil();
|
||||
slot.index = dstc_lsloti(c);
|
||||
|
@ -221,26 +221,11 @@ DstFuncDef *dst_funcdef_alloc() {
|
||||
return def;
|
||||
}
|
||||
|
||||
/* Create a closure from a funcdef and a parent function */
|
||||
DstFunction *dst_function(DstFuncDef *def, DstFunction *parent) {
|
||||
int32_t i;
|
||||
/* Create a simple closure from a funcdef */
|
||||
DstFunction *dst_thunk(DstFuncDef *def) {
|
||||
DstFunction *func = dst_gcalloc(DST_MEMORY_FUNCTION, sizeof(DstFunction));
|
||||
int32_t elen = def->environments_length;
|
||||
func->def = def;
|
||||
if (elen) {
|
||||
func->envs = malloc(sizeof(DstFuncEnv *) * elen);
|
||||
if (elen > 1 && !parent) return NULL;
|
||||
if (NULL == func->envs) {
|
||||
DST_OUT_OF_MEMORY;
|
||||
}
|
||||
func->envs[0] = NULL;
|
||||
} else {
|
||||
func->envs = NULL;
|
||||
}
|
||||
for (i = 1; i < def->environments_length; ++i) {
|
||||
int32_t inherit = def->environments[i];
|
||||
func->envs[i] = parent->envs[inherit];
|
||||
}
|
||||
func->envs = NULL;
|
||||
return func;
|
||||
}
|
||||
|
||||
@ -256,5 +241,5 @@ DstFunction *dst_quick_asm(int32_t arity, int varargs, int32_t slots, const uint
|
||||
DST_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(def->bytecode, bytecode, bytecode_size);
|
||||
return dst_function(def, NULL);
|
||||
return dst_thunk(def);
|
||||
}
|
||||
|
@ -101,19 +101,6 @@ void dst_fiber_pushn(DstFiber *fiber, const Dst *arr, int32_t n) {
|
||||
fiber->stacktop = newtop;
|
||||
}
|
||||
|
||||
/* Help set up function */
|
||||
static void funcframe_env(DstFiber *fiber, DstFunction *func) {
|
||||
/* Check closure env */
|
||||
if (func->def->flags & DST_FUNCDEF_FLAG_NEEDSENV) {
|
||||
/* Delayed capture of current stack frame */
|
||||
DstFuncEnv *env = dst_gcalloc(DST_MEMORY_FUNCENV, sizeof(DstFuncEnv));
|
||||
env->offset = fiber->frame;
|
||||
env->as.fiber = fiber;
|
||||
env->length = func->def->slotcount;
|
||||
func->envs[0] = env;
|
||||
}
|
||||
}
|
||||
|
||||
/* Push a stack frame to a fiber */
|
||||
void dst_fiber_funcframe(DstFiber *fiber, DstFunction *func) {
|
||||
DstStackFrame *newframe;
|
||||
@ -140,6 +127,7 @@ void dst_fiber_funcframe(DstFiber *fiber, DstFunction *func) {
|
||||
newframe->prevframe = oldframe;
|
||||
newframe->pc = func->def->bytecode;
|
||||
newframe->func = func;
|
||||
newframe->env = NULL;
|
||||
|
||||
/* Check varargs */
|
||||
if (func->def->flags & DST_FUNCDEF_FLAG_VARARG) {
|
||||
@ -152,17 +140,13 @@ void dst_fiber_funcframe(DstFiber *fiber, DstFunction *func) {
|
||||
oldtop - tuplehead));
|
||||
}
|
||||
}
|
||||
|
||||
/* Check env */
|
||||
funcframe_env(fiber, func) ;
|
||||
}
|
||||
|
||||
/* If a frame has a closure environment, detach it from
|
||||
* the stack and have it keep its own values */
|
||||
static void dst_function_detach(DstFunction *func) {
|
||||
static void dst_env_detach(DstFuncEnv *env) {
|
||||
/* Check for closure environment */
|
||||
if (NULL != func->envs && NULL != func->envs[0]) {
|
||||
DstFuncEnv *env = func->envs[0];
|
||||
if (env) {
|
||||
size_t s = sizeof(Dst) * env->length;
|
||||
Dst *vmem = malloc(s);
|
||||
if (NULL == vmem) {
|
||||
@ -190,7 +174,8 @@ void dst_fiber_funcframe_tail(DstFiber *fiber, DstFunction *func) {
|
||||
|
||||
/* Detatch old function */
|
||||
if (NULL != dst_fiber_frame(fiber)->func)
|
||||
dst_function_detach(dst_fiber_frame(fiber)->func);
|
||||
dst_env_detach(dst_fiber_frame(fiber)->env);
|
||||
dst_fiber_frame(fiber)->env = NULL;
|
||||
|
||||
/* Check varargs */
|
||||
if (func->def->flags & DST_FUNCDEF_FLAG_VARARG) {
|
||||
@ -218,9 +203,6 @@ void dst_fiber_funcframe_tail(DstFiber *fiber, DstFunction *func) {
|
||||
/* Set stack stuff */
|
||||
fiber->stacktop = fiber->stackstart = nextstacktop;
|
||||
|
||||
/* Varargs and func envs */
|
||||
funcframe_env(fiber, func);
|
||||
|
||||
/* Set frame stuff */
|
||||
dst_fiber_frame(fiber)->func = func;
|
||||
dst_fiber_frame(fiber)->pc = func->def->bytecode;
|
||||
@ -257,7 +239,7 @@ void dst_fiber_popframe(DstFiber *fiber) {
|
||||
|
||||
/* Clean up the frame (detach environments) */
|
||||
if (NULL != frame->func)
|
||||
dst_function_detach(frame->func);
|
||||
dst_env_detach(frame->env);
|
||||
|
||||
/* Shrink stack */
|
||||
fiber->stacktop = fiber->stackstart = fiber->frame;
|
||||
|
@ -186,6 +186,8 @@ static void dst_mark_fiber(DstFiber *fiber) {
|
||||
frame = (DstStackFrame *)(fiber->data + i - DST_FRAME_SIZE);
|
||||
if (NULL != frame->func)
|
||||
dst_mark_function(frame->func);
|
||||
if (NULL != frame->env)
|
||||
dst_mark_funcenv(frame->env);
|
||||
/* Mark all values in the stack frame */
|
||||
dst_mark_many(fiber->data + i, j - i);
|
||||
j = i - DST_FRAME_SIZE;
|
||||
|
@ -494,32 +494,63 @@ static void *op_lookup[255] = {
|
||||
VM_OP(DOP_CLOSURE)
|
||||
{
|
||||
DstFuncDef *fd;
|
||||
DstFunction *fn;
|
||||
vm_assert((int32_t)oparg(2, 0xFFFF) < func->def->defs_length, "invalid funcdef");
|
||||
fd = func->def->defs[(int32_t)oparg(2, 0xFFFF)];
|
||||
stack[oparg(1, 0xFF)] = dst_wrap_function(dst_function(fd, func));
|
||||
fn = dst_thunk(fd);
|
||||
{
|
||||
int32_t elen = fd->environments_length;
|
||||
if (elen) {
|
||||
int32_t i;
|
||||
fn->envs = malloc(sizeof(DstFuncEnv *) * elen);
|
||||
if (NULL == fn->envs) {
|
||||
DST_OUT_OF_MEMORY;
|
||||
}
|
||||
for (i = 0; i < elen; ++i) {
|
||||
int32_t inherit = fd->environments[i];
|
||||
if (inherit == -1) {
|
||||
DstStackFrame *frame = (DstStackFrame *)stack - 1;
|
||||
if (!frame->env) {
|
||||
/* Lazy capture of current stack frame */
|
||||
DstFuncEnv *env = dst_gcalloc(DST_MEMORY_FUNCENV, sizeof(DstFuncEnv));
|
||||
env->offset = dst_vm_fiber->frame;
|
||||
env->as.fiber = dst_vm_fiber;
|
||||
env->length = func->def->slotcount;
|
||||
frame->env = env;
|
||||
}
|
||||
fn->envs[i] = frame->env;
|
||||
} else {
|
||||
fn->envs[i] = func->envs[inherit];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fn->envs = NULL;
|
||||
}
|
||||
}
|
||||
stack[oparg(1, 0xFF)] = dst_wrap_function(fn);
|
||||
pc++;
|
||||
vm_checkgc_next();
|
||||
}
|
||||
|
||||
VM_OP(DOP_PUSH)
|
||||
dst_fiber_push(dst_vm_fiber, stack[oparg(1, 0xFFFFFF)]);
|
||||
pc++;
|
||||
stack = dst_vm_fiber->data + dst_vm_fiber->frame;
|
||||
vm_checkgc_next();
|
||||
dst_fiber_push(dst_vm_fiber, stack[oparg(1, 0xFFFFFF)]);
|
||||
pc++;
|
||||
stack = dst_vm_fiber->data + dst_vm_fiber->frame;
|
||||
vm_checkgc_next();
|
||||
|
||||
VM_OP(DOP_PUSH_2)
|
||||
dst_fiber_push2(dst_vm_fiber,
|
||||
stack[oparg(1, 0xFF)],
|
||||
stack[oparg(2, 0xFFFF)]);
|
||||
dst_fiber_push2(dst_vm_fiber,
|
||||
stack[oparg(1, 0xFF)],
|
||||
stack[oparg(2, 0xFFFF)]);
|
||||
pc++;
|
||||
stack = dst_vm_fiber->data + dst_vm_fiber->frame;
|
||||
vm_checkgc_next();
|
||||
|
||||
VM_OP(DOP_PUSH_3)
|
||||
dst_fiber_push3(dst_vm_fiber,
|
||||
stack[oparg(1, 0xFF)],
|
||||
stack[oparg(2, 0xFF)],
|
||||
stack[oparg(3, 0xFF)]);
|
||||
dst_fiber_push3(dst_vm_fiber,
|
||||
stack[oparg(1, 0xFF)],
|
||||
stack[oparg(2, 0xFF)],
|
||||
stack[oparg(3, 0xFF)]);
|
||||
pc++;
|
||||
stack = dst_vm_fiber->data + dst_vm_fiber->frame;
|
||||
vm_checkgc_next();
|
||||
@ -743,10 +774,10 @@ static void *op_lookup[255] = {
|
||||
/* Run the vm with a given function. This function is
|
||||
* called to start the vm. */
|
||||
int dst_run(Dst callee, Dst *returnreg) {
|
||||
if (NULL == dst_vm_fiber) {
|
||||
dst_vm_fiber = dst_fiber(0);
|
||||
if (dst_vm_fiber) {
|
||||
dst_fiber_reset(dst_vm_fiber);
|
||||
} else {
|
||||
dst_fiber_reset(dst_vm_fiber);
|
||||
dst_vm_fiber = dst_fiber(64);
|
||||
}
|
||||
if (dst_checktype(callee, DST_CFUNCTION)) {
|
||||
DstArgs args;
|
||||
@ -772,7 +803,7 @@ int dst_call(Dst callee, Dst *returnreg, int32_t argn, const Dst *argv) {
|
||||
int lock;
|
||||
DstFiber *oldfiber = dst_vm_fiber;
|
||||
lock = dst_vm_gc_suspend++;
|
||||
dst_vm_fiber = dst_fiber(0);
|
||||
dst_vm_fiber = dst_fiber(64);
|
||||
dst_fiber_pushn(dst_vm_fiber, argv, argn);
|
||||
if (dst_checktype(callee, DST_CFUNCTION)) {
|
||||
DstArgs args;
|
||||
|
@ -172,7 +172,7 @@ int dst_gcunrootall(Dst root);
|
||||
|
||||
/* Functions */
|
||||
DstFuncDef *dst_funcdef_alloc(void);
|
||||
DstFunction *dst_function(DstFuncDef *def, DstFunction *parent);
|
||||
DstFunction *dst_thunk(DstFuncDef *def);
|
||||
int dst_verify(DstFuncDef *def);
|
||||
DstFunction *dst_quick_asm(int32_t arity, int varargs, int32_t slots, const uint32_t *bytecode, size_t bytecode_size);
|
||||
|
||||
|
@ -328,6 +328,7 @@ struct DstStackFrame {
|
||||
DstFunction *func;
|
||||
uint32_t *pc;
|
||||
int32_t prevframe;
|
||||
DstFuncEnv *env;
|
||||
};
|
||||
|
||||
/* Number of Dsts a frame takes up in the stack */
|
||||
|
Loading…
Reference in New Issue
Block a user