@@ -1328,6 +1328,18 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
13281328 mrb_gc_arena_restore (mrb , ai );
13291329 if (mrb -> exc ) goto L_RAISE ;
13301330 ci = mrb -> c -> ci ;
1331+ if (GET_OPCODE (i ) == OP_SENDB ) {
1332+ mrb_value blk ;
1333+
1334+ blk = ci -> stackent [bidx ];
1335+ if (mrb_type (blk ) == MRB_TT_PROC ) {
1336+ struct RProc * p = mrb_proc_ptr (blk );
1337+
1338+ if (p && p -> env == ci [-1 ].env ) {
1339+ p -> flags |= MRB_PROC_ORPHAN ;
1340+ }
1341+ }
1342+ }
13311343 if (!ci -> target_class ) { /* return from context modifying method (resume/yield) */
13321344 if (ci -> acc == CI_ACC_RESUMED ) {
13331345 mrb -> jmp = prev_jmp ;
@@ -1748,8 +1760,29 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
17481760 /* fall through */
17491761 CASE (OP_RETURN ) {
17501762 /* A B return R(A) (B=normal,in-block return/break) */
1763+ mrb_callinfo * ci ;
1764+
1765+ ci = mrb -> c -> ci ;
1766+ if (ci -> mid ) {
1767+ mrb_value blk ;
1768+
1769+ if (ci -> argc < 0 ) {
1770+ blk = regs [2 ];
1771+ }
1772+ else {
1773+ blk = regs [ci -> argc + 1 ];
1774+ }
1775+ if (mrb_type (blk ) == MRB_TT_PROC ) {
1776+ struct RProc * p = mrb_proc_ptr (blk );
1777+
1778+ if (ci > mrb -> c -> cibase && p -> env == ci [-1 ].env ) {
1779+ p -> flags |= MRB_PROC_ORPHAN ;
1780+ }
1781+ }
1782+ }
1783+
17511784 if (mrb -> exc ) {
1752- mrb_callinfo * ci , * ci0 ;
1785+ mrb_callinfo * ci0 ;
17531786 mrb_value * stk ;
17541787
17551788 L_RAISE :
@@ -1805,7 +1838,6 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
18051838 pc = mrb -> c -> rescue [-- mrb -> c -> ridx ];
18061839 }
18071840 else {
1808- mrb_callinfo * ci = mrb -> c -> ci ;
18091841 int acc ;
18101842 mrb_value v = regs [GETARG_A (i )];
18111843
@@ -1864,7 +1896,7 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
18641896 break ;
18651897 case OP_R_BREAK :
18661898 if (MRB_PROC_STRICT_P (proc )) goto NORMAL_RETURN ;
1867- if (! proc -> env || ! MRB_ENV_STACK_SHARED_P (proc -> env )) {
1899+ if (MRB_PROC_ORPHAN_P (proc )) {
18681900 mrb_value exc ;
18691901
18701902 L_BREAK_ERROR :
@@ -1873,6 +1905,9 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
18731905 mrb_exc_set (mrb , exc );
18741906 goto L_RAISE ;
18751907 }
1908+ if (!proc -> env || !MRB_ENV_STACK_SHARED_P (proc -> env )) {
1909+ goto L_BREAK_ERROR ;
1910+ }
18761911 /* break from fiber block */
18771912 if (mrb -> c -> ci == mrb -> c -> cibase && mrb -> c -> ci -> pc ) {
18781913 struct mrb_context * c = mrb -> c ;
0 commit comments