S_regcppop(pTHX_ regexp *rex, U32 *maxopenparen_p)
{
    UV i;
    U32 paren;
    GET_RE_DEBUG_FLAGS_DECL;

    PERL_ARGS_ASSERT_REGCPPOP;

    /* Pop REGCP_OTHER_ELEMS before the parentheses loop starts. */
    i = SSPOPUV;
    assert((i & SAVE_MASK) == SAVEt_REGCONTEXT); /* Check that the magic cookie is there. */
    i >>= SAVE_TIGHT_SHIFT; /* Parentheses elements to pop. */
    rex->lastcloseparen = SSPOPINT;
    rex->lastparen = SSPOPINT;
    *maxopenparen_p = SSPOPINT;

    i -= REGCP_OTHER_ELEMS;
    /* Now restore the parentheses context. */
    DEBUG_BUFFERS_r(
	if (i || rex->lastparen + 1 <= rex->nparens)
	    PerlIO_printf(Perl_debug_log,
		"rex=0x%"UVxf" offs=0x%"UVxf": restoring capture indices to:\n",
		PTR2UV(rex),
		PTR2UV(rex->offs)
	    );
    );
    paren = *maxopenparen_p;
    for ( ; i > 0; i -= REGCP_PAREN_ELEMS) {
	SSize_t tmps;
	rex->offs[paren].start_tmp = SSPOPINT;
	rex->offs[paren].start = SSPOPIV;
	tmps = SSPOPIV;
	if (paren <= rex->lastparen)
	    rex->offs[paren].end = tmps;
	DEBUG_BUFFERS_r( PerlIO_printf(Perl_debug_log,
	    "    \\%"UVuf": %"IVdf"(%"IVdf")..%"IVdf"%s\n",
	    (UV)paren,
	    (IV)rex->offs[paren].start,
	    (IV)rex->offs[paren].start_tmp,
	    (IV)rex->offs[paren].end,
	    (paren > rex->lastparen ? "(skipped)" : ""));
	);
	paren--;
    }
#if 1
    /* It would seem that the similar code in regtry()
     * already takes care of this, and in fact it is in
     * a better location to since this code can #if 0-ed out
     * but the code in regtry() is needed or otherwise tests
     * requiring null fields (pat.t#187 and split.t#{13,14}
     * (as of patchlevel 7877)  will fail.  Then again,
     * this code seems to be necessary or otherwise
     * this erroneously leaves $1 defined: "1" =~ /^(?:(\d)x)?\d$/
     * --jhi updated by dapm */
    for (i = rex->lastparen + 1; i <= rex->nparens; i++) {
	if (i > *maxopenparen_p)
	    rex->offs[i].start = -1;
	rex->offs[i].end = -1;
	DEBUG_BUFFERS_r( PerlIO_printf(Perl_debug_log,
	    "    \\%"UVuf": %s   ..-1 undeffing\n",
	    (UV)i,
	    (i > *maxopenparen_p) ? "-1" : "  "
	));
    }
#endif
}
S_regcppop(pTHX_ regexp *rex, U32 *maxopenparen_p)
{
    UV i;
    U32 paren;
    GET_RE_DEBUG_FLAGS_DECL;

    PERL_ARGS_ASSERT_REGCPPOP;

     
    i = SSPOPUV;
    assert((i & SAVE_MASK) == SAVEt_REGCONTEXT);  
    i >>= SAVE_TIGHT_SHIFT;  
    rex->lastcloseparen = SSPOPINT;
    rex->lastparen = SSPOPINT;
    *maxopenparen_p = SSPOPINT;

    i -= REGCP_OTHER_ELEMS;
     
    DEBUG_BUFFERS_r(
	if (i || rex->lastparen + 1 <= rex->nparens)
	    PerlIO_printf(Perl_debug_log,
		"rex=0x%"UVxf" offs=0x%"UVxf": restoring capture indices to:\n",
		PTR2UV(rex),
		PTR2UV(rex->offs)
	    );
    );
    paren = *maxopenparen_p;
    for ( ; i > 0; i -= REGCP_PAREN_ELEMS) {
	SSize_t tmps;
	rex->offs[paren].start_tmp = SSPOPINT;
	rex->offs[paren].start = SSPOPIV;
	tmps = SSPOPIV;
	if (paren <= rex->lastparen)
	    rex->offs[paren].end = tmps;
	DEBUG_BUFFERS_r( PerlIO_printf(Perl_debug_log,
	    "    \\%"UVuf": %"IVdf"(%"IVdf")..%"IVdf"%s\n",
	    (UV)paren,
	    (IV)rex->offs[paren].start,
	    (IV)rex->offs[paren].start_tmp,
	    (IV)rex->offs[paren].end,
	    (paren > rex->lastparen ? "(skipped)" : ""));
	);
	paren--;
    }
#if 1
     
    for (i = rex->lastparen + 1; i <= rex->nparens; i++) {
	if (i > *maxopenparen_p)
	    rex->offs[i].start = -1;
	rex->offs[i].end = -1;
	DEBUG_BUFFERS_r( PerlIO_printf(Perl_debug_log,
	    "    \\%"UVuf": %s   ..-1 undeffing\n",
	    (UV)i,
	    (i > *maxopenparen_p) ? "-1" : "  "
	));
    }
#endif
}