VmEnvironment RebuildEnvironment( object[] objects, int index, Composite composite, Func<int, object> reader) { var result = new VmEnvironment (); objects [index] = result; result.Frame = (VmEnvFrame)reader (composite.Elements [0]); result.Next = (VmEnvironment)reader (composite.Elements [1]); result.Uses = (int)(long)reader (composite.Elements [2]); return result; }
int SerializeEnvironment(VmEnvironment env, object obj) { var composite = new Composite { Kind = ObjectTypes.Environment, Elements = new int[3] }; var result = SerializeOneHashed (composite, obj); composite.Elements [0] = Serialize (env.Frame); composite.Elements [1] = Serialize (env.Next); composite.Elements [2] = SerializeOne (env.Uses); return result; }
static Value GetFromEnvironment(VmEnvironment env, int frameNumber, int varIndex) { return FindFrame (env, frameNumber).Values [varIndex]; }
static void HandleNewFrame(Vm vm) { var instruction = vm.CurrentInstruction (); var args = (string[])instruction.Arguments; var frame = new VmEnvFrame () { VarNames = args, Values = new Value[args.Length], IntroducedAtProgramCounter = vm.programCounter }; var newEnv = new VmEnvironment () { Frame = frame, Next = vm.currentEnvironment }; vm.currentEnvironment = newEnv; vm.IncrementCells (args.Length * 3 + 5); vm.programCounter++; }
void DeserializeState(byte[] serializedState) { using (var ms = new MemoryStream(serializedState)) { Serialization.Utils.DeserializeWithMd5CheckSum (ms, str => { var version = Serialization.Utils.ReadInt (str); if (version > Shovel.Api.Version) { throw new Exceptions.VersionNotSupportedException (); } var stackIndex = Serialization.Utils.ReadInt (str); var envIndex = Serialization.Utils.ReadInt (str); this.programCounter = Serialization.Utils.ReadInt (str); var bytes = new byte[32]; str.Read (bytes, 0, 32); var actualBytecodeMd5 = Encoding.UTF8.GetString (bytes); if (actualBytecodeMd5 != Utils.GetBytecodeMd5 (this.bytecode)) { throw new Exceptions.BytecodeDoesntMatchState (); } // Read and ignore the source MD5. str.Read (bytes, 0, 32); // Read the number of ticks executed so far. this.executedTicks = Serialization.Utils.ReadLong (ms); // Read the number of used cells. this.usedCells = Serialization.Utils.ReadInt (ms); var ser = new Serialization.VmStateSerializer (); ser.Deserialize (str, version, reader => { this.stack = new Stack ((Value[])reader (stackIndex)); this.currentEnvironment = (VmEnvironment)reader (envIndex); } ); return null; }); } }
static VmEnvFrame FindFrame(VmEnvironment env, int frameNumber) { while (env != null && frameNumber > 0) { env = env.Next; frameNumber --; } if (env == null) { Utils.Panic (); } return env.Frame; }
int CountCellsEnvironment(VmEnvironment env, HashSet<object> visited) { var sum = 3; visited.Add (env); sum += CountCellsImpl (env.Frame, visited); sum += CountCellsImpl (env.Next, visited); return sum; }
void ApplyReturnAddress(ReturnAddress returnAddress) { this.programCounter = returnAddress.ProgramCounter; this.currentEnvironment = returnAddress.Environment; }
static void SetInEnvironment( VmEnvironment env, int frameNumber, int varIndex, Value value) { FindFrame (env, frameNumber).Values [varIndex] = value; }
void ApplyReturnAddress(ReturnAddress returnAddress) { this.programCounter = returnAddress.ProgramCounter; this.currentEnvironment = returnAddress.Environment; this.currentEnvironment.DecreaseUsesLocally (); }
static VmEnvironment FreshFrame(Vm vm, Instruction instruction) { var args = (string[])instruction.Arguments; var frame = new VmEnvFrame () { VarNames = args, Values = new Value[args.Length], IntroducedAtProgramCounter = vm.programCounter }; var result = new VmEnvironment () { Frame = frame, }; vm.IncrementCells (args.Length * 3 + 5); instruction.Cache = result; return result; }