diff --git a/src/vm/jvm/runtime/org/raku/nqp/sixmodel/REPRRegistry.java b/src/vm/jvm/runtime/org/raku/nqp/sixmodel/REPRRegistry.java index 46e11fa17..ca63d0e2c 100644 --- a/src/vm/jvm/runtime/org/raku/nqp/sixmodel/REPRRegistry.java +++ b/src/vm/jvm/runtime/org/raku/nqp/sixmodel/REPRRegistry.java @@ -73,6 +73,15 @@ private static void addREPR(String name, REPR REPR) { addREPR("P6opaque", new P6Opaque()); addREPR("VMHash", new VMHash()); addREPR("VMArray", new VMArray()); + addREPR("VMArray_i8", new VMArray()); + addREPR("VMArray_u8", new VMArray()); + addREPR("VMArray_i16", new VMArray()); + addREPR("VMArray_u16", new VMArray()); + addREPR("VMArray_i32", new VMArray()); + addREPR("VMArray_u32", new VMArray()); + addREPR("VMArray_i", new VMArray()); + addREPR("VMArray_n", new VMArray()); + addREPR("VMArray_s", new VMArray()); addREPR("VMIter", new VMIter()); addREPR("P6str", new P6str()); addREPR("P6int", new P6int()); diff --git a/src/vm/jvm/runtime/org/raku/nqp/sixmodel/SerializationWriter.java b/src/vm/jvm/runtime/org/raku/nqp/sixmodel/SerializationWriter.java index c2d6e12c0..164265642 100644 --- a/src/vm/jvm/runtime/org/raku/nqp/sixmodel/SerializationWriter.java +++ b/src/vm/jvm/runtime/org/raku/nqp/sixmodel/SerializationWriter.java @@ -16,6 +16,7 @@ import org.raku.nqp.sixmodel.reprs.CallCapture; import org.raku.nqp.sixmodel.reprs.IOHandle; import org.raku.nqp.sixmodel.reprs.MultiCache; +import org.raku.nqp.sixmodel.reprs.VMArrayREPRData; public class SerializationWriter { /* The current version of the serialization format. */ @@ -549,7 +550,45 @@ private void serializeStable(STable st) { growToHold(STABLES, STABLES_TABLE_ENTRY_SIZE); /* Make STables table entry. */ - outputs[STABLES].putInt(addStringToHeap(st.REPR.name)); + if (st.REPRData instanceof VMArrayREPRData) { + /* Workaround for native arrays. If they end up as VMArray in the + * string heap, a plain VMArray will be created in deserialize_stub. + * So we cheat and add a suffix to the real REPR name. */ + String reprNameForSerialization; + StorageSpec ss = ((VMArrayREPRData)st.REPRData).ss; + switch (ss.boxed_primitive) { + case StorageSpec.BP_INT: + if (ss.bits == 64) + reprNameForSerialization = "VMArray_i"; + else if (ss.bits == 8) + reprNameForSerialization = ss.is_unsigned == 0 + ? "VMArray_i8" + : "VMArray_u8"; + else if (ss.bits == 16) + reprNameForSerialization = ss.is_unsigned == 0 + ? "VMArray_i16" + : "VMArray_u16"; + else if (ss.bits == 32) + reprNameForSerialization = ss.is_unsigned == 0 + ? "VMArray_i32" + : "VMArray_u32"; + else + reprNameForSerialization = "VMArray_i"; + break; + case StorageSpec.BP_NUM: + reprNameForSerialization = "VMArray_n"; + break; + case StorageSpec.BP_STR: + reprNameForSerialization = "VMArray_s"; + break; + default: + throw ExceptionHandling.dieInternal(tc, "Invalid REPR data for VMArray"); + } + outputs[STABLES].putInt(addStringToHeap(reprNameForSerialization)); + } + else { + outputs[STABLES].putInt(addStringToHeap(st.REPR.name)); + } outputs[STABLES].putInt(outputs[STABLE_DATA].position()); /* Make sure we're going to write to the correct place. */ diff --git a/src/vm/jvm/runtime/org/raku/nqp/sixmodel/reprs/VMArray.java b/src/vm/jvm/runtime/org/raku/nqp/sixmodel/reprs/VMArray.java index 82aaf4536..68c795d09 100644 --- a/src/vm/jvm/runtime/org/raku/nqp/sixmodel/reprs/VMArray.java +++ b/src/vm/jvm/runtime/org/raku/nqp/sixmodel/reprs/VMArray.java @@ -88,7 +88,43 @@ public void compose(ThreadContext tc, STable st, SixModelObject repr_info) { public SixModelObject deserialize_stub(ThreadContext tc, STable st) { SixModelObject obj; if (st.REPRData == null) { - obj = new VMArrayInstance(); + // Either a real VMArray or REPRData not yet known. + switch (st.REPR.name) { + case "VMArray": + obj = new VMArrayInstance(); + break; + case "VMArray_i8": + obj = new VMArrayInstance_i8(); + break; + case "VMArray_u8": + obj = new VMArrayInstance_u8(); + break; + case "VMArray_i16": + obj = new VMArrayInstance_i16(); + break; + case "VMArray_u16": + obj = new VMArrayInstance_u16(); + break; + case "VMArray_i32": + obj = new VMArrayInstance_i32(); + break; + case "VMArray_u32": + obj = new VMArrayInstance_u32(); + break; + case "VMArray_i": + obj = new VMArrayInstance_i(); + break; + case "VMArray_n": + obj = new VMArrayInstance_n(); + break; + case "VMArray_s": + obj = new VMArrayInstance_s(); + break; + default: + throw ExceptionHandling.dieInternal(tc, "Invalid REPR name for VMArray"); + } + // Set real REPR name (we cheated during serialization). + st.REPR.name = "VMArray"; } else { StorageSpec ss = ((VMArrayREPRData)st.REPRData).ss;