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