Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fill out STable and object deserialization logic.
This also adds the REPR deserialize functions for some representations
but others (especially the rather more complex P6opaque) are to come.
This gets a knowhow with a method in to deserialize well enough to be
able to call the method, at least.
  • Loading branch information
jnthn committed Jan 18, 2013
1 parent 9516dc1 commit e664ef5
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 6 deletions.
5 changes: 3 additions & 2 deletions src/org/perl6/nqp/sixmodel/REPR.java
Expand Up @@ -78,13 +78,14 @@ public void change_type(ThreadContext tc, SixModelObject Object, SixModelObject
* serialization writer. */
// XXX void (*serialize) (ThreadContext, STable *st, void *data, SerializationWriter *writer);

/* Object deserialization. Happens in two steps. The first stub step
/**
* Object deserialization. Happens in two steps. The first stub step
* creates an object to be filled out later. Note that the STable may
* not be fully available yet if it's in the current compilation unit.
* The second step has the STable fully formed (though objects it
* references may not be) and should do the rest of the work. */
public abstract SixModelObject deserialize_stub(ThreadContext tc, STable st);
// XXX void (*deserialize) (ThreadContext, STable *st, void *data, SerializationReader *reader);
public abstract void deserialize_finish(ThreadContext tc, STable st, SerializationReader reader, SixModelObject obj);

/**
* REPR data serialization. Serializes the per-type representation data that
Expand Down
161 changes: 159 additions & 2 deletions src/org/perl6/nqp/sixmodel/SerializationReader.java
Expand Up @@ -2,9 +2,9 @@

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import org.perl6.nqp.runtime.CodeRef;
import org.perl6.nqp.runtime.ThreadContext;
import org.perl6.nqp.sixmodel.reprs.VMHashInstance;

public class SerializationReader {
/* The current version of the serialization format. */
Expand All @@ -19,6 +19,20 @@ public class SerializationReader {
private final int CONTEXTS_TABLE_ENTRY_SIZE = 16;
private final int REPOS_TABLE_ENTRY_SIZE = 16;

/* Possible reference types we can serialize. */
private final short REFVAR_NULL = 1;
private final short REFVAR_OBJECT = 2;
private final short REFVAR_VM_NULL = 3;
private final short REFVAR_VM_INT = 4;
private final short REFVAR_VM_NUM = 5;
private final short REFVAR_VM_STR = 6;
private final short REFVAR_VM_ARR_VAR = 7;
private final short REFVAR_VM_ARR_STR = 8;
private final short REFVAR_VM_ARR_INT = 9;
private final short REFVAR_VM_HASH_STR_VAR = 10;
private final short REFVAR_STATIC_CODEREF = 11;
private final short REFVAR_CLONED_CODEREF = 12;

/* Starting state. */
private ThreadContext tc;
private SerializationContext sc;
Expand Down Expand Up @@ -69,6 +83,12 @@ public void deserialize() {
checkAndDisectInput();
resolveDependencies();

// Put code refs in place.
for (int i = 0; i < cr.length; i++) {
cr[i].sc = sc;
sc.root_codes.add(cr[i]);
}

// Handle any reposessions.
if (reposTableEntries > 0)
throw new RuntimeException("Reposession of SC objects NYI");
Expand All @@ -77,7 +97,19 @@ public void deserialize() {
stubSTables();
stubObjects();

throw new RuntimeException("Deserialization NYI");
// Do first step of deserializing any closures.
if (closureTableEntries > 0)
throw new RuntimeException("Closure deserialization NYI");

// Second passes over STables and objects.
deserializeSTables();
deserializeObjects();

// Finish up contexts and closures.
if (closureTableEntries > 0)
throw new RuntimeException("Closure deserialization NYI");
if (contextTableEntries > 0)
throw new RuntimeException("Context deserialization NYI");
}

/* Checks the header looks sane and all of the places it points to make sense.
Expand Down Expand Up @@ -239,6 +271,131 @@ private void stubObjects() {
}
}

private void deserializeSTables() {
for (int i = 0; i < stTableEntries; i++) {
// Seek to the right position in the data chunk.
orig.position(stTableOffset + i * STABLES_TABLE_ENTRY_SIZE + 4);
orig.position(stDataOffset + orig.getInt());

// Get the STable we need to deserialize into.
STable st = sc.root_stables.get(i);

// Read the HOW, WHAT and WHO.
st.HOW = readObjRef();
st.WHAT = readObjRef();
st.WHO = readRef();

/* Method cache and v-table. */
st.MethodCache = ((VMHashInstance)readRef()).storage;
st.VTable = new SixModelObject[(int)orig.getLong()];
for (int j = 0; j < st.VTable.length; j++)
st.VTable[j] = readRef();

/* Type check cache. */
st.TypeCheckCache = new SixModelObject[(int)orig.getLong()];
for (int j = 0; j < st.TypeCheckCache.length; j++)
st.TypeCheckCache[j] = readRef();

/* Mode flags. */
st.ModeFlags = orig.getInt();

/* Boolification spec. */
if (orig.getLong() != 0) {
st.BoolificationSpec = new BoolificationSpec();
st.BoolificationSpec.Mode = (int)orig.getLong();
st.BoolificationSpec.Method = readRef();
}

/* Container spec. */
if (orig.getLong() != 0) {
st.ContainerSpec = new ContainerSpec();
st.ContainerSpec.ClassHandle = readRef();
st.ContainerSpec.AttrName = lookupString(orig.getInt());
st.ContainerSpec.Hint = (int)orig.getLong();
st.ContainerSpec.FetchMethod = readRef();
}

/* If the REPR has a function to deserialize representation data, call it. */
st.REPR.deserialize_repr_data(tc, st, this);
}
}

private void deserializeObjects() {
for (int i = 0; i < objTableEntries; i++) {
// Can skip if it's a type object.
SixModelObject obj = sc.root_objects.get(i);
if (obj instanceof TypeObject)
continue;

// Seek reader to object data offset.
orig.position(objTableOffset + i * OBJECTS_TABLE_ENTRY_SIZE + 8);
orig.position(objDataOffset + orig.getInt());

// Complete the object's deserialization.
obj.st.REPR.deserialize_finish(tc, obj.st, this, obj);
}
}

public SixModelObject readRef() {
short discrim = orig.getShort();
int elems;
switch (discrim) {
case REFVAR_NULL:
case REFVAR_VM_NULL:
return null;
case REFVAR_OBJECT:
return readObjRef();
case REFVAR_VM_ARR_VAR:
SixModelObject BOOTArray = tc.gc.BOOTArray;
SixModelObject resArray = BOOTArray.st.REPR.allocate(tc, BOOTArray.st);
resArray.initialize(tc);
elems = orig.getInt();
for (int i = 0; i < elems; i++)
resArray.bind_pos_boxed(tc, i, readRef());
resArray.sc = sc;
return resArray;
case REFVAR_VM_HASH_STR_VAR:
SixModelObject BOOTHash = tc.gc.BOOTHash;
SixModelObject resHash = BOOTHash.st.REPR.allocate(tc, BOOTHash.st);
resHash.initialize(tc);
elems = orig.getInt();
for (int i = 0; i < elems; i++) {
String key = lookupString(orig.getInt());
resHash.bind_key_boxed(tc, key, readRef());
}
resHash.sc = sc;
return resHash;
case REFVAR_STATIC_CODEREF:
case REFVAR_CLONED_CODEREF:
SerializationContext sc = locateSC(orig.getInt());
int idx = orig.getInt();
if (idx < 0 || idx >= sc.root_codes.size())
throw new RuntimeException("Invalid SC code index " + idx);
return sc.root_codes.get(idx);
default:
throw new RuntimeException("Unimplemented case of read_ref");
}
}

public SixModelObject readObjRef() {
SerializationContext sc = locateSC(orig.getInt());
int idx = orig.getInt();
if (idx < 0 || idx >= sc.root_objects.size())
throw new RuntimeException("Invalid SC object index " + idx);
return sc.root_objects.get(idx);
}

public long readLong() {
return orig.getLong();
}

public double readDouble() {
return orig.getDouble();
}

public String readStr() {
return lookupString(orig.getInt());
}

private STable lookupSTable(int scIdx, int idx) {
SerializationContext sc = locateSC(scIdx);
Expand Down
6 changes: 6 additions & 0 deletions src/org/perl6/nqp/sixmodel/reprs/KnowHOWAttribute.java
Expand Up @@ -3,6 +3,7 @@
import org.perl6.nqp.runtime.ThreadContext;
import org.perl6.nqp.sixmodel.REPR;
import org.perl6.nqp.sixmodel.STable;
import org.perl6.nqp.sixmodel.SerializationReader;
import org.perl6.nqp.sixmodel.SixModelObject;
import org.perl6.nqp.sixmodel.TypeObject;

Expand All @@ -26,4 +27,9 @@ public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
obj.st = st;
return obj;
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
throw new RuntimeException("KnowHOWAttribute deserialization NYI");
}
}
16 changes: 14 additions & 2 deletions src/org/perl6/nqp/sixmodel/reprs/KnowHOWREPR.java
Expand Up @@ -24,8 +24,20 @@ public SixModelObject allocate(ThreadContext tc, STable st) {
public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
KnowHOWREPRInstance obj = new KnowHOWREPRInstance();
obj.st = st;
obj.attributes = new ArrayList<SixModelObject>();
obj.methods = new HashMap<String, SixModelObject>();
return obj;
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
KnowHOWREPRInstance body = (KnowHOWREPRInstance)obj;
body.name = reader.readStr();

body.attributes = new ArrayList<SixModelObject>();
SixModelObject attrs = reader.readRef();
long elems = attrs.elems(tc);
for (long i = 0; i < elems; i++)
body.attributes.add(attrs.at_pos_boxed(tc, i));

body.methods = ((VMHashInstance)reader.readRef()).storage;
}
}
5 changes: 5 additions & 0 deletions src/org/perl6/nqp/sixmodel/reprs/P6Opaque.java
Expand Up @@ -344,4 +344,9 @@ public Class<?> findClass(String name) {
public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
throw new RuntimeException("P6opaque deserialization NYI");
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
throw new RuntimeException("P6opaque deserialization NYI");
}
}
6 changes: 6 additions & 0 deletions src/org/perl6/nqp/sixmodel/reprs/P6int.java
Expand Up @@ -13,6 +13,7 @@
import org.perl6.nqp.runtime.ThreadContext;
import org.perl6.nqp.sixmodel.REPR;
import org.perl6.nqp.sixmodel.STable;
import org.perl6.nqp.sixmodel.SerializationReader;
import org.perl6.nqp.sixmodel.SixModelObject;
import org.perl6.nqp.sixmodel.StorageSpec;
import org.perl6.nqp.sixmodel.TypeObject;
Expand Down Expand Up @@ -108,4 +109,9 @@ public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
obj.st = st;
return obj;
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
((P6intInstance)obj).value = reader.readLong();
}
}
6 changes: 6 additions & 0 deletions src/org/perl6/nqp/sixmodel/reprs/P6num.java
Expand Up @@ -13,6 +13,7 @@
import org.perl6.nqp.runtime.ThreadContext;
import org.perl6.nqp.sixmodel.REPR;
import org.perl6.nqp.sixmodel.STable;
import org.perl6.nqp.sixmodel.SerializationReader;
import org.perl6.nqp.sixmodel.SixModelObject;
import org.perl6.nqp.sixmodel.StorageSpec;
import org.perl6.nqp.sixmodel.TypeObject;
Expand Down Expand Up @@ -109,4 +110,9 @@ public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
obj.st = st;
return obj;
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
((P6numInstance)obj).value = reader.readDouble();
}
}
6 changes: 6 additions & 0 deletions src/org/perl6/nqp/sixmodel/reprs/P6str.java
Expand Up @@ -13,6 +13,7 @@
import org.perl6.nqp.runtime.ThreadContext;
import org.perl6.nqp.sixmodel.REPR;
import org.perl6.nqp.sixmodel.STable;
import org.perl6.nqp.sixmodel.SerializationReader;
import org.perl6.nqp.sixmodel.SixModelObject;
import org.perl6.nqp.sixmodel.StorageSpec;
import org.perl6.nqp.sixmodel.TypeObject;
Expand Down Expand Up @@ -108,4 +109,9 @@ public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
obj.st = st;
return obj;
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
((P6strInstance)obj).value = reader.readStr();
}
}
6 changes: 6 additions & 0 deletions src/org/perl6/nqp/sixmodel/reprs/SCRef.java
Expand Up @@ -3,6 +3,7 @@
import org.perl6.nqp.runtime.ThreadContext;
import org.perl6.nqp.sixmodel.REPR;
import org.perl6.nqp.sixmodel.STable;
import org.perl6.nqp.sixmodel.SerializationReader;
import org.perl6.nqp.sixmodel.SixModelObject;
import org.perl6.nqp.sixmodel.TypeObject;

Expand All @@ -24,4 +25,9 @@ public SixModelObject allocate(ThreadContext tc, STable st) {
public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
throw new RuntimeException("SCRef does not participate in serialization");
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
throw new RuntimeException("SCRef does not participate in serialization");
}
}
6 changes: 6 additions & 0 deletions src/org/perl6/nqp/sixmodel/reprs/Uninstantiable.java
Expand Up @@ -3,6 +3,7 @@
import org.perl6.nqp.runtime.ThreadContext;
import org.perl6.nqp.sixmodel.REPR;
import org.perl6.nqp.sixmodel.STable;
import org.perl6.nqp.sixmodel.SerializationReader;
import org.perl6.nqp.sixmodel.SixModelObject;
import org.perl6.nqp.sixmodel.TypeObject;

Expand All @@ -22,4 +23,9 @@ public SixModelObject allocate(ThreadContext tc, STable st) {
public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
throw new RuntimeException("Cannot stub an Uninstantiable instance");
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
throw new RuntimeException("Cannot stub an Uninstantiable instance");
}
}
5 changes: 5 additions & 0 deletions src/org/perl6/nqp/sixmodel/reprs/VMArray.java
Expand Up @@ -23,4 +23,9 @@ public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
obj.st = st;
return obj;
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
throw new RuntimeException("VMArray deserialization NYI");
}
}
5 changes: 5 additions & 0 deletions src/org/perl6/nqp/sixmodel/reprs/VMHash.java
Expand Up @@ -30,4 +30,9 @@ public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
obj.storage = new HashMap<String, SixModelObject>();
return obj;
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
throw new RuntimeException("VMHash deserialization NYI");
}
}
6 changes: 6 additions & 0 deletions src/org/perl6/nqp/sixmodel/reprs/VMIter.java
Expand Up @@ -3,6 +3,7 @@
import org.perl6.nqp.runtime.ThreadContext;
import org.perl6.nqp.sixmodel.REPR;
import org.perl6.nqp.sixmodel.STable;
import org.perl6.nqp.sixmodel.SerializationReader;
import org.perl6.nqp.sixmodel.SixModelObject;
import org.perl6.nqp.sixmodel.StorageSpec;
import org.perl6.nqp.sixmodel.TypeObject;
Expand All @@ -29,4 +30,9 @@ public StorageSpec get_value_storage_spec(ThreadContext tc, STable st) {
public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
throw new RuntimeException("VMIter does not participate in serialization");
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
throw new RuntimeException("VMIter does not participate in serialization");
}
}

0 comments on commit e664ef5

Please sign in to comment.