Skip to content
Newer
Older
100644 800 lines (692 sloc) 24.9 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
eee0cbb @sorear Add framework for detecting stale precompiled modules
authored
63 internal static readonly HashAlgorithm hash = SHA256.Create();
d832c02 @sorear Second draft of serialization code
authored
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
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
133 su.root = tb.ObjRef();
c0af787 @sorear Fix fixup call order (oops!), serialization-compatible calling of pha…
authored
134 tb.RunFixups();
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, I…
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,
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
214 ReflectObj,
7ae298f @sorear Make CC, LIHint serializable
authored
215 CC,
216 AltInfo,
1993029 @sorear Start implementing serialization for our objects
authored
217
218 // types of P6any-reified object
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
219 P6opaque, // eventually let's specialize this
1993029 @sorear Start implementing serialization for our objects
authored
220 Frame,
221 Cursor,
222
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
223 // miscellany - keep these in same order as FallbackFreeze
224 String,
225 ArrP6any,
226 ArrVariable,
7ae298f @sorear Make CC, LIHint serializable
authored
227 ArrString,
228 ArrCC,
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
229 Boolean,
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
230 Int,
231 Double,
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
232 Type,
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
233
ab35238 @sorear Tidy up STable fields a bit, add TiedVariable serialize
authored
234 // variables
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
235 SimpleVariable, // allow 4 for flags
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
236 SimpleVariable_1,
237 SimpleVariable_2,
238 SimpleVariable_3,
239 SubstrLValue,
ab35238 @sorear Tidy up STable fields a bit, add TiedVariable serialize
authored
240 TiedVariable,
1993029 @sorear Start implementing serialization for our objects
authored
241
242 // vivification hooks
ab35238 @sorear Tidy up STable fields a bit, add TiedVariable serialize
authored
243 SubViviHook,
1993029 @sorear Start implementing serialization for our objects
authored
244 ArrayViviHook,
245 NewArrayViviHook,
246 HashViviHook,
247 NewHashViviHook,
b1088dc @sorear implement serialization for SubInfo, LAD, LexInfo
authored
248
249 // Longest-token automaton descriptors
250 LADNone, // no-args
251 LADNull,
252 LADDot,
253 LADDispatcher,
254 LADImp,
255 LADStr, // string
256 LADStrNoCase,
257 LADMethod,
258 LADParam,
259 LADOpt, // LAD
260 LADPlus,
261 LADStar,
262 LADSequence, // LAD[]
263 LADAny,
264 LADCC, // CC
8184302 @sorear Start draft of serialization/deserialization code
authored
265 }
266
267 // An instance of this class is used to serialize serialization units
1993029 @sorear Start implementing serialization for our objects
authored
268 public class FreezeBuffer {
8184302 @sorear Start draft of serialization/deserialization code
authored
269 byte[] data;
270 int wpointer;
271
d832c02 @sorear Second draft of serialization code
authored
272 Dictionary<SerUnit,int> unit_to_offset;
273 int usedunits;
8184302 @sorear Start draft of serialization/deserialization code
authored
274
275 ObjectRegistry reg;
d832c02 @sorear Second draft of serialization code
authored
276 SerUnit unit;
8184302 @sorear Start draft of serialization/deserialization code
authored
277
d832c02 @sorear Second draft of serialization code
authored
278 internal FreezeBuffer(ObjectRegistry reg, SerUnit unit) {
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
279 if (reg == null || unit == null)
280 throw new ArgumentNullException();
8184302 @sorear Start draft of serialization/deserialization code
authored
281 this.reg = reg;
d832c02 @sorear Second draft of serialization code
authored
282 this.unit = unit;
283 unit_to_offset = new Dictionary<SerUnit,int>();
8184302 @sorear Start draft of serialization/deserialization code
authored
284 data = new byte[256];
285 }
286
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
287 internal byte[] GetData() {
288 byte[] ret = new byte[wpointer];
289 Array.Copy(data, ret, ret.Length);
290 return ret;
291 }
292
8184302 @sorear Start draft of serialization/deserialization code
authored
293 void Ensure(int ct) {
294 while (ct + wpointer > data.Length)
295 Array.Resize(ref data, data.Length * 2);
296 }
297
298 public void Byte(byte x) {
299 Ensure(1);
300 data[wpointer++] = x;
301 }
302
19ada5b @sorear Implement variable-length coding for serialization
authored
303 public void Long(long x) {
304 //Console.WriteLine("Saving {0} at {1}", x, wpointer);
305 Ensure(10);
306 while (true) {
307 if (x >= -64 && x <= 63) {
308 data[wpointer++] = (byte) (127 & (byte)x);
309 break;
310 } else {
311 data[wpointer++] = (byte) (128 | (byte)x);
312 x >>= 7;
313 }
314 }
8184302 @sorear Start draft of serialization/deserialization code
authored
315 }
316
19ada5b @sorear Implement variable-length coding for serialization
authored
317 public void ULong(ulong x) {
318 //Console.WriteLine("Saving {0} at {1}", x, wpointer);
319 Ensure(10);
320 while (true) {
321 if (x <= 127) {
322 data[wpointer++] = (byte) (127 & (byte)x);
323 break;
324 } else {
325 data[wpointer++] = (byte) (128 | (byte)x);
326 x >>= 7;
327 }
328 }
8184302 @sorear Start draft of serialization/deserialization code
authored
329 }
330
19ada5b @sorear Implement variable-length coding for serialization
authored
331 public void Short(short x) { Long(x); }
332 public void Int(int x) { Long(x); }
8184302 @sorear Start draft of serialization/deserialization code
authored
333
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
334 public void Double(double x) {
335 Long(BitConverter.DoubleToInt64Bits(x));
336 }
337
8184302 @sorear Start draft of serialization/deserialization code
authored
338 public void String(string s) {
339 if (s == null) {
340 Int(-1);
341 } else {
342 Int(s.Length);
343 foreach (char ch in s)
19ada5b @sorear Implement variable-length coding for serialization
authored
344 ULong((ulong)ch);
8184302 @sorear Start draft of serialization/deserialization code
authored
345 }
346 }
347
3dc4789 @sorear Implement freezing for types
authored
348 public void Strings(string[] s) {
349 if (s == null) Int(-1);
350 else {
351 Int(s.Length);
352 foreach (string ch in s) String(ch);
353 }
354 }
355
b1088dc @sorear implement serialization for SubInfo, LAD, LexInfo
authored
356 public void Ints(int[] s) {
357 if (s == null) {
358 Int(-1);
359 } else {
360 Int(s.Length);
361 foreach (int ch in s)
362 Int(ch);
363 }
364 }
365
dc6dd55 @sorear Implement serialization for Frame, finally kill off hashtable lexicals
authored
366 public void Refs<T> (T[] x) {
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
367 if (x == null) {
368 Int(-1);
369 } else {
370 Int(x.Length);
371 foreach (T y in x)
372 ObjRef(y);
373 }
374 }
375
dc6dd55 @sorear Implement serialization for Frame, finally kill off hashtable lexicals
authored
376 public void Refs<T> (IList<T> x) {
3dc4789 @sorear Implement freezing for types
authored
377 if (x == null) {
378 Int(-1);
379 } else {
380 Int(x.Count);
381 foreach (T y in x)
382 ObjRef(y);
383 }
384 }
385
d832c02 @sorear Second draft of serialization code
authored
386 // This is the main routine you should call from your Freeze
387 // callbacks to freeze an object
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
388 public void ObjRef(object o) {
d832c02 @sorear Second draft of serialization code
authored
389 int id;
390 SerUnit altunit;
19ada5b @sorear Implement variable-length coding for serialization
authored
391 if (Config.SerTrace)
392 Console.WriteLine("Saving {0} at {1}...", o, wpointer);
d832c02 @sorear Second draft of serialization code
authored
393 if (o == null) { // null pointers are special
394 Byte((byte)SerializationCode.Null);
395 return;
396 }
397
398 if (reg.CheckWriteObject(unit, o, out altunit, out id)) {
8184302 @sorear Start draft of serialization/deserialization code
authored
399 if (altunit == unit) {
400 Byte((byte)SerializationCode.SelfRef);
401 } else {
d832c02 @sorear Second draft of serialization code
authored
402 int altcode;
403 if (!unit_to_offset.TryGetValue(altunit, out altcode)) {
8184302 @sorear Start draft of serialization/deserialization code
authored
404 Byte((byte)SerializationCode.NewUnitRef);
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
405 String(altunit.name);
d832c02 @sorear Second draft of serialization code
authored
406 // save the hash too so stale refs can be caught
407 foreach (byte b in altunit.hash) Byte(b);
408
8184302 @sorear Start draft of serialization/deserialization code
authored
409 unit_to_offset[altunit] = usedunits++;
410 } else {
411 Byte((byte)SerializationCode.ForeignRef);
d832c02 @sorear Second draft of serialization code
authored
412 Int(altcode);
8184302 @sorear Start draft of serialization/deserialization code
authored
413 }
414 }
415 Int((int)id);
416 } else {
d832c02 @sorear Second draft of serialization code
authored
417 // must take responsibility for saving the tag
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
418 IFreeze f = o as IFreeze;
419 if (f != null) {
420 f.Freeze(this);
421 } else {
422 FallbackFreeze(o);
423 }
424 }
425 }
426
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
427 internal static Type[] boxTypes = new Type[] {
428 null, typeof(Rat), typeof(FatRat), typeof(Complex),
7ae298f @sorear Make CC, LIHint serializable
authored
429 typeof(double), typeof(int), typeof(string), typeof(VarHash),
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
430 typeof(Variable[]), typeof(VarDeque), typeof(STable),
431 };
432 internal static Func<P6opaque>[] boxCreate = new Func<P6opaque>[] {
433 P6opaque.Create, BoxObject<Rat>.Create, BoxObject<FatRat>.Create,
434 BoxObject<Complex>.Create, BoxObject<double>.Create,
435 BoxObject<int>.Create, BoxObject<string>.Create,
19ada5b @sorear Implement variable-length coding for serialization
authored
436 BoxObject<VarHash>.Create, BoxObject<Variable[]>.Create,
437 BoxObject<VarDeque>.Create, BoxObject<STable>.Create,
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
438 };
439
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
440 static Type[] anyTypes = new Type[] {
441 typeof(string), typeof(P6any[]), typeof(Variable[]),
7ae298f @sorear Make CC, LIHint serializable
authored
442 typeof(string[]), typeof(CC[]),
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
443 typeof(bool), typeof(int), typeof(double), typeof(Type),
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
444 };
445
446 void FallbackFreeze(object o) {
447 int ix = 0;
448 Type t = o.GetType();
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
449 while (ix != anyTypes.Length && anyTypes[ix] != t) ix++;
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
450 Byte((byte)(((int)SerializationCode.String) + ix));
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
451
452 switch(ix) {
453 case 0:
454 String((string)o);
455 break;
456 case 1:
457 Refs((P6any[])o);
458 break;
459 case 2:
460 Refs((Variable[])o);
461 break;
462 case 3:
7ae298f @sorear Make CC, LIHint serializable
authored
463 Refs((string[])o);
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
464 break;
465 case 4:
7ae298f @sorear Make CC, LIHint serializable
authored
466 Refs((CC[])o);
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
467 break;
468 case 5:
7ae298f @sorear Make CC, LIHint serializable
authored
469 Byte((byte)((bool)o ? 1 : 0));
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
470 break;
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
471 case 6:
7ae298f @sorear Make CC, LIHint serializable
authored
472 Int((int)o);
473 break;
474 case 7:
475 Double((double)o);
476 break;
477 case 8:
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
478 String(((Type)o).AssemblyQualifiedName);
479 break;
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
480 default:
481 throw new NotImplementedException(t.FullName);
8184302 @sorear Start draft of serialization/deserialization code
authored
482 }
483 }
484 }
485
486 // Note that this interface only handles freezing - thaw is done using
487 // a switch statement.
1993029 @sorear Start implementing serialization for our objects
authored
488 public interface IFreeze {
8184302 @sorear Start draft of serialization/deserialization code
authored
489 void Freeze(FreezeBuffer fb);
490 }
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
491 // implement this if you need to copy in data from other objects, &c
492 interface IFixup {
493 void Fixup();
494 }
8184302 @sorear Start draft of serialization/deserialization code
authored
495
496 class ThawBuffer {
497 byte[] data;
498 int rpointer;
499 ObjectRegistry reg;
500
d832c02 @sorear Second draft of serialization code
authored
501 SerUnit[] unit_map = new SerUnit[8];
8184302 @sorear Start draft of serialization/deserialization code
authored
502 int refed_units;
d832c02 @sorear Second draft of serialization code
authored
503 SerUnit unit;
8184302 @sorear Start draft of serialization/deserialization code
authored
504
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
505 List<IFixup> fixups_needed = new List<IFixup>();
2ff6525 @sorear Thaw routines for types
authored
506 List<object> revalidate = new List<object>();
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
507
288db48 @sorear Use precompiled IL when using a precompiled module
authored
508 public Type type;
509
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
510 internal ThawBuffer(ObjectRegistry reg, SerUnit unit, byte[] data) {
8184302 @sorear Start draft of serialization/deserialization code
authored
511 this.data = data;
512 this.reg = reg;
d832c02 @sorear Second draft of serialization code
authored
513 this.unit = unit;
8184302 @sorear Start draft of serialization/deserialization code
authored
514 }
515
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
516 internal void RunFixups() {
2ff6525 @sorear Thaw routines for types
authored
517 P6how.BulkRevalidate(revalidate);
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
518 foreach (IFixup f in fixups_needed)
519 f.Fixup();
520 fixups_needed.Clear();
521 }
522
523 internal void PushFixup(IFixup f) {
524 fixups_needed.Add(f);
525 }
526
2ff6525 @sorear Thaw routines for types
authored
527 internal void PushRevalidate(STable f) {
528 revalidate.Add(f);
529 }
530
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
531 public byte Byte() { return data[rpointer++]; }
532
19ada5b @sorear Implement variable-length coding for serialization
authored
533 public long Long() {
534 int shift = 0;
535 long accum = 0;
536 while (true) {
537 byte b = Byte();
538 accum |= (((long)(b & 127)) << shift);
539 shift += 7;
540 if ((b & 128) == 0) {
541 if ((b & 64) != 0) {
542 accum |= ((-1L) << shift);
543 }
544 //Console.WriteLine("Read {0} end {1}", accum, rpointer);
545 return accum;
546 }
547 }
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
548 }
549
19ada5b @sorear Implement variable-length coding for serialization
authored
550 public ulong ULong() {
551 int shift = 0;
552 ulong accum = 0;
553 while (true) {
554 byte b = Byte();
555 accum |= (((ulong)(b & 127)) << shift);
556 shift += 7;
557 if ((b & 128) == 0) {
558 //Console.WriteLine("Read {0} end {1}", accum, rpointer);
559 return accum;
560 }
561 }
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
562 }
563
19ada5b @sorear Implement variable-length coding for serialization
authored
564 public short Short() {
565 return checked((short)Long());
566 }
567
568 public int Int() {
569 return checked((int)Long());
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
570 }
571
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
572 public double Double() {
573 return BitConverter.Int64BitsToDouble(Long());
574 }
575
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
576 public string String() {
577 int l = Int();
578
579 if (l < 0) return null;
580 char[] cb = new char[l];
581
582 for (int i = 0; i < l; i++)
19ada5b @sorear Implement variable-length coding for serialization
authored
583 cb[i] = (char)ULong();
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
584
585 return new string(cb);
586 }
587
588 public byte[] Bytes(int k) {
589 byte[] buf = new byte[k];
590
591 for (int i = 0; i < k; i++)
592 buf[i] = Byte();
593
594 return buf;
595 }
596
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
597 public List<T> RefsL<T>() where T : class {
598 int ct = Int();
599 if (ct < 0) return null;
600 List<T> ret = new List<T>();
601 for (int i = 0; i < ct; i++)
602 ret.Add((T) ObjRef());
603 return ret;
604 }
605
2ff6525 @sorear Thaw routines for types
authored
606 public int[] Ints() {
607 int ct = Int();
608 if (ct < 0) return null;
609 int[] ret = new int[ct];
610 for (int i = 0; i < ct; i++) ret[i] = Int();
611 return ret;
612 }
613
614 public string[] Strings() {
615 int ct = Int();
616 if (ct < 0) return null;
617 string[] ret = new string[ct];
618 for (int i = 0; i < ct; i++) ret[i] = String();
619 return ret;
620 }
621
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
622 public T[] RefsA<T>() where T : class {
623 int ct = Int();
624 if (ct < 0) return null;
625 T[] ret = new T[ct];
626 for (int i = 0; i < ct; i++)
627 ret[i] = (T) ObjRef();
628 return ret;
629 }
630
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
631 public object ObjRef() {
8184302 @sorear Start draft of serialization/deserialization code
authored
632 var tag = (SerializationCode)Byte();
19ada5b @sorear Implement variable-length coding for serialization
authored
633 if (Config.SerTrace)
634 Console.WriteLine("Reading {0} from {1}...", tag, rpointer-1);
8184302 @sorear Start draft of serialization/deserialization code
authored
635 int i, j;
636 switch(tag) {
d832c02 @sorear Second draft of serialization code
authored
637 case SerializationCode.Null:
638 return null;
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
639
8184302 @sorear Start draft of serialization/deserialization code
authored
640 case SerializationCode.ForeignRef:
641 i = Int();
642 j = Int();
d832c02 @sorear Second draft of serialization code
authored
643 return unit_map[i].bynum[j];
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
644 case SerializationCode.SelfRef:
645 i = Int();
646 return unit.bynum[i];
8184302 @sorear Start draft of serialization/deserialization code
authored
647 case SerializationCode.NewUnitRef:
d832c02 @sorear Second draft of serialization code
authored
648 return LoadNewUnit();
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
649
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
650 case SerializationCode.RuntimeUnit:
651 return RuntimeUnit.Thaw(this);
2671ab4 @sorear Add thaw routine for SubInfo
authored
652 case SerializationCode.SubInfo:
653 return SubInfo.Thaw(this);
2ff6525 @sorear Thaw routines for types
authored
654 case SerializationCode.STable:
655 return STable.Thaw(this);
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
656 case SerializationCode.StashEnt:
657 return StashEnt.Thaw(this);
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
658 case SerializationCode.Rat:
659 return Rat.Thaw(this);
660 case SerializationCode.FatRat:
661 return FatRat.Thaw(this);
662 case SerializationCode.Complex:
663 return Complex.Thaw(this);
664 case SerializationCode.BigInteger:
665 return BigInteger.Thaw(this);
666 case SerializationCode.VarDeque:
667 return VarDeque.Thaw(this);
668 case SerializationCode.VarHash:
669 return VarHash.Thaw(this);
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
670 case SerializationCode.DispatchEnt:
671 return DispatchEnt.Thaw(this);
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
672 //case SerializationCode.RxFrame:
673 // return RxFrame.Thaw(this);
2ff6525 @sorear Thaw routines for types
authored
674 case SerializationCode.P6how:
675 return P6how.Thaw(this);
7ae298f @sorear Make CC, LIHint serializable
authored
676 case SerializationCode.CC:
677 return CC.Thaw(this);
678 //case SerializationCode.AltInfo:
679 // return AltInfo.Thaw(this);
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
680
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
681 case SerializationCode.ReflectObj:
682 return ReflectObj.Thaw(this);
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
683 case SerializationCode.P6opaque:
684 return P6opaque.Thaw(this);
9b6504a @sorear Thaw routines for Frame
authored
685 case SerializationCode.Frame:
686 return Frame.Thaw(this);
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
687 //Cursor,
688
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
689 case SerializationCode.String:
690 return Register(String());
691 case SerializationCode.ArrP6any:
692 return Register(RefsA<P6any>());
693 case SerializationCode.ArrVariable:
694 return Register(RefsA<Variable>());
7ae298f @sorear Make CC, LIHint serializable
authored
695 case SerializationCode.ArrString:
696 return Register(RefsA<string>());
697 case SerializationCode.ArrCC:
698 return Register(RefsA<CC>());
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
699 case SerializationCode.Boolean:
700 return Register(Byte() != 0);
701 case SerializationCode.Int:
702 return Register(Int());
703 case SerializationCode.Double:
704 return Register(Double());
705 case SerializationCode.Type:
706 return Register(Type.GetType(String(), true));
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
707
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
708 case SerializationCode.SimpleVariable:
709 case SerializationCode.SimpleVariable_1:
710 case SerializationCode.SimpleVariable_2:
711 case SerializationCode.SimpleVariable_3:
712 return SimpleVariable.Thaw(this,
713 (int)tag - (int)SerializationCode.SimpleVariable);
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
714 //SubstrLValue,
715 //TiedVariable,
716 //SubViviHook,
717 //ArrayViviHook,
718 //NewArrayViviHook,
719 //HashViviHook,
720 //NewHashViviHook,
721 //LADNone, // no-args
722 //LADNull,
723 //LADDot,
724 //LADDispatcher,
725 //LADImp,
726 //LADStr, // string
727 //LADStrNoCase,
728 //LADMethod,
729 //LADParam,
730 //LADOpt, // LAD
731 //LADPlus,
732 //LADStar,
733 //LADSequence, // LAD[]
734 //LADAny,
735 //LADCC, // CC
8184302 @sorear Start draft of serialization/deserialization code
authored
736 default:
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
737 throw new ThawException("unexpected object tag " + tag);
8184302 @sorear Start draft of serialization/deserialization code
authored
738 }
739 }
d832c02 @sorear Second draft of serialization code
authored
740
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
741 // call this when thawing any new object
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
742 internal object Register(object o) {
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
743 reg.RegisterThawed(unit, o);
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
744 return o;
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
745 }
746
d832c02 @sorear Second draft of serialization code
authored
747 object LoadNewUnit() {
748 string name = String();
749 if (refed_units == unit_map.Length)
750 Array.Resize(ref unit_map, refed_units * 2);
751
752 SerUnit su = reg.LoadUnit(name);
753 unit_map[refed_units++] = su;
754
755 byte[] hash = Bytes(su.hash.Length);
756
757 for (int i = 0; i < hash.Length; i++)
758 if (hash[i] != su.hash[i])
759 goto badhash;
760
761 int ix = Int();
762 return su.bynum[ix];
763
764 badhash:
eee0cbb @sorear Add framework for detecting stale precompiled modules
authored
765 throw new ThawException(string.Format("Hash mismatch for " +
766 "unit {0} referenced from {1}, wanted {2}, got {3}",
767 su.name, unit.name, Utils.HashToStr(unit.hash),
768 Utils.HashToStr(su.hash)));
d832c02 @sorear Second draft of serialization code
authored
769 }
770 }
771
772 // Thrown to indicate data format problems in the serialized stream
773 // Not necessarily bugs; could also indicate stale files, including
774 // cases where the data format is changed and cases where a depended
775 // file was recreated
776 class ThawException : Exception {
777 public ThawException(string s) : base(s) { }
778 public ThawException() : base() { }
8184302 @sorear Start draft of serialization/deserialization code
authored
779 }
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
780
781 public class ReflectObj : IFreeze {
782 protected virtual object[] GetData() { return new object[0]; }
783 protected virtual void SetData(object[] a) { }
784 void IFreeze.Freeze(FreezeBuffer fb) {
785 fb.Byte((byte)SerializationCode.ReflectObj);
786 fb.String(GetType().AssemblyQualifiedName);
787 fb.Refs(GetData());
788 }
789
790 internal static ReflectObj Thaw(ThawBuffer tb) {
791 Type nt = Type.GetType(tb.String());
792 ReflectObj n = (ReflectObj)
793 nt.GetConstructor(new Type[0]).Invoke(null, new object[0]);
794 tb.Register(n);
795 n.SetData(tb.RefsA<object>());
796 return n;
797 }
798 }
8184302 @sorear Start draft of serialization/deserialization code
authored
799 }
Something went wrong with that request. Please try again.