mirror of
https://github.com/janet-lang/janet
synced 2026-11-02 03:34:27 +00:00
Raise a compile error on too many closures.
Previously, we had silent miscompiles in some cases. The ideal fix is to let us reference upvalues beyond slot 255. One way would be to add a new instruction pair that would reference a 16-bit constant index, which would itself encode a pair of at least 16 bit values instead of the current instruction which encodes a pair of 8 bit values.
This commit is contained in:
3 files changed
+20
No files matched your search
@@ -414,6 +414,11 @@ found:
|
||||
ret.envindex = -1;
|
||||
return ret;
|
||||
}
|
||||
if (ret.index > 0xFF) {
|
||||
janetc_error(c, janet_formatc("too many closure upvalues: %S", sym));
|
||||
ret.envindex = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* non-local scope needs to expose its environment */
|
||||
JanetScope *original_scope = scope;
|
||||
|
||||
@@ -125,6 +125,10 @@ static void janetc_movenear(JanetCompiler *c,
|
||||
JOP_GET_INDEX);
|
||||
}
|
||||
} else if (src.envindex >= 0) {
|
||||
/* Convert src to near reg */
|
||||
if (src.index > 255) {
|
||||
janet_assert(0, "upvalue index > 255, cannot load");
|
||||
}
|
||||
janetc_emit(c,
|
||||
((uint32_t)(src.index) << 24) |
|
||||
((uint32_t)(src.envindex) << 16) |
|
||||
@@ -158,6 +162,9 @@ static void janetc_moveback(JanetCompiler *c,
|
||||
janetc_emit(c, JOP_MOVE_NEAR | ((uint32_t)(src) << 16) | ((uint32_t) newsrc << 8));
|
||||
src = newsrc;
|
||||
}
|
||||
if (dest.index > 255) {
|
||||
janet_assert(0, "upvalue index > 255, cannot store");
|
||||
}
|
||||
janetc_emit(c,
|
||||
((uint32_t)(dest.index) << 24) |
|
||||
((uint32_t)(dest.envindex) << 16) |
|
||||
|
||||
@@ -963,6 +963,10 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
|
||||
JanetFuncDef *def = janetc_pop_funcdef(c, janet_cstring("while"));
|
||||
janet_def_addflags(def);
|
||||
int32_t defindex = janetc_addfuncdef(c, def);
|
||||
if (defindex > 255) {
|
||||
janetc_error(c, janet_cstring("too many closures"));
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
}
|
||||
/* Do basic optimization */
|
||||
if (!(c->scope->flags & JANET_SCOPE_UNUSED)) {
|
||||
janet_bytecode_optimize(def, c->optimize);
|
||||
@@ -1212,6 +1216,10 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) {
|
||||
|
||||
janet_def_addflags(def);
|
||||
defindex = janetc_addfuncdef(c, def);
|
||||
if (defindex > 255) {
|
||||
errmsg = "too many closures";
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Ensure enough slots for vararg function. */
|
||||
if (arity + vararg > def->slotcount) def->slotcount = arity + vararg;
|
||||
|
||||
Reference in new issue
Block a user