object LoadNewUnit() { string name = String(); if (refed_units == unit_map.Length) { Array.Resize(ref unit_map, refed_units * 2); } SerUnit su = reg.LoadUnit(name); unit_map[refed_units++] = su; byte[] hash = Bytes(su.hash.Length); for (int i = 0; i < hash.Length; i++) { if (hash[i] != su.hash[i]) { goto badhash; } } int ix = Int(); return(su.bynum[ix]); badhash: throw new ThawException(string.Format("Hash mismatch for " + "unit {0} referenced from {1}, wanted {2}, got {3}", su.name, unit.name, Utils.HashToStr(unit.hash), Utils.HashToStr(su.hash))); }
// Routines for use by serialization code public bool CheckWriteObject(SerUnit into, object o, out SerUnit lui, out int id) { ObjRef or; if (byref.TryGetValue(o, out or)) { lui = or.unit; id = or.id; return(true); } if (into.nobj == into.bynum.Length) { Array.Resize(ref into.bynum, into.nobj * 2); } or.unit = lui = into; id = or.id = into.nobj++; into.bynum[id] = o; byref[o] = or; return(false); }
internal ThawBuffer(Compartment setting, ObjectRegistry reg, SerUnit unit, byte[] data) { this.data = data; this.setting = setting; this.reg = reg; this.unit = unit; }
internal FreezeBuffer(ObjectRegistry reg, SerUnit unit) { if (reg == null || unit == null) { throw new ArgumentNullException(); } this.reg = reg; this.unit = unit; unit_to_offset = new Dictionary <SerUnit, int>(); data = new byte[256]; }
// Routines for use by compilation manager // Loads a single unit from the compiled-data directory. // Will throw a ThawException if a stale reference is encountered // or other data format error. public SerUnit LoadUnit(string name) { SerUnit su; // is the unit already loaded? if (units.TryGetValue(name, out su)) { return(su); } string file = Path.Combine(Backend.obj_dir, Backend.prefix + name.Replace("::", ".") + ".ser"); byte[] bytes = File.ReadAllBytes(file); su = new SerUnit(); su.name = name; su.hash = NewHash().ComputeHash(bytes); ThawBuffer tb = new ThawBuffer(this, su, bytes); units[name] = su; bool success = false; try { string rsig = tb.String(); if (rsig != signature) { throw new ThawException("signature mismatch loading " + file); } int rver = tb.Int(); if (rver != version) { throw new ThawException("version mismatch loading " + file); } su.root = tb.ObjRef(); tb.RunFixups(); success = true; } finally { // don't leave half-read units in the map if (!success) { UnloadUnit(name); } } return(su); }
public void RegisterThawed(SerUnit into, object o) { ObjRef or; if (into.nobj == into.bynum.Length) { Array.Resize(ref into.bynum, into.nobj * 2); } or.unit = into; or.id = into.nobj++; into.bynum[or.id] = o; byref[o] = or; }
// removes a stale unit so a new version can be saved over it. public void UnloadUnit(string name) { if (!units.ContainsKey(name)) { return; } SerUnit su = units[name]; units.Remove(name); for (int i = 0; i < su.nobj; i++) { byref.Remove(su.bynum[i]); } }
// Routines for use by compilation manager public void InstallFakeUnit(string name, params object[] items) { SerUnit su = new SerUnit(); su.fake = true; su.name = name; su.bynum = items; su.hash = new byte[0]; units[name] = su; ObjRef or; or.unit = su; for (or.id = 0; or.id < items.Length; or.id++) { byref[items[or.id]] = or; } }
public SerUnit SaveUnit(string name, IFreeze root) { SerUnit su = new SerUnit(); su.name = name; su.root = root; if (units.ContainsKey(name)) { throw new InvalidOperationException("unit " + name + " exists"); } bool success = false; string file = Path.Combine(Backend.obj_dir, Backend.prefix + name.Replace("::", ".") + ".ser"); FreezeBuffer fb = new FreezeBuffer(this, su); units[name] = su; try { fb.String(signature); fb.Int(version); fb.ObjRef(root); byte[] data = fb.GetData(); su.hash = NewHash().ComputeHash(data); File.WriteAllBytes(file, data); success = true; } finally { if (!success) { UnloadUnit(name); } } return(su); }
internal ThawBuffer(ObjectRegistry reg, SerUnit unit, byte[] data) { this.data = data; this.reg = reg; this.unit = unit; }
// Loads a single unit from the compiled-data directory. // Will throw a ThawException if a stale reference is encountered // or other data format error. public SerUnit LoadUnit(string name, bool fake = false) { SerUnit su; // is the unit already loaded? if (units.TryGetValue(name, out su)) { return(su); } if (fake) { if (name.StartsWith("CLR,")) { CLRWrapperProvider.LoadWrapper(setting, name.Substring(4)); } else { throw new ThawException("No handler for fake unit name " + name); } return(units[name]); } // Probe for the topmost cache that contains our module string file = null; byte[] bytes = null; for (int i = setting.obj_dirs.Length - 1; i >= 0; i--) { file = Path.Combine(setting.obj_dirs[i], name.Replace("::", ".") + ".ser"); if (File.Exists(file)) { bytes = File.ReadAllBytes(file); break; } } if (bytes == null) { throw new ThawException("unit not found: " + name); } su = new SerUnit(); su.name = name; su.hash = NewHash().ComputeHash(bytes); ThawBuffer tb = new ThawBuffer(setting, this, su, bytes); tb.file = file; units[name] = su; bool success = false; try { string rsig = tb.String(); if (rsig != signature) { throw new ThawException("signature mismatch loading " + file); } int rver = tb.Int(); if (rver < VersionMin || rver > VersionCur) { throw new ThawException("version mismatch loading " + file); } tb.version = rver; su.root = tb.ObjRef(); tb.RunFixups(); success = true; } finally { // don't leave half-read units in the map if (!success) { UnloadUnit(name); } } return(su); }
// Undo previous method... public void DeleteLastObject(SerUnit into) { byref.Remove(into.bynum[--into.nobj]); into.bynum[into.nobj] = null; }