+/* --- Unwind stack -------------------------------------------------------- */
+
+typedef struct {
+ I32 cxix;
+ I32 items;
+} su_ud_unwind;
+
+STATIC void su_unwind(pTHX_ void *ud_) {
+ su_ud_unwind *ud = (su_ud_unwind *) ud_;
+ OP fakeop;
+ I32 cxix = ud->cxix;
+ I32 items = ud->items - 1;
+ I32 gimme, mark;
+
+ if (cxstack_ix > cxix)
+ dounwind(cxix);
+
+ /* Hide the level */
+ if (items >= 0)
+ PL_stack_sp--;
+
+ mark = PL_markstack[cxstack[cxix].blk_oldmarksp];
+
+ gimme = GIMME_V;
+ if (gimme == G_SCALAR) {
+ *PL_markstack_ptr = PL_stack_sp - PL_stack_base;
+ PL_stack_sp += items;
+ } else {
+ *PL_markstack_ptr = PL_stack_sp - PL_stack_base - items;
+ }
+
+ SU_D({
+ PerlIO_printf(Perl_debug_log,
+ "%p: cx=%d gimme=%s items=%d sp=%d oldmark=%d mark=%d\n",
+ ud, cxix,
+ gimme == G_VOID ? "void" : gimme == G_ARRAY ? "list" : "scalar",
+ items, PL_stack_sp - PL_stack_base, *PL_markstack_ptr, mark);
+ });
+
+ PL_op = PL_ppaddr[OP_RETURN](aTHX);
+ *PL_markstack_ptr = mark;
+
+ fakeop.op_next = PL_op;
+ PL_op = &fakeop;
+
+ Safefree(ud);
+}
+
+/* --- XS ------------------------------------------------------------------ */
+