[perl #131870] [CONC] [REGEX] Capture lookup inside regex is not threadsafe

2017-08-09 Thread Sam S. via RT
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

2017-08-09 Thread Sam S. via RT
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

2017-08-09 Thread via RT
# 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

2017-08-09 Thread via RT
# 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.