Skip to content

Commit

Permalink
[JVM] Deserialize VMNull as such
Browse files Browse the repository at this point in the history
The old deserialization code gave back a Java null when it encountered
a VMNull. This led to problems when compiling Rakudo's settings: Class
attributes that were initialized to nqp::null ended up as NQPMu.

Fixes Raku#828.
  • Loading branch information
usev6 authored Nov 23, 2024
1 parent b79283c commit 4651b89
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -598,8 +598,9 @@ public SixModelObject readRef() {
int elems;
switch (discrim) {
case REFVAR_NULL:
case REFVAR_VM_NULL:
return null;
case REFVAR_VM_NULL:
return Ops.createNull(tc);
case REFVAR_OBJECT:
return readObjRef();
case REFVAR_VM_INT:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,21 +298,25 @@ public void stop() {
public void writeRef(SixModelObject ref) {
/* Work out what kind of thing we have and determine the discriminator. */
short discrim = 0;
if (Ops.isnull(ref) == 1) {
if (ref == null) {
discrim = REFVAR_NULL;
}
else if (Ops.isnull(ref) == 1) {
/* A real VMNull. */
discrim = REFVAR_VM_NULL;
}
else if (ref.st.REPR instanceof IOHandle) {
/* Can't serialize handles. */
discrim = REFVAR_VM_NULL;
discrim = REFVAR_NULL;
}
else if (ref.st.REPR instanceof CallCapture) {
/* This is a hack for Rakudo's sake; it keeps a CallCapture around in
* the lexpad, for no really good reason. */
discrim = REFVAR_VM_NULL;
discrim = REFVAR_NULL;
}
else if (ref.st.REPR instanceof MultiCache) {
/* These are re-computed each time. */
discrim = REFVAR_VM_NULL;
discrim = REFVAR_NULL;
}
else if (ref.st.WHAT == tc.gc.BOOTInt) {
discrim = REFVAR_VM_INT;
Expand Down Expand Up @@ -606,7 +610,7 @@ else if (ss.bits == 32)
writeHash(st.MethodCache);
}
else {
outputs[currentBuffer].putShort(REFVAR_VM_NULL);
outputs[currentBuffer].putShort(REFVAR_NULL);
}
int vtl = st.VTable == null ? 0 : st.VTable.length;
writeInt(vtl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ else if (nameToHintObject instanceof VMHashInstance) {
i == REPRData.unboxStrSlot || i == REPRData.unboxObjSlot;
info.posDelegate = i == REPRData.posDelSlot;
info.assDelegate = i == REPRData.assDelSlot;
info.hasAutoVivContainer = REPRData.autoVivContainers[i] != null;
info.hasAutoVivContainer = Ops.isnull(REPRData.autoVivContainers[i]) == 0;
attrInfoList.add(info);
}
if (numAttributes > 0) {
Expand Down
6 changes: 5 additions & 1 deletion t/serialization/01-basic.t
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
plan(1518);
plan(1519);

{
my $sc := nqp::createsc('exampleHandle');
Expand Down Expand Up @@ -134,6 +134,7 @@ sub fresh_out_sc() {
has int $!a;
has num $!b;
has str $!c;
has $!d;
method new() {
my $obj := nqp::create(self);
$obj.BUILD();
Expand All @@ -143,10 +144,12 @@ sub fresh_out_sc() {
$!a := 42;
$!b := 6.9;
$!c := 'llama';
$!d := nqp::null;
}
method a() { $!a }
method b() { $!b }
method c() { $!c }
method d() { $!d }
}
my $v := T4.new();
add_to_sc($sc, 0, $v);
Expand All @@ -162,6 +165,7 @@ sub fresh_out_sc() {
ok(nqp::scgetobj($dsc, 0).a == 42, 'P6int attribute has correct value');
ok(nqp::scgetobj($dsc, 0).b == 6.9, 'P6num attribute has correct value');
ok(nqp::scgetobj($dsc, 0).c eq 'llama', 'P6str attribute has correct value');
ok(nqp::isnull(nqp::scgetobj($dsc, 0).d), 'attribute with value nqp::null unchanged');
}

# Serializing an SC with P6opaues and circular references
Expand Down

0 comments on commit 4651b89

Please sign in to comment.