New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add some concreteness/definedness checks #3130
Conversation
This makes most of S02-names/pseudo-6e.t pass on the JVM backend.
Overall, I don't see a point for this PR. Usually it's good to have safety guards, but in this case they're redundant. Unless I overlook something. |
Well, there are failures when running S02-names/pseudo-6e.t on the JVM backend (on HEAD). I'll add details below (should probably have done that before, sorry). The patches help with the mentioned problems, but I'm totally not sure if the underlying problem is somewhere else -- and my changes are just glossing over that underlying problem. In that case, I should probably open an issue (and close this PR). The first check for concreteness helps with this code:
The second added check and third added check make this code work. (The third check (for nqp::defined) avoids the NPE, the second check (for nqp::isconcrete) resolves the resulting error 'ctxlexpad requires an operand with REPR ContextRef):
|
Don't close the PR yet. But the problem requires deeper investigation. I don't use JVM backend. It could be peculiarity in it which I don't know about. Though it would be really weird as context cannot be just a type object. Anyway, in this case your patch would perhaps be necessary. More likely it's another bug in JVM popping up. Then we better don't cover it with a workaround. Another thing I would like to ask you about is to provide a test for this problem. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current status: needs more investigation on JVM backend. Likely a bug in JVM implementation.
@@ -359,7 +359,7 @@ my class PseudoStash is Map { | |||
nqp::stmts( | |||
(my $ctx := nqp::decont(@ctx-info[0])), | |||
nqp::if( | |||
nqp::existskey($ctx,nqp::unbox_s($key)), | |||
(nqp::isconcrete($ctx) && nqp::existskey($ctx,nqp::unbox_s($key))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of this check? $ctx
comes from CtxWalker.next-one which would not return null ctx. Instead it returns empty list which is cut off by the enclosing nqp::while
condition. I consider this isconcrete
check redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I poked some more and I think the underlying problem is this: #1613
The nqp::isnull
checks for $!ctx
in method next-ctx()
don't really work on the JVM backend. I played around with using Mu
and changing the checks to nqp::eqaddr($!ctx,Mu)
and that seemed to help -- this isconcrete
check wasn't necessary anymore.
Since there are a lot of nqp::isnull
checks, it doesn't seem feasible to special case for the JVM backend (with #?if jvm
). sigh
nqp::if( | ||
nqp::isconcrete($!ctx), | ||
($!iter := nqp::iterator(nqp::ctxlexpad($!ctx))) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the previous: the enclosing nqp::if
checks if CtxWalker
object has at least one contexts to iterate over. For this reason $!ctx
will always be something here.
@@ -480,7 +483,7 @@ my class PseudoStash is Map { | |||
($sym := nqp::iterkey_s($!iter)), | |||
# The symbol has to be dynamic if pseudo-package is marked as requiring dynamics or if | |||
# we'recurrently iterating over the dynamic chain. | |||
($got-one := !nqp::atkey($!seen,$sym) && ( | |||
($got-one := !nqp::defined(nqp::atkey($!seen,$sym)) && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do we win with this? Values in $!seen
would either exists and be 1 or not exists. !
would effectively boolify (in NQP terms) both 1 and null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, AFAIK nqp::atkey returns null for the 'not exists' case on the JVM backend. And trying to negate that null results in a NullPointerException:
$ ./perl6-j -e 'use nqp; my $foo := nqp::hash(); my $bar := !nqp::atkey($foo,"foo")'
java.lang.NullPointerException
in block <unit> at -e line 1
Just adding the nqp::defined looks inprecise, though. Reading your comment ("Values in $!seen
would either exists and be 1 or not exists) and the code of next-one() again, wouldn't using nqp::existskey instead of nqp::atkey suffice:
($got-one := !nqp::existskey($!seen,$sym) && ( ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about nqp::existskey
it too. Don't think it would ever be necessary to store 0
s in $!seen
. I'd be ok with it.
But !nqp::null()
failing on JVM sounds like a bug to me. Could be a source of many other problems around the core.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But !nqp::null() failing on JVM sounds like a bug to me. Could be a source of many other problems around the core.
That's very true. For the record, it seems to work with NQP:
$ (cd nqp; ./nqp-j -e 'say(!nqp::null)')
1
$ ./perl6-j -e 'use nqp; nqp::say(!nqp::null)'
java.lang.NullPointerException
in block <unit> at -e line 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be fixed with Raku/nqp@670400e625
No need for s/atkey/existskey/
.
I think, it became clear that my proposed changes didn't make much sense. We've identified the underlying problems:
If no one objects, I'll close this PR. @vrurg Thanks for looking at this! |
Ok, I'm closing. Thank you too! |
This avoids explosions in S02-names/pseudo-6e.t (on the JVM backend) that seem to be related to the code in 'method ctx()' in src/core.e/PseudoStash.pm6. (Compare comments in the closed PR rakudo/rakudo#3130.)
This makes most of S02-names/pseudo-6e.t pass on the JVM backend.