Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 617 lines (521 sloc) 18.85 kb
8184302 @sorear Start draft of serialization/deserialization code
authored
1 using System;
d832c02 @sorear Second draft of serialization code
authored
2 using System.IO;
3 using System.Security.Cryptography;
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
4 using System.Collections.Generic;
d832c02 @sorear Second draft of serialization code
authored
5 using System.Text;
8184302 @sorear Start draft of serialization/deserialization code
authored
6
cdde7e0 @sorear Notes on four kinds of module scope
authored
7 // Here in Niecza we have four different kinds of unit scopes:
8 //
9 // * COMPILING::UNIT, aka RuntimeUnit: one of these exists for every
10 // call into the compiler, whether eval or module. The REPL will
11 // be considered as if it were eval.
12 //
13 // * Serialization scopes, which are created when compiling modules
14 // or when pre-compiling a main program. During execution there is
15 // no current serialization scope; evals inherit the serialization
16 // scope or lack thereof that was in effect.
17 //
18 // * Assembly scopes, which are an artifact of the CLR and almost align
19 // with precompilation scopes, except that they have to exist always
20 // because methods cannot be created free-floating in CLR 2.x.
21 //
22 // An assembly scope is created for all serialization scopes, and
23 // non-saved anonymous assemblies are created for eval-and-run of
24 // a file and non-BEGIN-time evals.
25 //
26 // * GLOBAL scope is very much like serialization scope except that there
27 // is a "true globals" scope that is used when not serializing.
28
8184302 @sorear Start draft of serialization/deserialization code
authored
29 // This implements "bounded serialization" for Niecza. Unfortunately
30 // the CLR's builtin serialization can't efficiently be made bounded,
31 // and anyway it would be nice if the serialization format could be
32 // transported across backends.
33
34 // TODO: implement a more Storable-like interface.
d832c02 @sorear Second draft of serialization code
authored
35
36 // Note, the serialization subsystem is *NOT* thread safe !
8184302 @sorear Start draft of serialization/deserialization code
authored
37 namespace Niecza.Serialization {
d832c02 @sorear Second draft of serialization code
authored
38 // Information kept on a serialization unit after loading or storing,
39 // but not before storing.
40 class SerUnit {
41 internal string name; // eg "File.Copy"
42 internal byte[] hash; // hash of entire file, filled at write time
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
43 internal object[] bynum = new object[8]; // objects in unit
d832c02 @sorear Second draft of serialization code
authored
44 internal object root; // the RuntimeUnit object
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
45 internal int nobj; // = 0
d832c02 @sorear Second draft of serialization code
authored
46 }
8184302 @sorear Start draft of serialization/deserialization code
authored
47
48 // The central feature of *bounded* serialization is that object
49 // registries are kept distinct from the (de)serializer, and can
50 // be shared between serialization runs.
51 class ObjectRegistry {
d832c02 @sorear Second draft of serialization code
authored
52 // TODO: investigate a more specialized representation,
53 // ideally not having to hash as many objects
54 struct ObjRef {
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
55 public SerUnit unit;
56 public int id;
8184302 @sorear Start draft of serialization/deserialization code
authored
57 }
d832c02 @sorear Second draft of serialization code
authored
58 Dictionary<object,ObjRef> byref = new Dictionary<object,ObjRef>();
8184302 @sorear Start draft of serialization/deserialization code
authored
59
d832c02 @sorear Second draft of serialization code
authored
60 Dictionary<string,SerUnit> units =
61 new Dictionary<string,SerUnit>();
62
63 static readonly HashAlgorithm hash = SHA256.Create();
64 static readonly string signature = "Niecza-Serialized-Module";
65 static readonly int version = 1;
66
67 // Routines for use by serialization code
68 public bool CheckWriteObject(SerUnit into, object o,
69 out SerUnit lui, out int id) {
70 ObjRef or;
71 if (byref.TryGetValue(o, out or)) {
72 lui = or.unit;
73 id = or.id;
8184302 @sorear Start draft of serialization/deserialization code
authored
74 return true;
d832c02 @sorear Second draft of serialization code
authored
75 }
8184302 @sorear Start draft of serialization/deserialization code
authored
76
d832c02 @sorear Second draft of serialization code
authored
77 if (into.nobj == into.bynum.Length)
78 Array.Resize(ref into.bynum, into.nobj * 2);
8184302 @sorear Start draft of serialization/deserialization code
authored
79
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
80 or.unit = lui = into;
d832c02 @sorear Second draft of serialization code
authored
81 id = or.id = into.nobj++;
82 into.bynum[id] = o;
83
84 byref[o] = or;
8184302 @sorear Start draft of serialization/deserialization code
authored
85
86 return false;
87 }
d832c02 @sorear Second draft of serialization code
authored
88
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
89 public void RegisterThawed(SerUnit into, object o) {
90 ObjRef or;
91 if (into.nobj == into.bynum.Length)
92 Array.Resize(ref into.bynum, into.nobj * 2);
93
94 or.unit = into;
95 or.id = into.nobj++;
96 into.bynum[or.id] = o;
97
98 byref[o] = or;
99 }
100
d832c02 @sorear Second draft of serialization code
authored
101 // Routines for use by compilation manager
102
103 // Loads a single unit from the compiled-data directory.
104 // Will throw a ThawException if a stale reference is encountered
105 // or other data format error.
106 public SerUnit LoadUnit(string name) {
107 SerUnit su;
108
109 // is the unit already loaded?
110 if (units.TryGetValue(name, out su))
111 return su;
112
113 string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
114 name + ".ser");
115 byte[] bytes = File.ReadAllBytes(file);
116
117 su = new SerUnit();
118 su.name = name;
119 su.hash = hash.ComputeHash(bytes);
120
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
121 ThawBuffer tb = new ThawBuffer(this, su, bytes);
d832c02 @sorear Second draft of serialization code
authored
122
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
123 units[name] = su;
d832c02 @sorear Second draft of serialization code
authored
124 bool success = false;
125 try {
126 string rsig = tb.String();
127 if (rsig != signature)
128 throw new ThawException("signature mismatch loading " + file);
129 int rver = tb.Int();
130 if (rver != version)
131 throw new ThawException("version mismatch loading " + file);
132
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
133 tb.RunFixups();
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
134 su.root = tb.ObjRef();
d832c02 @sorear Second draft of serialization code
authored
135 success = true;
136 } finally {
137 // don't leave half-read units in the map
138 if (!success)
139 UnloadUnit(name);
140 }
141
142 return su;
143 }
144
145 // removes a stale unit so a new version can be saved over it.
146 public void UnloadUnit(string name) {
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
147 if (!units.ContainsKey(name))
148 return;
d832c02 @sorear Second draft of serialization code
authored
149 SerUnit su = units[name];
150 units.Remove(name);
151
152 for (int i = 0; i < su.nobj; i++)
153 byref.Remove(su.bynum[i]);
154 }
155
156 public SerUnit SaveUnit(string name, IFreeze root) {
157 SerUnit su = new SerUnit();
158 su.name = name;
159 su.root = root;
160
161 if (units.ContainsKey(name))
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
162 throw new InvalidOperationException("unit " +name+ " exists");
d832c02 @sorear Second draft of serialization code
authored
163
164 bool success = false;
165 string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
166 name + ".ser");
167
168 FreezeBuffer fb = new FreezeBuffer(this, su);
169
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
170 units[name] = su;
171
d832c02 @sorear Second draft of serialization code
authored
172 try {
173 fb.String(signature);
174 fb.Int(version);
175 fb.ObjRef(root);
176
177 byte[] data = fb.GetData();
178 su.hash = hash.ComputeHash(data);
179 File.WriteAllBytes(file, data);
180 success = true;
181 } finally {
182 if (!success)
183 UnloadUnit(name);
184 }
185
186 return su;
187 }
8184302 @sorear Start draft of serialization/deserialization code
authored
188 }
189
190 // One of these codes is written at the beginning of every object ref
1993029 @sorear Start implementing serialization for our objects
authored
191 enum SerializationCode : byte {
d832c02 @sorear Second draft of serialization code
authored
192 // special
193 Null,
194
8184302 @sorear Start draft of serialization/deserialization code
authored
195 // existing objects
196 ForeignRef,
197 SelfRef,
198 NewUnitRef,
1993029 @sorear Start implementing serialization for our objects
authored
199
200 // types of new object
201 RuntimeUnit,
202 SubInfo,
203 STable,
204 StashEnt,
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, Int3...
authored
205 Rat,
206 FatRat,
207 Complex,
208 BigInteger,
209 VarDeque,
210 VarHash,
dc6dd55 @sorear Implement serialization for Frame, finally kill off hashtable lexicals
authored
211 DispatchEnt,
212 RxFrame,
213 P6how,
1993029 @sorear Start implementing serialization for our objects
authored
214
215 // types of P6any-reified object
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, Int3...
authored
216 P6opaque, // eventually let's specialize this
1993029 @sorear Start implementing serialization for our objects
authored
217 Frame,
218 Cursor,
219
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
220 // miscellany - keep these in same order as FallbackFreeze
221 String,
222 ArrP6any,
223 ArrVariable,
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
224 Boolean,
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
225 Int,
226 Double,
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, Int3...
authored
227
ab35238 @sorear Tidy up STable fields a bit, add TiedVariable serialize
authored
228 // variables
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
229 SimpleVariable, // allow 4 for flags
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
230 SimpleVariable_1,
231 SimpleVariable_2,
232 SimpleVariable_3,
233 SubstrLValue,
ab35238 @sorear Tidy up STable fields a bit, add TiedVariable serialize
authored
234 TiedVariable,
1993029 @sorear Start implementing serialization for our objects
authored
235
236 // vivification hooks
ab35238 @sorear Tidy up STable fields a bit, add TiedVariable serialize
authored
237 SubViviHook,
1993029 @sorear Start implementing serialization for our objects
authored
238 ArrayViviHook,
239 NewArrayViviHook,
240 HashViviHook,
241 NewHashViviHook,
b1088dc @sorear implement serialization for SubInfo, LAD, LexInfo
authored
242
243 // Longest-token automaton descriptors
244 LADNone, // no-args
245 LADNull,
246 LADDot,
247 LADDispatcher,
248 LADImp,
249 LADStr, // string
250 LADStrNoCase,
251 LADMethod,
252 LADParam,
253 LADOpt, // LAD
254 LADPlus,
255 LADStar,
256 LADSequence, // LAD[]
257 LADAny,
258 LADCC, // CC
8184302 @sorear Start draft of serialization/deserialization code
authored
259 }
260
261 // An instance of this class is used to serialize serialization units
1993029 @sorear Start implementing serialization for our objects
authored
262 public class FreezeBuffer {
8184302 @sorear Start draft of serialization/deserialization code
authored
263 byte[] data;
264 int wpointer;
265
d832c02 @sorear Second draft of serialization code
authored
266 Dictionary<SerUnit,int> unit_to_offset;
267 int usedunits;
8184302 @sorear Start draft of serialization/deserialization code
authored
268
269 ObjectRegistry reg;
d832c02 @sorear Second draft of serialization code
authored
270 SerUnit unit;
8184302 @sorear Start draft of serialization/deserialization code
authored
271
d832c02 @sorear Second draft of serialization code
authored
272 internal FreezeBuffer(ObjectRegistry reg, SerUnit unit) {
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
273 if (reg == null || unit == null)
274 throw new ArgumentNullException();
8184302 @sorear Start draft of serialization/deserialization code
authored
275 this.reg = reg;
d832c02 @sorear Second draft of serialization code
authored
276 this.unit = unit;
277 unit_to_offset = new Dictionary<SerUnit,int>();
8184302 @sorear Start draft of serialization/deserialization code
authored
278 data = new byte[256];
279 }
280
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
281 internal byte[] GetData() {
282 byte[] ret = new byte[wpointer];
283 Array.Copy(data, ret, ret.Length);
284 return ret;
285 }
286
8184302 @sorear Start draft of serialization/deserialization code
authored
287 void Ensure(int ct) {
288 while (ct + wpointer > data.Length)
289 Array.Resize(ref data, data.Length * 2);
290 }
291
292 public void Byte(byte x) {
293 Ensure(1);
294 data[wpointer++] = x;
295 }
296
297 public void Short(short x) {
298 Ensure(2);
299 data[wpointer++] = (byte)(x >> 8);
300 data[wpointer++] = (byte)(x );
301 }
302
303 public void Int(int x) {
304 Ensure(4);
305 data[wpointer++] = (byte)(x >> 24);
306 data[wpointer++] = (byte)(x >> 16);
307 data[wpointer++] = (byte)(x >> 8);
308 data[wpointer++] = (byte)(x );
309 }
310
311 public void Long(long x) {
312 Ensure(8);
313 data[wpointer++] = (byte)(x >> 56);
314 data[wpointer++] = (byte)(x >> 48);
315 data[wpointer++] = (byte)(x >> 40);
316 data[wpointer++] = (byte)(x >> 32);
317 data[wpointer++] = (byte)(x >> 24);
318 data[wpointer++] = (byte)(x >> 16);
319 data[wpointer++] = (byte)(x >> 8);
320 data[wpointer++] = (byte)(x );
321 }
322
323 public void String(string s) {
324 if (s == null) {
325 Int(-1);
326 } else {
327 Int(s.Length);
328 foreach (char ch in s)
329 Short((short)ch);
330 }
331 }
332
3dc4789 @sorear Implement freezing for types
authored
333 public void Strings(string[] s) {
334 if (s == null) Int(-1);
335 else {
336 Int(s.Length);
337 foreach (string ch in s) String(ch);
338 }
339 }
340
b1088dc @sorear implement serialization for SubInfo, LAD, LexInfo
authored
341 public void Ints(int[] s) {
342 if (s == null) {
343 Int(-1);
344 } else {
345 Int(s.Length);
346 foreach (int ch in s)
347 Int(ch);
348 }
349 }
350
dc6dd55 @sorear Implement serialization for Frame, finally kill off hashtable lexicals
authored
351 public void Refs<T> (T[] x) {
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, Int3...
authored
352 if (x == null) {
353 Int(-1);
354 } else {
355 Int(x.Length);
356 foreach (T y in x)
357 ObjRef(y);
358 }
359 }
360
dc6dd55 @sorear Implement serialization for Frame, finally kill off hashtable lexicals
authored
361 public void Refs<T> (IList<T> x) {
3dc4789 @sorear Implement freezing for types
authored
362 if (x == null) {
363 Int(-1);
364 } else {
365 Int(x.Count);
366 foreach (T y in x)
367 ObjRef(y);
368 }
369 }
370
d832c02 @sorear Second draft of serialization code
authored
371 // This is the main routine you should call from your Freeze
372 // callbacks to freeze an object
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, Int3...
authored
373 public void ObjRef(object o) {
d832c02 @sorear Second draft of serialization code
authored
374 int id;
375 SerUnit altunit;
376 if (o == null) { // null pointers are special
377 Byte((byte)SerializationCode.Null);
378 return;
379 }
380
381 if (reg.CheckWriteObject(unit, o, out altunit, out id)) {
8184302 @sorear Start draft of serialization/deserialization code
authored
382 if (altunit == unit) {
383 Byte((byte)SerializationCode.SelfRef);
384 } else {
d832c02 @sorear Second draft of serialization code
authored
385 int altcode;
386 if (!unit_to_offset.TryGetValue(altunit, out altcode)) {
8184302 @sorear Start draft of serialization/deserialization code
authored
387 Byte((byte)SerializationCode.NewUnitRef);
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
388 String(altunit.name);
d832c02 @sorear Second draft of serialization code
authored
389 // save the hash too so stale refs can be caught
390 foreach (byte b in altunit.hash) Byte(b);
391
8184302 @sorear Start draft of serialization/deserialization code
authored
392 unit_to_offset[altunit] = usedunits++;
393 } else {
394 Byte((byte)SerializationCode.ForeignRef);
d832c02 @sorear Second draft of serialization code
authored
395 Int(altcode);
8184302 @sorear Start draft of serialization/deserialization code
authored
396 }
397 }
398 Int((int)id);
399 } else {
d832c02 @sorear Second draft of serialization code
authored
400 // must take responsibility for saving the tag
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, Int3...
authored
401 IFreeze f = o as IFreeze;
402 if (f != null) {
403 f.Freeze(this);
404 } else {
405 FallbackFreeze(o);
406 }
407 }
408 }
409
410 static Type[] anyTypes = new Type[] {
411 typeof(string), typeof(P6any[]), typeof(Variable[]),
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
412 typeof(bool), typeof(int), typeof(double),
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, Int3...
authored
413 };
414
415 void FallbackFreeze(object o) {
416 int ix = 0;
417 Type t = o.GetType();
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
418 while (ix != anyTypes.Length && anyTypes[ix] != t) ix++;
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
419 Byte((byte)(((int)SerializationCode.String) + ix));
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, Int3...
authored
420
421 switch(ix) {
422 case 0:
423 String((string)o);
424 break;
425 case 1:
426 Refs((P6any[])o);
427 break;
428 case 2:
429 Refs((Variable[])o);
430 break;
431 case 3:
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
432 Byte((byte)((bool)o ? 1 : 0));
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, Int3...
authored
433 break;
434 case 4:
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
435 Int((int)o);
436 break;
437 case 5:
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, Int3...
authored
438 Long(BitConverter.DoubleToInt64Bits((double)o));
439 break;
440 default:
441 throw new NotImplementedException(t.FullName);
8184302 @sorear Start draft of serialization/deserialization code
authored
442 }
443 }
444 }
445
446 // Note that this interface only handles freezing - thaw is done using
447 // a switch statement.
1993029 @sorear Start implementing serialization for our objects
authored
448 public interface IFreeze {
8184302 @sorear Start draft of serialization/deserialization code
authored
449 void Freeze(FreezeBuffer fb);
450 }
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
451 // implement this if you need to copy in data from other objects, &c
452 interface IFixup {
453 void Fixup();
454 }
8184302 @sorear Start draft of serialization/deserialization code
authored
455
456 class ThawBuffer {
457 byte[] data;
458 int rpointer;
459 ObjectRegistry reg;
460
d832c02 @sorear Second draft of serialization code
authored
461 SerUnit[] unit_map = new SerUnit[8];
8184302 @sorear Start draft of serialization/deserialization code
authored
462 int refed_units;
d832c02 @sorear Second draft of serialization code
authored
463 SerUnit unit;
8184302 @sorear Start draft of serialization/deserialization code
authored
464
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
465 List<IFixup> fixups_needed = new List<IFixup>();
466
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
467 internal ThawBuffer(ObjectRegistry reg, SerUnit unit, byte[] data) {
8184302 @sorear Start draft of serialization/deserialization code
authored
468 this.data = data;
469 this.reg = reg;
d832c02 @sorear Second draft of serialization code
authored
470 this.unit = unit;
8184302 @sorear Start draft of serialization/deserialization code
authored
471 }
472
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
473 internal void RunFixups() {
474 foreach (IFixup f in fixups_needed)
475 f.Fixup();
476 fixups_needed.Clear();
477 }
478
479 internal void PushFixup(IFixup f) {
480 fixups_needed.Add(f);
481 }
482
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
483 public byte Byte() { return data[rpointer++]; }
484
485 public short Short() {
486 return (short)((((int)Byte()) << 8) | Byte());
487 }
488
489 public int Int() {
490 return (((int)Byte()) << 24) | (((int)Byte()) << 16) |
491 (((int)Byte()) << 8) | ((int)Byte());
492 }
493
494 public long Long() {
495 // try to do as much as possible in 32-bit precision,
496 // but suppress sign extension
497 return (((long)Int()) << 32) | (long)(uint)Int();
498 }
499
500 public string String() {
501 int l = Int();
502
503 if (l < 0) return null;
504 char[] cb = new char[l];
505
506 for (int i = 0; i < l; i++)
507 cb[i] = (char)Short();
508
509 return new string(cb);
510 }
511
512 public byte[] Bytes(int k) {
513 byte[] buf = new byte[k];
514
515 for (int i = 0; i < k; i++)
516 buf[i] = Byte();
517
518 return buf;
519 }
520
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
521 public List<T> RefsL<T>() where T : class {
522 int ct = Int();
523 if (ct < 0) return null;
524 List<T> ret = new List<T>();
525 for (int i = 0; i < ct; i++)
526 ret.Add((T) ObjRef());
527 return ret;
528 }
529
530 public T[] RefsA<T>() where T : class {
531 int ct = Int();
532 if (ct < 0) return null;
533 T[] ret = new T[ct];
534 for (int i = 0; i < ct; i++)
535 ret[i] = (T) ObjRef();
536 return ret;
537 }
538
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
539 public object ObjRef() {
8184302 @sorear Start draft of serialization/deserialization code
authored
540 var tag = (SerializationCode)Byte();
541 int i, j;
542 switch(tag) {
d832c02 @sorear Second draft of serialization code
authored
543 case SerializationCode.Null:
544 return null;
8184302 @sorear Start draft of serialization/deserialization code
authored
545 case SerializationCode.SelfRef:
546 i = Int();
d832c02 @sorear Second draft of serialization code
authored
547 return unit.bynum[i];
8184302 @sorear Start draft of serialization/deserialization code
authored
548 case SerializationCode.ForeignRef:
549 i = Int();
550 j = Int();
d832c02 @sorear Second draft of serialization code
authored
551 return unit_map[i].bynum[j];
8184302 @sorear Start draft of serialization/deserialization code
authored
552 case SerializationCode.NewUnitRef:
d832c02 @sorear Second draft of serialization code
authored
553 return LoadNewUnit();
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
554 case SerializationCode.RuntimeUnit:
555 return RuntimeUnit.Thaw(this);
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
556 case SerializationCode.StashEnt:
557 return StashEnt.Thaw(this);
558 case SerializationCode.SimpleVariable:
559 case SerializationCode.SimpleVariable_1:
560 case SerializationCode.SimpleVariable_2:
561 case SerializationCode.SimpleVariable_3:
562 return SimpleVariable.Thaw(this,
563 (int)tag - (int)SerializationCode.SimpleVariable);
8184302 @sorear Start draft of serialization/deserialization code
authored
564 default:
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
565 throw new ThawException("unexpected object tag " + tag);
8184302 @sorear Start draft of serialization/deserialization code
authored
566 }
567 }
d832c02 @sorear Second draft of serialization code
authored
568
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
569 // call this when thawing any new object
570 internal void Register(object o) {
571 reg.RegisterThawed(unit, o);
572 }
573
d832c02 @sorear Second draft of serialization code
authored
574 object LoadNewUnit() {
575 string name = String();
576 if (refed_units == unit_map.Length)
577 Array.Resize(ref unit_map, refed_units * 2);
578
579 SerUnit su = reg.LoadUnit(name);
580 unit_map[refed_units++] = su;
581
582 byte[] hash = Bytes(su.hash.Length);
583
584 for (int i = 0; i < hash.Length; i++)
585 if (hash[i] != su.hash[i])
586 goto badhash;
587
588 int ix = Int();
589 return su.bynum[ix];
590
591 badhash:
592 StringBuilder sb = new StringBuilder();
593 sb.AppendFormat("Hash mismatch for unit {0} referenced from {1}",
594 su.name, unit.name);
595
596 sb.Append(", wanted ");
597 foreach (byte b in hash)
598 sb.AppendFormat("{0:X2}", b);
599
600 sb.Append(", got ");
601 foreach (byte b in su.hash)
602 sb.AppendFormat("{0:X2}", b);
603
604 throw new ThawException(sb.ToString());
605 }
606 }
607
608 // Thrown to indicate data format problems in the serialized stream
609 // Not necessarily bugs; could also indicate stale files, including
610 // cases where the data format is changed and cases where a depended
611 // file was recreated
612 class ThawException : Exception {
613 public ThawException(string s) : base(s) { }
614 public ThawException() : base() { }
8184302 @sorear Start draft of serialization/deserialization code
authored
615 }
616 }
Something went wrong with that request. Please try again.