Permalink
Browse files

Start implementing serialization for our objects

  • Loading branch information...
1 parent b25256f commit 1993029d001b083d357e1607429e36c76e877f75 @sorear committed Oct 9, 2011
Showing with 181 additions and 16 deletions.
  1. +1 −0 lib/Builtins.cs
  2. +1 −0 lib/Cursor.cs
  3. +139 −11 lib/Kernel.cs
  4. +3 −0 lib/NieczaCLR.cs
  5. +11 −2 lib/ObjModel.cs
  6. +26 −3 lib/Serialize.cs
View
@@ -223,6 +223,7 @@ class SubstrLValue: Variable {
public override Variable GetVar() {
return Kernel.BoxAnyMO<Variable>(this, Kernel.ScalarMO);
}
+ public override void Freeze(Niecza.Serialization.FreezeBuffer fb) { throw new NotImplementedException(); }
}
public static string LaxSubstring(string str, int from) {
View
@@ -533,6 +533,7 @@ public class Cursor : P6any {
public CapInfo captures;
public STable save_klass;
+ public override void Freeze(Niecza.Serialization.FreezeBuffer fb) { throw new NotImplementedException(); }
public string GetBacking() { return global.orig_s; }
public Cursor(P6any proto, string text, P6any actions)
View
@@ -7,6 +7,7 @@
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using Niecza.CLRBackend;
+using Niecza.Serialization;
namespace Niecza {
// We like to reuse continuation objects for speed - every function only
@@ -38,7 +39,7 @@ public sealed class DispatchEnt {
// except the targets of := and ::=.
[StructLayout(LayoutKind.Sequential, Pack = 1)]
- public abstract class Variable {
+ public abstract class Variable : IFreeze {
public ViviHook whence;
// these should be treated as ro for the life of the variable
@@ -51,10 +52,47 @@ public abstract class Variable {
public abstract Variable GetVar();
+ const int S_RO = 0;
+ const int S_LIST = 1;
+ const int S_RW = 2;
+ const int S_VIV = 3;
+
+ public abstract void Freeze(FreezeBuffer fb);
+
+ internal void BaseFreeze(FreezeBuffer fb, SerializationCode code) {
+ fb.Byte((byte)((int)code + (islist ? S_LIST :
+ !rw ? S_RO : whence == null ? S_RW : S_VIV)));
+
+ if (whence != null) fb.ObjRef(whence);
+ if (rw) fb.ObjRef(type);
+ }
+
+ // note: callers need to make sure type is set up properly if null
+ public Variable() { }
+ internal Variable(ThawBuffer tb, int subcode) {
+ switch (subcode) {
+ default: break;
+ case S_RO:
+ // rw = false islist = false whence = null type = null
+ break;
+ case S_LIST:
+ islist = true;
+ break;
+ case S_VIV:
+ whence = (ViviHook) tb.ObjRef();
+ goto case S_RW;
+ case S_RW:
+ rw = true;
+ type = (STable) tb.ObjRef();
+ break;
+ }
+ }
+
public static readonly Variable[] None = new Variable[0];
}
- public abstract class ViviHook {
+ public abstract class ViviHook : IFreeze {
+ public abstract void Freeze(FreezeBuffer fb);
public abstract void Do(Variable toviv);
}
@@ -65,6 +103,13 @@ public class SubViviHook : ViviHook {
Kernel.RunInferior(sub.Invoke(Kernel.GetInferiorRoot(),
new Variable[] { toviv }, null));
}
+ public override void Freeze(FreezeBuffer fb) {
+ fb.Byte((byte)SerializationCode.SubViviHook);
+ fb.ObjRef(sub);
+ }
+ internal static SubViviHook Thaw(ThawBuffer tb) {
+ return new SubViviHook((P6any)tb.ObjRef());
+ }
}
public class HashViviHook : ViviHook {
@@ -75,6 +120,14 @@ public class HashViviHook : ViviHook {
VarHash rh = Kernel.UnboxAny<VarHash>(hash);
rh[key] = toviv;
}
+ public override void Freeze(FreezeBuffer fb) {
+ fb.Byte((byte)SerializationCode.HashViviHook);
+ fb.ObjRef(hash);
+ fb.String(key);
+ }
+ internal static IFreeze Thaw(ThawBuffer tb) {
+ return new HashViviHook((P6any)tb.ObjRef(), tb.String());
+ }
}
public class NewHashViviHook : ViviHook {
@@ -86,6 +139,14 @@ public class NewHashViviHook : ViviHook {
rh[key] = toviv;
hashv.Store(Kernel.BoxRaw(rh, Kernel.HashMO));
}
+ public override void Freeze(FreezeBuffer fb) {
+ fb.Byte((byte)SerializationCode.NewHashViviHook);
+ fb.ObjRef(hashv);
+ fb.String(key);
+ }
+ internal static IFreeze Thaw(ThawBuffer tb) {
+ return new NewHashViviHook((Variable)tb.ObjRef(), tb.String());
+ }
}
public class ArrayViviHook : ViviHook {
@@ -98,6 +159,14 @@ public class ArrayViviHook : ViviHook {
vd.Push(Kernel.NewTypedScalar(null));
vd[key] = toviv;
}
+ public override void Freeze(FreezeBuffer fb) {
+ fb.Byte((byte)SerializationCode.ArrayViviHook);
+ fb.ObjRef(ary);
+ fb.Int(key);
+ }
+ internal static IFreeze Thaw(ThawBuffer tb) {
+ return new ArrayViviHook((P6any)tb.ObjRef(), tb.Int());
+ }
}
public class NewArrayViviHook : ViviHook {
@@ -114,6 +183,14 @@ public class NewArrayViviHook : ViviHook {
d.slots[1] = new VarDeque();
ary.Store(d);
}
+ public override void Freeze(FreezeBuffer fb) {
+ fb.Byte((byte)SerializationCode.NewArrayViviHook);
+ fb.ObjRef(ary);
+ fb.Int(key);
+ }
+ internal static IFreeze Thaw(ThawBuffer tb) {
+ return new NewArrayViviHook((Variable)tb.ObjRef(), tb.Int());
+ }
}
public sealed class SimpleVariable: Variable {
@@ -146,6 +223,11 @@ public sealed class SimpleVariable: Variable {
public override Variable GetVar() {
return Kernel.BoxAnyMO<Variable>(this, Kernel.ScalarMO);
}
+
+ public override void Freeze(FreezeBuffer fb) {
+ BaseFreeze(fb, SerializationCode.SimpleVariable);
+ fb.ObjRef(val);
+ }
}
public sealed class TiedVariable: Variable {
@@ -183,7 +265,8 @@ public sealed class TiedVariable: Variable {
public override Variable GetVar() {
return Kernel.BoxAnyMO<Variable>(this, Kernel.ScalarMO);
}
- }
+ public override void Freeze(FreezeBuffer fb) { throw new NotImplementedException(); }
+}
// Used to make Variable sharing explicit in some cases; will eventually be
// the only way to share a bvalue
@@ -192,13 +275,28 @@ public sealed class BValue {
public BValue(Variable v) { this.v = v; }
}
- public class StashEnt {
+ public class StashEnt : IFreeze {
public Variable v;
public string file;
public int line;
+
+ void IFreeze.Freeze(FreezeBuffer fb) {
+ fb.Byte((byte)SerializationCode.StashEnt);
+ fb.ObjRef(v);
+ fb.String(file);
+ fb.Int(line);
+ }
+
+ internal static StashEnt Thaw(ThawBuffer tb) {
+ StashEnt r = new StashEnt();
+ r.v = (Variable)tb.ObjRef();
+ r.file = tb.String();
+ r.line = tb.Int();
+ return r;
+ }
}
- public sealed class RuntimeUnit {
+ public sealed class RuntimeUnit : IFreeze {
static Dictionary<string, byte[]> heapreg;
public string name, filename, modtime, asm_name, dll_name;
@@ -455,7 +553,7 @@ class IdentityComparer : IEqualityComparer<object> {
}
internal CpsOp AltInfoConst(CgContext cx, object lads, string dba, string[] labels) {
- return null; // TODO: redesign needed
+ throw new NotImplementedException(); // TODO: redesign needed
}
internal FieldBuilder NewField(string name, Type ty) {
@@ -1019,6 +1117,26 @@ class IdentityComparer : IEqualityComparer<object> {
type);
}
}
+
+ void IFreeze.Freeze(FreezeBuffer fb) {
+ fb.Byte((byte)SerializationCode.RuntimeUnit);
+
+ fb.String(name);
+ fb.String(filename);
+ fb.String(modtime);
+ fb.String(asm_name);
+ fb.String(dll_name);
+
+ fb.Int(globals.Count);
+ foreach (KeyValuePair<string, StashEnt> kv in globals) {
+ fb.String(kv.Key);
+ fb.ObjRef(kv.Value);
+ }
+
+ fb.ObjRef(mainline);
+ fb.ObjRef(bottom);
+ fb.Byte((byte)(is_mainish ? 1 : 0));
+ }
}
public class LeaveHook {
@@ -1263,23 +1381,27 @@ public class LIPackage : LexInfo {
// changed, but it's rare by construction. We don't want to be
// like Rakudo/Parrot where simple sub cloning requires copying
// 100s of bytes.
- public class SubInfo {
+ public class SubInfo : IFreeze {
// Essential call functions
public DynBlockDelegate code;
public int nspill;
public int[] sig_i;
public object[] sig_r;
- // Standard metadata
+ // Basic metadata
+ public int[] lines;
public Dictionary<string, LexInfo> dylex;
public uint dylex_filter; // (32,1) Bloom on hash code
- public int[] lines;
- public STable mo;
- // for inheriting hints
+
+ // References to related objects
public SubInfo outer;
public P6any protosub;
public Frame protopad;
public RuntimeUnit unit;
+
+ public STable mo;
+
+ // Standard metadata
public int xref_no;
public int fixups_from;
public string name;
@@ -1870,6 +1992,11 @@ public class UsedInScopeInfo {
public SubInfo(string name, DynBlockDelegate code) :
this(name, null, code, null, null, new int[0], null, 0) { }
+
+ void IFreeze.Freeze(FreezeBuffer fb) {
+ fb.Byte((byte)SerializationCode.SubInfo);
+ throw new NotImplementedException();
+ }
}
// We need hashy frames available to properly handle BEGIN; for the time
@@ -2176,6 +2303,7 @@ public class Frame: P6any {
}
return caller;
}
+ public override void Freeze(FreezeBuffer fb) { throw new NotImplementedException(); }
}
public class NieczaException: Exception {
View
@@ -209,6 +209,8 @@ sealed class PropertyProxy : Variable {
public override Variable GetVar() {
return Kernel.BoxAnyMO<Variable>(this, Kernel.ScalarMO);
}
+
+ public override void Freeze(Niecza.Serialization.FreezeBuffer fb) { throw new NotImplementedException(); }
}
sealed class FieldProxy : Variable {
@@ -241,6 +243,7 @@ sealed class FieldProxy : Variable {
public override Variable GetVar() {
return Kernel.BoxAnyMO<Variable>(this, Kernel.ScalarMO);
}
+ public override void Freeze(Niecza.Serialization.FreezeBuffer fb) { throw new NotImplementedException(); }
}
class OverloadCandidate : MultiCandidate {
View
@@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
+using Niecza.Serialization;
namespace Niecza {
- public abstract class P6any {
+ public abstract class P6any: IFreeze {
public STable mo;
+ public abstract void Freeze(FreezeBuffer fb);
+
public virtual object GetSlot(string name) {
throw new InvalidOperationException("no slots in this repr");
}
@@ -628,7 +631,7 @@ public class DispatchSet {
// generally a single class is limited to a single representation.
// (Although due to quirks of the C# implementation, Cursor and
// BoxObject can share the P6opaque STable)
- public class STable {
+ public class STable: IFreeze {
public static readonly ContextHandler<Variable> CallStr
= new CtxCallMethod("Str");
public static readonly ContextHandler<Variable> CallBool
@@ -851,6 +854,10 @@ public class STable {
public void FillParametricRole(P6any factory) {
mo.FillParametricRole(factory);
}
+
+ void IFreeze.Freeze(FreezeBuffer fb) {
+ throw new NotImplementedException();
+ }
}
// This is quite similar to DynFrame and I wonder if I can unify them.
@@ -888,6 +895,8 @@ public class P6opaque: P6any {
public override bool IsDefined() {
return this != mo.typeObject;
}
+
+ public override void Freeze(FreezeBuffer fb) { throw new NotImplementedException(); }
}
public class BoxObject<T> : P6opaque {
Oops, something went wrong.

0 comments on commit 1993029

Please sign in to comment.