vm.c (cipop): check type of the callinfo::blk; fix #5791

Since `callinfo::blk` is not marked in the GC, it may be reclaimed in
the sweep phase. When it reclaimed, it will become either (a) a non Proc
object, or (b) a Proc object that happen to have the same address.

For case (a), adding `b->tt == MRB_TT_PROC` check works. We should avoid
the following `MRB_PROC_STRICT_P()` and `MRB_PROC_ENV()` operations for
non Proc objects.

For case (b), `MRB_PROC_ENV(b) == CI_ENV(&c->ci[-1])` check should work.
Unrelated Proc objects should be filtered by the check.

We don't need to clear `callinfo::blk` by `NULL` because the callinfo
struct will be discarded afterward in the `cipop()` function.
This commit is contained in:
Yukihiro "Matz" Matsumoto
2022-09-19 08:29:23 +09:00
parent 5b62fbc0fc
commit 81f98a3925
+1 -1
View File
@@ -410,7 +410,7 @@ cipop(mrb_state *mrb)
mrb_vm_ci_env_set(c->ci, NULL); // make possible to free by GC if env is not needed
struct RProc *b = c->ci->blk;
if (b && !MRB_PROC_STRICT_P(b) && MRB_PROC_ENV(b) == CI_ENV(&c->ci[-1])) {
if (b && b->tt == MRB_TT_PROC && !MRB_PROC_STRICT_P(b) && MRB_PROC_ENV(b) == CI_ENV(&c->ci[-1])) {
b->flags |= MRB_PROC_ORPHAN;
}
if (env && !mrb_env_unshare(mrb, env, TRUE)) {