Permalink
Browse files

Thaw for SimpleVariable, StashEnt

  • Loading branch information...
1 parent 1c5bb04 commit fe6e5952425df586f40d471e0f5c02a653334c92 @sorear committed Oct 15, 2011
Showing with 90 additions and 55 deletions.
  1. +54 −51 lib/Kernel.cs
  2. +36 −4 lib/Serialize.cs
View
@@ -60,41 +60,10 @@ public abstract class Variable : IFreeze {
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];
}
@@ -201,9 +170,10 @@ public class NewArrayViviHook : ViviHook {
}
}
- public sealed class SimpleVariable: Variable {
+ public sealed class SimpleVariable: Variable, IFixup {
P6any val;
+ private SimpleVariable() { }
public SimpleVariable(bool rw, bool islist, STable type, ViviHook whence, P6any val) {
this.val = val; this.whence = whence; this.rw = rw;
this.islist = islist; this.type = type;
@@ -232,16 +202,54 @@ public sealed class SimpleVariable: Variable {
return Kernel.BoxAnyMO<Variable>(this, Kernel.ScalarMO);
}
+ const int S_RO = 0;
+ const int S_LIST = 1;
+ const int S_RW = 2;
+ const int S_VIV = 3;
+
public override void Freeze(FreezeBuffer fb) {
- BaseFreeze(fb, SerializationCode.SimpleVariable);
+ int code = ((int)SerializationCode.SimpleVariable) +
+ (islist ? S_LIST : !rw ? S_RO : whence == null ? S_RW : S_VIV);
+ fb.Byte((byte)code);
+
+ if (whence != null) fb.ObjRef(whence);
+ if (rw) fb.ObjRef(type);
fb.ObjRef(val);
}
+ void IFixup.Fixup() {
+ type = val.mo;
+ }
+ internal static SimpleVariable Thaw(ThawBuffer tb, int subcode) {
+ SimpleVariable n = new SimpleVariable();
+ tb.Register(n);
+ switch (subcode) {
+ default: throw new ArgumentException(subcode.ToString());
+ case S_RO:
+ // rw = false islist = false whence = null type = null
+ tb.PushFixup(n);
+ break;
+ case S_LIST:
+ tb.PushFixup(n);
+ n.islist = true;
+ break;
+ case S_VIV:
+ n.whence = (ViviHook) tb.ObjRef();
+ goto case S_RW;
+ case S_RW:
+ n.rw = true;
+ n.type = (STable) tb.ObjRef();
+ break;
+ }
+ n.val = (P6any) tb.ObjRef();
+ return n;
+ }
}
public sealed class TiedVariable: Variable {
P6any fetch;
P6any store;
+ private TiedVariable() { }
public TiedVariable(STable type, P6any whsub, P6any fetch, P6any store) {
this.fetch = fetch;
this.store = store;
@@ -280,6 +288,15 @@ public sealed class TiedVariable: Variable {
fb.ObjRef(store);
fb.ObjRef(whence);
}
+ internal static TiedVariable Thaw(ThawBuffer tb) {
+ TiedVariable n = new TiedVariable();
+ tb.Register(n);
+ n.type = (STable) tb.ObjRef();
+ n.fetch = (P6any) tb.ObjRef();
+ n.store = (P6any) tb.ObjRef();
+ n.whence = (ViviHook) tb.ObjRef();
+ return n;
+ }
}
// Used to make Variable sharing explicit in some cases; will eventually be
@@ -303,6 +320,7 @@ public class StashEnt : IFreeze {
internal static StashEnt Thaw(ThawBuffer tb) {
StashEnt r = new StashEnt();
+ tb.Register(r);
r.v = (Variable)tb.ObjRef();
r.file = tb.String();
r.line = tb.Int();
@@ -1591,29 +1609,14 @@ public class UsedInScopeInfo {
fb.ObjRef(o);
}
// can't save param0/param1. Or can we?
- fb.Int(children.Count);
- foreach(SubInfo si in children)
- fb.ObjRef(si);
+ fb.Refs(children);
if (extend == null)
- fb.Int(-1);
+ fb.Int(0);
else {
fb.Int(extend.Count);
foreach(KeyValuePair<string,object[]> kv in extend) {
fb.String(kv.Key);
- fb.Int(kv.Value.Length);
- foreach (object o in kv.Value) {
- if (o is int) {
- fb.Byte(0);
- fb.Int((int)o);
- } else if (o is string) {
- fb.Byte(1);
- fb.String((string)o);
- } else if (o is bool) {
- fb.Byte((byte)(((bool)o)? 3 : 2));
- } else {
- throw new NotImplementedException(o.GetType().Name);
- }
- }
+ fb.Refs(kv.Value);
}
}
}
View
@@ -130,6 +130,7 @@ struct ObjRef {
if (rver != version)
throw new ThawException("version mismatch loading " + file);
+ tb.RunFixups();
su.root = tb.ObjRef();
success = true;
} finally {
@@ -220,12 +221,16 @@ enum SerializationCode : byte {
String,
ArrP6any,
ArrVariable,
+ Boolean,
Int,
Double,
// variables
SimpleVariable, // allow 4 for flags
- SubstrLValue = SimpleVariable + 4,
+ SimpleVariable_1,
+ SimpleVariable_2,
+ SimpleVariable_3,
+ SubstrLValue,
TiedVariable,
// vivification hooks
@@ -404,13 +409,13 @@ public class FreezeBuffer {
static Type[] anyTypes = new Type[] {
typeof(string), typeof(P6any[]), typeof(Variable[]),
- typeof(int), typeof(double),
+ typeof(bool), typeof(int), typeof(double),
};
void FallbackFreeze(object o) {
int ix = 0;
Type t = o.GetType();
- while (ix != 11 && anyTypes[ix] != t) ix++;
+ while (ix != anyTypes.Length && anyTypes[ix] != t) ix++;
Byte((byte)(((int)SerializationCode.String) + ix));
switch(ix) {
@@ -424,9 +429,12 @@ public class FreezeBuffer {
Refs((Variable[])o);
break;
case 3:
- Int((int)o);
+ Byte((byte)((bool)o ? 1 : 0));
break;
case 4:
+ Int((int)o);
+ break;
+ case 5:
Long(BitConverter.DoubleToInt64Bits((double)o));
break;
default:
@@ -440,6 +448,10 @@ public class FreezeBuffer {
public interface IFreeze {
void Freeze(FreezeBuffer fb);
}
+ // implement this if you need to copy in data from other objects, &c
+ interface IFixup {
+ void Fixup();
+ }
class ThawBuffer {
byte[] data;
@@ -450,12 +462,24 @@ class ThawBuffer {
int refed_units;
SerUnit unit;
+ List<IFixup> fixups_needed = new List<IFixup>();
+
internal ThawBuffer(ObjectRegistry reg, SerUnit unit, byte[] data) {
this.data = data;
this.reg = reg;
this.unit = unit;
}
+ internal void RunFixups() {
+ foreach (IFixup f in fixups_needed)
+ f.Fixup();
+ fixups_needed.Clear();
+ }
+
+ internal void PushFixup(IFixup f) {
+ fixups_needed.Add(f);
+ }
+
public byte Byte() { return data[rpointer++]; }
public short Short() {
@@ -529,6 +553,14 @@ class ThawBuffer {
return LoadNewUnit();
case SerializationCode.RuntimeUnit:
return RuntimeUnit.Thaw(this);
+ case SerializationCode.StashEnt:
+ return StashEnt.Thaw(this);
+ case SerializationCode.SimpleVariable:
+ case SerializationCode.SimpleVariable_1:
+ case SerializationCode.SimpleVariable_2:
+ case SerializationCode.SimpleVariable_3:
+ return SimpleVariable.Thaw(this,
+ (int)tag - (int)SerializationCode.SimpleVariable);
default:
throw new ThawException("unexpected object tag " + tag);
}

0 comments on commit fe6e595

Please sign in to comment.