Skip to content

Commit 215243f

Browse files
committed
Update nqp_rxcommit to preserve captures at point of commit.
1 parent 485d4f2 commit 215243f

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

src/ops/nqp.ops

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,6 +2042,10 @@ Push a new backtracking mark onto $1 with label $2, position $3, and count $4
20422042

20432043
Set $1 to be the index of latest mark frame $3 in stack $2.
20442044

2045+
=item nqp_rxcommit(stack, label)
2046+
2047+
Commit all captures and backtracking on stack $1 up to mark frame $2.
2048+
20452049
=cut
20462050

20472051
*/
@@ -2073,10 +2077,26 @@ inline op nqp_rxcommit(in PMC, in LABEL) :base_core {
20732077
PMC *bstack = $1;
20742078
INTVAL mark = PTR2INTVAL(CUR_OPCODE + $2);
20752079
INTVAL ptr = VTABLE_elements(interp, bstack);
2080+
INTVAL caps = (ptr > 0)
2081+
? VTABLE_get_integer_keyed_int(interp, bstack, ptr-1)
2082+
: 0;
20762083
while (ptr >= 0 && VTABLE_get_integer_keyed_int(interp, bstack, ptr) != mark) {
20772084
ptr -= 4;
20782085
}
20792086
VTABLE_set_integer_native(interp, bstack, ptr);
2087+
if (caps > 0) {
2088+
if (ptr > 0 && VTABLE_get_integer_keyed_int(interp, bstack, ptr-3) < 0) {
2089+
/* top mark frame is an autofail frame, reuse it to hold captures */
2090+
VTABLE_set_integer_keyed_int(interp, bstack, ptr-1, caps);
2091+
}
2092+
else {
2093+
/* push a new autofail frame onto bstack to hold the captures */
2094+
VTABLE_push_integer(interp, bstack, 0);
2095+
VTABLE_push_integer(interp, bstack, -1);
2096+
VTABLE_push_integer(interp, bstack, 0);
2097+
VTABLE_push_integer(interp, bstack, caps);
2098+
}
2099+
}
20802100
}
20812101

20822102

0 commit comments

Comments
 (0)