Skip to content

Instantly share code, notes, and snippets.

@usev6
Created May 1, 2016 12:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save usev6/65701798270ef412a1e41b8c480a0133 to your computer and use it in GitHub Desktop.
Save usev6/65701798270ef412a1e41b8c480a0133 to your computer and use it in GitHub Desktop.
I'm trying to debug the following NullPointerException:
$ perl6-j -e 'CallFrame.new.perl'
java.lang.NullPointerException
in block <unit> at -e line 1
For some reasons iterating over the values of a specially constructed Stash (using nqp::iterval) does not work. I get the following output with the program below.
$ perl6-m iterating.p6 # works fine
-- Iterating using $h.values --
([] (!UNIT_MARKER) (EXPORT) (Any) Nil (GLOBAL) (GLOBAL) Nil (Mu) (Mu) Nil <anon> (GLOBAL))
-- Iterating using $h.foo --
([] (!UNIT_MARKER) (EXPORT) (Any) Nil (GLOBAL) (GLOBAL) Nil (Mu) (Mu) Nil <anon> (GLOBAL))
-- Iterating "by hand" --
[] (!UNIT_MARKER) (EXPORT) (Any) Nil (GLOBAL) (GLOBAL) Nil (Mu) (Mu) Nil <anon> (GLOBAL)
$ perl6-j iterating.p6
-- Iterating using $h.values --
((Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu))
-- Iterating using $h.foo --
((Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu) (Mu))
-- Iterating "by hand" --
(Mu) (GLOBAL) <anon> (!UNIT_MARKER) Nil (Mu) Nil (GLOBAL) (EXPORT) Nil [] (Any) (GLOBAL)
====
$ cat iterating.p6
use nqp;
use MONKEY-TYPING;
my Mu $ctx := nqp::ctx();
my $h := nqp::create(Stash);
nqp::bindattr($h, Map, "\$!storage", $ctx);
#say $h.keys; # works
#say $h.values; # all (Mu) on JVM
#say $h.pairs; # NPE on JVM
augment class Stash {
# duplicate method 'value' from Map.pm
method foo () {
Seq.new(class :: does Rakudo::Internals::MappyIterator {
method pull-one() {
$!iter
?? nqp::iterval(nqp::shift($!iter))
!! IterationEnd
}
method push-all($target) {
my $no-sink;
$no-sink :=
$target.push(nqp::iterval(nqp::shift($!iter)))
while $!iter;
IterationEnd
}
}.new(self))
}
}
say "-- Iterating using \$h.values --";
say $h.values;
say "-- Iterating using \$h.foo --";
say $h.foo;
say '-- Iterating "by hand" --';
for $h.keys -> $key { print $h{$key}.gist, " " };
@usev6
Copy link
Author

usev6 commented May 1, 2016

It's no general problem with nqp::iterval. The following code (same code path as far as I understand) works as expected:

perl6-j -e 'use nqp; my $foo := nqp::hash("a",2,"b",3); my $h := nqp::create(Stash); nqp::bindattr($h, Map, "$!storage", $foo); say $h.values'
(3 2)

@usev6
Copy link
Author

usev6 commented May 1, 2016

diff --git a/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java b/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java
index af0bfbe..601572d 100644
--- a/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java
+++ b/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java
@@ -3619,19 +3619,29 @@ public final class Ops {
             StaticCodeInfo sci = ((ContextRefInstance)agg).context.codeRef.staticInfo;
             if (sci.oLexicalNames != null) {
                 for (int i = 0; i < sci.oLexicalNames.length; i++)
-                    hash.bind_key_boxed(tc, sci.oLexicalNames[i], null);
+                    hash.bind_key_boxed(tc, sci.oLexicalNames[i],
+                        ((ContextRefInstance)agg).at_key_boxed(tc, sci.oLexicalNames[i]));
             }
             if (sci.iLexicalNames != null) {
-                for (int i = 0; i < sci.iLexicalNames.length; i++)
-                    hash.bind_key_boxed(tc, sci.iLexicalNames[i], null);
+                for (int i = 0; i < sci.iLexicalNames.length; i++) {
+                    ((ContextRefInstance)agg).at_key_boxed(tc, sci.iLexicalNames[i]);
+                    hash.bind_key_boxed(tc, sci.iLexicalNames[i],
+                        box_i(tc.native_i, ((ContextRefInstance)agg).context.codeRef.staticInfo.compUnit.hllConfig.intBoxType, tc));
+                }
             }
             if (sci.nLexicalNames != null) {
-                for (int i = 0; i < sci.nLexicalNames.length; i++)
-                    hash.bind_key_boxed(tc, sci.nLexicalNames[i], null);
+                for (int i = 0; i < sci.nLexicalNames.length; i++) {
+                    ((ContextRefInstance)agg).at_key_boxed(tc, sci.nLexicalNames[i]);
+                    hash.bind_key_boxed(tc, sci.nLexicalNames[i],
+                        box_n(tc.native_n, ((ContextRefInstance)agg).context.codeRef.staticInfo.compUnit.hllConfig.numBoxType, tc));
+                }
             }
             if (sci.sLexicalNames != null) {
-                for (int i = 0; i < sci.sLexicalNames.length; i++)
-                    hash.bind_key_boxed(tc, sci.sLexicalNames[i], null);
+                for (int i = 0; i < sci.sLexicalNames.length; i++) {
+                    ((ContextRefInstance)agg).at_key_boxed(tc, sci.sLexicalNames[i]);
+                    hash.bind_key_boxed(tc, sci.sLexicalNames[i],
+                        box_s(tc.native_s, ((ContextRefInstance)agg).context.codeRef.staticInfo.compUnit.hllConfig.strBoxType, tc));
+                }
             }

             return iter(hash, tc);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment