// 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); }
// 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); }