diff --git a/src/core/compile.c b/src/core/compile.c index fc668d4e..c11ec6da 100644 --- a/src/core/compile.c +++ b/src/core/compile.c @@ -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; diff --git a/src/core/emit.c b/src/core/emit.c index 32e20fc9..e4e76d49 100644 --- a/src/core/emit.c +++ b/src/core/emit.c @@ -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) | diff --git a/src/core/specials.c b/src/core/specials.c index 8798b7fe..25da14f3 100644 --- a/src/core/specials.c +++ b/src/core/specials.c @@ -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;