Skip to content

HTTPS clone URL

Subversion checkout URL

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