Here are my preliminary findings about this problem.
I used the following evaluation for my debugging:

$ ./perl6-j -e 'say (so 1).perl'
1

The optimizer generates a QAST::Want with two children
(output generated with RAKUDO_OPTIMIZER_DEBUG=1):

[...]
- QAST::Op(callstatic &say) <sunk> :statement_id<?> say (so 1).perl
  - QAST::Op(hllize) <wanted>
    - QAST::Op(callmethod perl) <> perl
      - QAST::Want <>
        - QAST::WVal(Bool) <>
        - Ii
        - QAST::IVal(1) <>

I tried the following patch (skipping the creation of that
QAST::Want if $ret_value is an instance of a Bool) and all 
the tests mentioned in my original post passed afterward:

====
diff --git a/src/Perl6/Optimizer.nqp b/src/Perl6/Optimizer.nqp
index 12398ba..dcdd55b 100644
--- a/src/Perl6/Optimizer.nqp
+++ b/src/Perl6/Optimizer.nqp
@@ -1435,7 +1435,7 @@ class Perl6::Optimizer {
                         my $want;
                         if !nqp::isconcrete($ret_value) {
 # can we create a Want with a type object???  XXX
-                        } elsif nqp::istype($ret_value, 
$!symbols.find_in_setting("Int")) && !nqp::isbig_I(nqp::decont($ret_value)) {
+                        } elsif nqp::istype($ret_value, 
$!symbols.find_in_setting("Int")) && !nqp::istype($ret_value, 
$!symbols.find_in_setting("Bool")) && !nqp::isbig_I(nqp::decont($ret_value)) {
                             $want := QAST::Want.new($wval,
                                 "Ii", 
QAST::IVal.new(:value(nqp::unbox_i($ret_value))));
                         } elsif nqp::istype($ret_value, 
$!symbols.find_in_setting("Num")) {
====

With that patch the evaluation gave:

$ ./perl6-j -e 'say (so 1).perl'
Bool::True

The generated QAST from the optimizer didn't had the Want
anymore (as expected):

[...]
- QAST::Op(callstatic &say) <sunk> :statement_id<?> say (so 1).perl
  - QAST::Op(hllize) <wanted>
    - QAST::Op(callmethod perl) <> perl
      - QAST::WVal(Bool) <>

In src/Perl6/Optimizer.nqp there is an comment that made me think
that those QAST::Want were only meant for instances of Int, Num
or Str: 
https://github.com/rakudo/rakudo/blob/nom/src/Perl6/Optimizer.nqp#L1433-L1434

We also generate those QAST::Want for Bool or Mixins like here:

$ ./perl6-j -e 'my $value = 42 but False; say ?$value'
True

[...]
- QAST::Want <>
  - QAST::WVal(Int+{<anon|1285927979>}) <>
  - Ii
  - QAST::IVal(42) <>

I asked about my patch on #perl6-dev. There was no clear result,
but the tenor of the discussion was, that the JVM backend should
be able to interprete those QAST::Want correctly.

==== start of discussion on IRC -- cmp. 
http://irclog.perlgeek.de/perl6-dev/2016-10-02#i_13323463
bartolin    could someone take a look at 
https://github.com/usev6/rakudo/commit/a547db7ebe ? It's an attempt to fix RT 
#129782 but I'm not sure if there is indeed a (kind of) bug in the optimizer or 
if the fix has to happen in the JVM specific code.
synopsebot6 Link:  https://rt.perl.org/rt3//Public/Bug/Display.html?id=129782
MasterDuke  bartolin: purely nitpicking, but if you put the added conditional 
at the end, the diff would be a little easier to read
MasterDuke  (not that one line is all that difficult...)
bartolin    MasterDuke: thanks, noted. I wondered where the additional check 
should be placed wrt performance, since the order could make a difference 
performance wise, couldn't it? But, I've no idea how hot that path is
MasterDuke  yeah, i was thinking about that after i said it
MasterDuke  since i would definitely prioritize almost any performance 
difference over the minor change in readability of a one-line commit
* bartolin  nods
psch        r: sub f(--> Bool) { so 1 }; say f().WHAT
camelia     rakudo-jvm 2a1605, rakudo-moar 4abc28: OUTPUT«(Bool)␤»
psch        r: sub f() { so 1 }; say f().WHAT
camelia     rakudo-jvm 2a1605, rakudo-moar 4abc28: OUTPUT«(Bool)␤»
psch        r: sub f() { so 1 }; say f().perl
camelia     rakudo-jvm 2a1605, rakudo-moar 4abc28: OUTPUT«Bool::True␤»
psch        r: say (so 1).perl
camelia     rakudo-jvm 2a1605: OUTPUT«1␤»
camelia     ..rakudo-moar 4abc28: OUTPUT«Bool::True␤»
psch        that is honestly weird
psch        bartolin: i'm inclined to think that the QAST::Want behavior is the 
actual problem though
psch        r: sub f { sub { say 1 } }; f()() # i am somehow reminded of this
camelia     rakudo-moar 4abc28: OUTPUT«1␤»
camelia     ..rakudo-jvm 2a1605: ( no output )
psch        aw don't be shy camelia, show the NPE :P
psch        r: sub f { sub { say 1 } }; f()() # i
camelia     rakudo-moar 4abc28: OUTPUT«1␤»
camelia     ..rakudo-jvm 2a1605: OUTPUT«java.lang.NullPointerException␤  in 
block <unit> at <tmp> line 1␤␤»
bartolin    psch: so, you would say it makes sense to have a QAST::Want with a 
QAST::WVal for the 'True' and a QAST::IVal for the '1'?
bartolin    psch: ... and the interpretation of that QAST::Want on JVM is wrong?
psch        bartolin: well, moar inlines it to Want <> with WVal(Bool) and 
IVal(1) as children
psch        bartolin: the &so call, that is
bartolin    psch: oh, your last evaluation does not give a NPE with 
--optimize=off -- I didn't know that
bartolin    psch: yeah, the QAST is the same on JVM (if I'm not mistaken)
psch        bartolin: and considering the post-optimize QAST looks the same 
across the backends but doesn't give the same result... well there's probably 
something wrong in the wrong backend :)
psch        bartolin: i'd guess it's probably something with how we have to do 
returns out of band on jvm and sometimes don't carry the right $*WANT around or 
so
psch        bartolin: but honestly those bits of the QAST -> JAST Compiler 
aren't particularly transparent to me :)
bartolin    psch: from the comments 
(https://github.com/rakudo/rakudo/blob/nom/src/Perl6/Optimizer.nqp#L1433) I got 
the impression that those QAST::Want are really only meant for Int, Num and Str 
(in order to add a native variant) -- and not for Bool
bartolin    timotimo: maybe you can shed some light? (wrt 
https://github.com/usev6/rakudo/commit/a547db7ebe)
timotimo    whoops, that want is totally broken :)
timotimo    it should have the Ii and the IVal at the same level as the 
WVal(Bool)
bartolin    timotimo: sorry, that was my fault
timotimo    oh, phew
bartolin    fixed
timotimo    your patch may be right
bartolin    r: my $value = 42 but False; say ?$value
camelia     rakudo-jvm 2a1605: OUTPUT«True␤»
camelia     ..rakudo-moar 28c23a: OUTPUT«False␤»
timotimo    o_O
bartolin    r-j gives False with --optimize=off here
timotimo    ugh ;(
bartolin    I guess it's the same problem (according to the output generated 
with RAKUDO_OPTIMIZER_DEBUG=1)
timotimo    might be, yeah :\
bartolin    so, if my patch makes sense, it is not complete
psch        bartolin: well, Bool is Int on one hand
psch        bartolin: and on the other, there's demonstrably other cases where 
the optimizer produces something related to Wants that works on moar and 
doesn't on jvm
psch        bartolin: so i think the optimizer isn't to blame
bartolin    psch: yeah. but do we really need the Want there? I mean, both the 
optimizer and the JVM backend could be wrong :-)
psch        m: sub f(int $) { say "yup" }; f Bool
camelia     rakudo-moar 28c23a: OUTPUT«Cannot unbox a type object␤  in sub f at 
<tmp> line 1␤  in block <unit> at <tmp> line 1␤␤»
psch        m: sub f(int $) { say "yup" }; f True
camelia     rakudo-moar 28c23a: OUTPUT«yup␤»
psch        j: sub f(int $) { say "yup" }; f True
camelia     rakudo-jvm 2a1605: OUTPUT«yup␤»
psch        bartolin: afaiu the Want means "here's the native value in case you 
need it", and an IVal makes perfect sense for in the case of Bool
bartolin    psch: ok, at least I understood the meaning of the Want, then :-)
timotimo    well, something is mishandling that case, though
psch        yeah, the Want handling in JAST::Compiler, probably :S
psch        but that seems to be complicated stuff and i don't get it
timotimo    right, the jast compiler isn't easy
bartolin    ok, so I won't open a PR then, but will add the discussion to the 
ticket
==== end of discussion on IRC -- powered by 
https://github.com/usev6/dump-irc-logs

Reply via email to