示例#1
0
        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)));
        }
示例#2
0
        // 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);
        }
示例#3
0
 internal ThawBuffer(Compartment setting, ObjectRegistry reg, SerUnit unit, byte[] data)
 {
     this.data    = data;
     this.setting = setting;
     this.reg     = reg;
     this.unit    = unit;
 }
示例#4
0
 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];
 }
示例#5
0
        // 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);
        }
示例#6
0
        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;
        }
示例#7
0
        // 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]);
            }
        }
示例#8
0
        // 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;
            }
        }
示例#9
0
        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);
        }
示例#10
0
 internal ThawBuffer(ObjectRegistry reg, SerUnit unit, byte[] data)
 {
     this.data = data;
     this.reg  = reg;
     this.unit = unit;
 }
示例#11
0
        // 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);
        }
示例#12
0
 // Undo previous method...
 public void DeleteLastObject(SerUnit into)
 {
     byref.Remove(into.bynum[--into.nobj]);
     into.bynum[into.nobj] = null;
 }