@@ -2042,6 +2042,10 @@ Push a new backtracking mark onto $1 with label $2, position $3, and count $4
2042
2042
2043
2043
Set $1 to be the index of latest mark frame $3 in stack $2.
2044
2044
2045
+ =item nqp_rxcommit(stack, label)
2046
+
2047
+ Commit all captures and backtracking on stack $1 up to mark frame $2.
2048
+
2045
2049
=cut
2046
2050
2047
2051
*/
@@ -2073,10 +2077,26 @@ inline op nqp_rxcommit(in PMC, in LABEL) :base_core {
2073
2077
PMC *bstack = $1;
2074
2078
INTVAL mark = PTR2INTVAL(CUR_OPCODE + $2);
2075
2079
INTVAL ptr = VTABLE_elements(interp, bstack);
2080
+ INTVAL caps = (ptr > 0)
2081
+ ? VTABLE_get_integer_keyed_int(interp, bstack, ptr-1)
2082
+ : 0;
2076
2083
while (ptr >= 0 && VTABLE_get_integer_keyed_int(interp, bstack, ptr) != mark) {
2077
2084
ptr -= 4;
2078
2085
}
2079
2086
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
+ }
2080
2100
}
2081
2101
2082
2102
0 commit comments