[perl #131870] [CONC] [REGEX] Capture lookup inside regex is not threadsafe
Heh, on further thought, they may be the same issue after all. In `/(...) { ... $i ... $0 ... }`, both the $i and the $0 (or $/ rather) are outer lexicals from the point of view of the curly block, right? So it might be a general problem with the way that *code blocks inside regexes* access outer lexicals. (It doesn't happen with code blocks *outside* of regexes, and as the other ticket demonstrates, also doesn't happen inside the regex-portion of regexes.)
[perl #131870] [CONC] [REGEX] Capture lookup inside regex is not threadsafe
Also notable is that multiple iterations somehow see the same value for `$i` (as observed in the output listing above). I've sumbitted a separate issue for that (RT #131871), because the Capture-lookup bug of the current issue occurs even when removing the `$i`.
[perl #131871] [CONC] [REGEX] Regex code block closing over lexical variable, is not threadsafe
# New Ticket Created by Sam S. # Please include the string: [perl #131871] # in the subject line of all future correspondence about this issue. # https://rt.perl.org/Ticket/Display.html?id=131871 > This bug was found as a side-effect of RT #131870, but might be a separate issue: ➜ await ^10 .map: -> $i { start { "".match(/ { say $i } /) } } 7 7 6 6 7 8 9 9 9 9 Somehow, multiple iterations see the same value for the closed-over variable `$i`. Without the `await` and `start`, it prints each number from 0 to 9 exactly once, like it should. --- Note that the problem is only with *code blocks* inside regexes. When a lexical variable is interpolated into the top-level of a regex directly, things seem to work fine: ➜ say await ^10 .map: -> $i { start { "0123456789".match(/ $i /) } } (「0」 「1」 「2」 「3」 「4」 「5」 「6」 「7」 「8」 「9 --- Bot-friendly version that reliably prints `False`, even though it should print `True`: my $c = Channel.new; (await ^100 .map: -> $i { start "".match(/ { $c.send: $i } /) }); $c.close; say $c.sort.list eqv (^100).list; According to bisectable6 and committable6 this prints `False` for all past Perl 6 releases, so it's not a regression but rather an old bug.
[perl #131870] [CONC] Capture lookup inside regexes is not threadsafe
# New Ticket Created by Sam S. # Please include the string: [perl #131870] # in the subject line of all future correspondence about this issue. # https://rt.perl.org/Ticket/Display.html?id=131870 > When the same regex is used concurrently from multiple `start` threads, looking up already matched captures like $0 or $ from an embedded code block *inside* that regex is unreliable: ➜ await do for ^10 -> $i { start { "A".match: /(“A”) { say "BOOM: $i) ", $0 if not $0 }/ } } BOOM: 2) Nil BOOM: 4) Nil BOOM: 2) 「A」 BOOM: 3) 「A」 BOOM: 6) Nil That example shouldn't print anything, because `$0` should always be a truthy `Match` object after the `(“A”)`. But in practice, it demonstrates the incorrect behavior shown above on most runs: *Some* iterations (different ones each time) seem to see `$0` as `Nil` or as a falsy `Match`. Additional failure modes that occur more rarely: - "Type check failed in binding to parameter '';" error - hanging indefinitely Increase the `^10` to `^1000` or so to guarantee failure. --- Bisect finds: https://gist.github.com/c04a40f14712ce5a67dc171f87d3bcdb https://github.com/rakudo/rakudo/commit/08e39ee However: <Zoffix> It's not a regression tho <Zoffix> Or maybe it is. <Zoffix> It's just before that commit, it looks like the $/ was shared around, so it wasn't necesarily "not $0" <Zoffix> c: 08e39ee2653b1ae^ await ^100 .map: -> $i { $/ = 42; start { "$i".match: /(\d+)/; if $i != +$0 { say "Boom: $i $0" } } } <committable6> Zoffix, https://gist.github.com/557c6716c35afeee06cd90a3daf22c47 <Zoffix> Yup. --- This is Rakudo version 2017.07-136-gda4a0f50a built on MoarVM version 2017.07-318-g604da4d0 implementing Perl 6.c.