mirror of
https://github.com/janet-lang/janet
synced 2025-02-04 11:19:10 +00:00
Address #1326 in a dynamic way that is fairly conservative.
Another optimization would be to keep track of immutable closure captures (vs. mutable closure captures) and always detach them.
This commit is contained in:
parent
56f33f514b
commit
9593c930de
@ -185,6 +185,19 @@ static void marshal_one_env(MarshalState *st, JanetFuncEnv *env, int flags);
|
|||||||
/* Prevent stack overflows */
|
/* Prevent stack overflows */
|
||||||
#define MARSH_STACKCHECK if ((flags & 0xFFFF) > JANET_RECURSION_GUARD) janet_panic("stack overflow")
|
#define MARSH_STACKCHECK if ((flags & 0xFFFF) > JANET_RECURSION_GUARD) janet_panic("stack overflow")
|
||||||
|
|
||||||
|
/* Quick check if a fiber cannot be marshalled. This is will
|
||||||
|
* have no false positives, but may have false negatives. */
|
||||||
|
static int fiber_cannot_be_marshalled(JanetFiber *fiber) {
|
||||||
|
if (janet_fiber_status(fiber) == JANET_STATUS_ALIVE) return 1;
|
||||||
|
int32_t i = fiber->frame;
|
||||||
|
while (i > 0) {
|
||||||
|
JanetStackFrame *frame = (JanetStackFrame *)(fiber->data + i - JANET_FRAME_SIZE);
|
||||||
|
if (!frame->func) return 1; /* has cfunction on stack */
|
||||||
|
i = frame->prevframe;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Marshal a function env */
|
/* Marshal a function env */
|
||||||
static void marshal_one_env(MarshalState *st, JanetFuncEnv *env, int flags) {
|
static void marshal_one_env(MarshalState *st, JanetFuncEnv *env, int flags) {
|
||||||
MARSH_STACKCHECK;
|
MARSH_STACKCHECK;
|
||||||
@ -197,7 +210,9 @@ static void marshal_one_env(MarshalState *st, JanetFuncEnv *env, int flags) {
|
|||||||
}
|
}
|
||||||
janet_env_valid(env);
|
janet_env_valid(env);
|
||||||
janet_v_push(st->seen_envs, env);
|
janet_v_push(st->seen_envs, env);
|
||||||
if (env->offset > 0 && (JANET_STATUS_ALIVE == janet_fiber_status(env->as.fiber) || (flags & JANET_MARSHAL_UNSAFE))) {
|
|
||||||
|
/* Special case for early detachment */
|
||||||
|
if (env->offset > 0 && fiber_cannot_be_marshalled(env->as.fiber)) {
|
||||||
pushint(st, 0);
|
pushint(st, 0);
|
||||||
pushint(st, env->length);
|
pushint(st, env->length);
|
||||||
Janet *values = env->as.fiber->data + env->offset;
|
Janet *values = env->as.fiber->data + env->offset;
|
||||||
|
Loading…
Reference in New Issue
Block a user