Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 902 lines (782 sloc) 29.851 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;
ee02ddf @sorear Tweaks to allow saving and thawing cross-unit deep sub clones, such a…
authored
5 using System.Reflection;
d832c02 @sorear Second draft of serialization code
authored
6 using System.Text;
9083142 @sorear Switch to single-AppDomain execution
authored
7 using Niecza.CLRBackend;
8184302 @sorear Start draft of serialization/deserialization code
authored
8
cdde7e0 @sorear Notes on four kinds of module scope
authored
9 // Here in Niecza we have four different kinds of unit scopes:
10 //
11 // * COMPILING::UNIT, aka RuntimeUnit: one of these exists for every
12 // call into the compiler, whether eval or module. The REPL will
13 // be considered as if it were eval.
14 //
15 // * Serialization scopes, which are created when compiling modules
16 // or when pre-compiling a main program. During execution there is
17 // no current serialization scope; evals inherit the serialization
18 // scope or lack thereof that was in effect.
19 //
20 // * Assembly scopes, which are an artifact of the CLR and almost align
21 // with precompilation scopes, except that they have to exist always
22 // because methods cannot be created free-floating in CLR 2.x.
23 //
24 // An assembly scope is created for all serialization scopes, and
25 // non-saved anonymous assemblies are created for eval-and-run of
26 // a file and non-BEGIN-time evals.
27 //
28 // * GLOBAL scope is very much like serialization scope except that there
29 // is a "true globals" scope that is used when not serializing.
30
8184302 @sorear Start draft of serialization/deserialization code
authored
31 // This implements "bounded serialization" for Niecza. Unfortunately
32 // the CLR's builtin serialization can't efficiently be made bounded,
33 // and anyway it would be nice if the serialization format could be
34 // transported across backends.
35
36 // TODO: implement a more Storable-like interface.
d832c02 @sorear Second draft of serialization code
authored
37
38 // Note, the serialization subsystem is *NOT* thread safe !
8184302 @sorear Start draft of serialization/deserialization code
authored
39 namespace Niecza.Serialization {
d832c02 @sorear Second draft of serialization code
authored
40 // Information kept on a serialization unit after loading or storing,
41 // but not before storing.
42 class SerUnit {
43 internal string name; // eg "File.Copy"
44 internal byte[] hash; // hash of entire file, filled at write time
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
45 internal object[] bynum = new object[8]; // objects in unit
d832c02 @sorear Second draft of serialization code
authored
46 internal object root; // the RuntimeUnit object
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
47 internal int nobj; // = 0
69f2cee @sorear A scheme for serializing CLR wrappers (fixes #117)
authored
48
49 internal bool fake; // true for CLR reference units
d832c02 @sorear Second draft of serialization code
authored
50 }
8184302 @sorear Start draft of serialization/deserialization code
authored
51
52 // The central feature of *bounded* serialization is that object
53 // registries are kept distinct from the (de)serializer, and can
54 // be shared between serialization runs.
55 class ObjectRegistry {
d832c02 @sorear Second draft of serialization code
authored
56 // TODO: investigate a more specialized representation,
57 // ideally not having to hash as many objects
58 struct ObjRef {
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
59 public SerUnit unit;
60 public int id;
8184302 @sorear Start draft of serialization/deserialization code
authored
61 }
c80570d @sorear misc top removal: MakePair, LHF
authored
62 Compartment setting;
d832c02 @sorear Second draft of serialization code
authored
63 Dictionary<object,ObjRef> byref = new Dictionary<object,ObjRef>();
8184302 @sorear Start draft of serialization/deserialization code
authored
64
d832c02 @sorear Second draft of serialization code
authored
65 Dictionary<string,SerUnit> units =
66 new Dictionary<string,SerUnit>();
67
cdb4548 @sorear Checkpoint of global-variable inventory
authored
68 internal static HashAlgorithm NewHash() { return new SHA256Managed(); }
69
ee02ddf @sorear Tweaks to allow saving and thawing cross-unit deep sub clones, such a…
authored
70 internal Dictionary<string,Dictionary<string,MethodInfo>> methods =
71 new Dictionary<string,Dictionary<string,MethodInfo>>();
c592587 @sorear Change constant table to use instance fields
authored
72 internal Dictionary<string,object> instances =
73 new Dictionary<string,object>();
ee02ddf @sorear Tweaks to allow saving and thawing cross-unit deep sub clones, such a…
authored
74
d832c02 @sorear Second draft of serialization code
authored
75 static readonly string signature = "Niecza-Serialized-Module";
f43fe40 @sorear Top removal: iterators, variables, vivihooks
authored
76 static readonly int version = 31;
d832c02 @sorear Second draft of serialization code
authored
77
c80570d @sorear misc top removal: MakePair, LHF
authored
78 public ObjectRegistry(Compartment s) { setting = s; }
79
d832c02 @sorear Second draft of serialization code
authored
80 // Routines for use by serialization code
81 public bool CheckWriteObject(SerUnit into, object o,
82 out SerUnit lui, out int id) {
83 ObjRef or;
84 if (byref.TryGetValue(o, out or)) {
85 lui = or.unit;
86 id = or.id;
8184302 @sorear Start draft of serialization/deserialization code
authored
87 return true;
d832c02 @sorear Second draft of serialization code
authored
88 }
8184302 @sorear Start draft of serialization/deserialization code
authored
89
d832c02 @sorear Second draft of serialization code
authored
90 if (into.nobj == into.bynum.Length)
91 Array.Resize(ref into.bynum, into.nobj * 2);
8184302 @sorear Start draft of serialization/deserialization code
authored
92
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
93 or.unit = lui = into;
d832c02 @sorear Second draft of serialization code
authored
94 id = or.id = into.nobj++;
95 into.bynum[id] = o;
96
97 byref[o] = or;
8184302 @sorear Start draft of serialization/deserialization code
authored
98
99 return false;
100 }
d832c02 @sorear Second draft of serialization code
authored
101
54921c8 @sorear Prevent choking when trying to serialize a multi-dispatch cache
authored
102 // Undo previous method...
103 public void DeleteLastObject(SerUnit into) {
104 byref.Remove(into.bynum[--into.nobj]);
105 into.bynum[into.nobj] = null;
106 }
107
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
108 public void RegisterThawed(SerUnit into, object o) {
109 ObjRef or;
110 if (into.nobj == into.bynum.Length)
111 Array.Resize(ref into.bynum, into.nobj * 2);
112
113 or.unit = into;
114 or.id = into.nobj++;
115 into.bynum[or.id] = o;
116
117 byref[o] = or;
118 }
119
d832c02 @sorear Second draft of serialization code
authored
120 // Routines for use by compilation manager
69f2cee @sorear A scheme for serializing CLR wrappers (fixes #117)
authored
121 public void InstallFakeUnit(string name, params object[] items) {
122 SerUnit su = new SerUnit();
123 su.fake = true;
124 su.name = name;
125 su.bynum = items;
126 su.hash = new byte[0];
127 units[name] = su;
128
129 ObjRef or;
130 or.unit = su;
131 for (or.id = 0; or.id < items.Length; or.id++)
132 byref[items[or.id]] = or;
133 }
d832c02 @sorear Second draft of serialization code
authored
134
135 // Loads a single unit from the compiled-data directory.
136 // Will throw a ThawException if a stale reference is encountered
137 // or other data format error.
69f2cee @sorear A scheme for serializing CLR wrappers (fixes #117)
authored
138 public SerUnit LoadUnit(string name, bool fake = false) {
d832c02 @sorear Second draft of serialization code
authored
139 SerUnit su;
140
141 // is the unit already loaded?
142 if (units.TryGetValue(name, out su))
143 return su;
144
69f2cee @sorear A scheme for serializing CLR wrappers (fixes #117)
authored
145 if (fake) {
146 if (name.StartsWith("CLR,"))
c80570d @sorear misc top removal: MakePair, LHF
authored
147 CLRWrapperProvider.LoadWrapper(setting, name.Substring(4));
69f2cee @sorear A scheme for serializing CLR wrappers (fixes #117)
authored
148 else
149 throw new ThawException("No handler for fake unit name " + name);
150
151 return units[name];
152 }
153
9083142 @sorear Switch to single-AppDomain execution
authored
154 string file = Path.Combine(Backend.obj_dir, Backend.prefix +
155 name.Replace("::",".") + ".ser");
d832c02 @sorear Second draft of serialization code
authored
156 byte[] bytes = File.ReadAllBytes(file);
157
158 su = new SerUnit();
159 su.name = name;
cdb4548 @sorear Checkpoint of global-variable inventory
authored
160 su.hash = NewHash().ComputeHash(bytes);
d832c02 @sorear Second draft of serialization code
authored
161
c80570d @sorear misc top removal: MakePair, LHF
authored
162 ThawBuffer tb = new ThawBuffer(setting, this, su, bytes);
d832c02 @sorear Second draft of serialization code
authored
163
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
164 units[name] = su;
d832c02 @sorear Second draft of serialization code
authored
165 bool success = false;
166 try {
167 string rsig = tb.String();
168 if (rsig != signature)
169 throw new ThawException("signature mismatch loading " + file);
170 int rver = tb.Int();
171 if (rver != version)
172 throw new ThawException("version mismatch loading " + file);
173
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
174 su.root = tb.ObjRef();
c0af787 @sorear Fix fixup call order (oops!), serialization-compatible calling of pha…
authored
175 tb.RunFixups();
d832c02 @sorear Second draft of serialization code
authored
176 success = true;
177 } finally {
178 // don't leave half-read units in the map
179 if (!success)
180 UnloadUnit(name);
181 }
182
183 return su;
184 }
185
186 // removes a stale unit so a new version can be saved over it.
187 public void UnloadUnit(string name) {
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
188 if (!units.ContainsKey(name))
189 return;
d832c02 @sorear Second draft of serialization code
authored
190 SerUnit su = units[name];
191 units.Remove(name);
192
193 for (int i = 0; i < su.nobj; i++)
194 byref.Remove(su.bynum[i]);
195 }
196
197 public SerUnit SaveUnit(string name, IFreeze root) {
198 SerUnit su = new SerUnit();
199 su.name = name;
200 su.root = root;
201
202 if (units.ContainsKey(name))
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
203 throw new InvalidOperationException("unit " +name+ " exists");
d832c02 @sorear Second draft of serialization code
authored
204
205 bool success = false;
9083142 @sorear Switch to single-AppDomain execution
authored
206 string file = Path.Combine(Backend.obj_dir, Backend.prefix +
207 name.Replace("::",".") + ".ser");
d832c02 @sorear Second draft of serialization code
authored
208
209 FreezeBuffer fb = new FreezeBuffer(this, su);
210
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
211 units[name] = su;
212
d832c02 @sorear Second draft of serialization code
authored
213 try {
214 fb.String(signature);
215 fb.Int(version);
216 fb.ObjRef(root);
217
218 byte[] data = fb.GetData();
cdb4548 @sorear Checkpoint of global-variable inventory
authored
219 su.hash = NewHash().ComputeHash(data);
d832c02 @sorear Second draft of serialization code
authored
220 File.WriteAllBytes(file, data);
221 success = true;
222 } finally {
223 if (!success)
224 UnloadUnit(name);
225 }
226
227 return su;
228 }
8184302 @sorear Start draft of serialization/deserialization code
authored
229 }
230
231 // One of these codes is written at the beginning of every object ref
1993029 @sorear Start implementing serialization for our objects
authored
232 enum SerializationCode : byte {
d832c02 @sorear Second draft of serialization code
authored
233 // special
234 Null,
235
8184302 @sorear Start draft of serialization/deserialization code
authored
236 // existing objects
237 ForeignRef,
238 SelfRef,
239 NewUnitRef,
69f2cee @sorear A scheme for serializing CLR wrappers (fixes #117)
authored
240 FakeUnitRef,
1993029 @sorear Start implementing serialization for our objects
authored
241
242 // types of new object
243 RuntimeUnit,
244 SubInfo,
245 STable,
246 StashEnt,
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
247 Rat,
248 FatRat,
249 Complex,
250 BigInteger,
251 VarDeque,
252 VarHash,
dc6dd55 @sorear Implement serialization for Frame, finally kill off hashtable lexicals
authored
253 DispatchEnt,
254 RxFrame,
255 P6how,
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
256 ReflectObj,
7ae298f @sorear Make CC, LIHint serializable
authored
257 CC,
258 AltInfo,
10ba66d @sorear Turn Signatures into real objects
authored
259 Signature,
260 Parameter,
1993029 @sorear Start implementing serialization for our objects
authored
261
262 // types of P6any-reified object
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
263 P6opaque, // eventually let's specialize this
1993029 @sorear Start implementing serialization for our objects
authored
264 Frame,
265 Cursor,
266
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
267 // miscellany - keep these in same order as FallbackFreeze
268 String,
269 ArrP6any,
270 ArrVariable,
7ae298f @sorear Make CC, LIHint serializable
authored
271 ArrString,
272 ArrCC,
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
273 Boolean,
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
274 Int,
275 Double,
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
276 Type,
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
277
ab35238 @sorear Tidy up STable fields a bit, add TiedVariable serialize
authored
278 // variables
40e1779 @sorear Split ListVariable out of SimpleVariable
authored
279 RWVariable, // allow 2 for flag
280 RWVariable_1,
281 ListVariable,
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
282 SubstrLValue,
ab35238 @sorear Tidy up STable fields a bit, add TiedVariable serialize
authored
283 TiedVariable,
037f4b7 @sorear Make * a "blackhole" container that ignores writes
authored
284 Blackhole,
1993029 @sorear Start implementing serialization for our objects
authored
285
286 // vivification hooks
ab35238 @sorear Tidy up STable fields a bit, add TiedVariable serialize
authored
287 SubViviHook,
1993029 @sorear Start implementing serialization for our objects
authored
288 ArrayViviHook,
289 NewArrayViviHook,
290 HashViviHook,
291 NewHashViviHook,
b1088dc @sorear implement serialization for SubInfo, LAD, LexInfo
authored
292
293 // Longest-token automaton descriptors
294 LADNone, // no-args
295 LADNull,
296 LADDot,
297 LADDispatcher,
298 LADImp,
299 LADStr, // string
300 LADStrNoCase,
301 LADMethod,
302 LADParam,
b8a5ff0 @sorear Treat quantifiers as partially declarative whenever at all possible
authored
303 LADQuant, // byte,LAD,LAD
b1088dc @sorear implement serialization for SubInfo, LAD, LexInfo
authored
304 LADSequence, // LAD[]
305 LADAny,
306 LADCC, // CC
8184302 @sorear Start draft of serialization/deserialization code
authored
307 }
308
309 // An instance of this class is used to serialize serialization units
1993029 @sorear Start implementing serialization for our objects
authored
310 public class FreezeBuffer {
8184302 @sorear Start draft of serialization/deserialization code
authored
311 byte[] data;
312 int wpointer;
313
d832c02 @sorear Second draft of serialization code
authored
314 Dictionary<SerUnit,int> unit_to_offset;
315 int usedunits;
8184302 @sorear Start draft of serialization/deserialization code
authored
316
317 ObjectRegistry reg;
d832c02 @sorear Second draft of serialization code
authored
318 SerUnit unit;
8184302 @sorear Start draft of serialization/deserialization code
authored
319
d832c02 @sorear Second draft of serialization code
authored
320 internal FreezeBuffer(ObjectRegistry reg, SerUnit unit) {
8ed36ea @sorear Wire up serializer to run after pre-compiler
authored
321 if (reg == null || unit == null)
322 throw new ArgumentNullException();
8184302 @sorear Start draft of serialization/deserialization code
authored
323 this.reg = reg;
d832c02 @sorear Second draft of serialization code
authored
324 this.unit = unit;
325 unit_to_offset = new Dictionary<SerUnit,int>();
8184302 @sorear Start draft of serialization/deserialization code
authored
326 data = new byte[256];
327 }
328
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
329 internal byte[] GetData() {
330 byte[] ret = new byte[wpointer];
331 Array.Copy(data, ret, ret.Length);
332 return ret;
333 }
334
8184302 @sorear Start draft of serialization/deserialization code
authored
335 void Ensure(int ct) {
336 while (ct + wpointer > data.Length)
337 Array.Resize(ref data, data.Length * 2);
338 }
339
340 public void Byte(byte x) {
341 Ensure(1);
342 data[wpointer++] = x;
343 }
344
19ada5b @sorear Implement variable-length coding for serialization
authored
345 public void Long(long x) {
346 //Console.WriteLine("Saving {0} at {1}", x, wpointer);
347 Ensure(10);
348 while (true) {
349 if (x >= -64 && x <= 63) {
350 data[wpointer++] = (byte) (127 & (byte)x);
351 break;
352 } else {
353 data[wpointer++] = (byte) (128 | (byte)x);
354 x >>= 7;
355 }
356 }
8184302 @sorear Start draft of serialization/deserialization code
authored
357 }
358
19ada5b @sorear Implement variable-length coding for serialization
authored
359 public void ULong(ulong x) {
360 //Console.WriteLine("Saving {0} at {1}", x, wpointer);
361 Ensure(10);
362 while (true) {
363 if (x <= 127) {
364 data[wpointer++] = (byte) (127 & (byte)x);
365 break;
366 } else {
367 data[wpointer++] = (byte) (128 | (byte)x);
368 x >>= 7;
369 }
370 }
8184302 @sorear Start draft of serialization/deserialization code
authored
371 }
372
19ada5b @sorear Implement variable-length coding for serialization
authored
373 public void Short(short x) { Long(x); }
374 public void Int(int x) { Long(x); }
8184302 @sorear Start draft of serialization/deserialization code
authored
375
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
376 public void Double(double x) {
377 Long(BitConverter.DoubleToInt64Bits(x));
378 }
379
8184302 @sorear Start draft of serialization/deserialization code
authored
380 public void String(string s) {
381 if (s == null) {
382 Int(-1);
383 } else {
384 Int(s.Length);
385 foreach (char ch in s)
19ada5b @sorear Implement variable-length coding for serialization
authored
386 ULong((ulong)ch);
8184302 @sorear Start draft of serialization/deserialization code
authored
387 }
388 }
389
3dc4789 @sorear Implement freezing for types
authored
390 public void Strings(string[] s) {
391 if (s == null) Int(-1);
392 else {
393 Int(s.Length);
394 foreach (string ch in s) String(ch);
395 }
396 }
397
b1088dc @sorear implement serialization for SubInfo, LAD, LexInfo
authored
398 public void Ints(int[] s) {
399 if (s == null) {
400 Int(-1);
401 } else {
402 Int(s.Length);
403 foreach (int ch in s)
404 Int(ch);
405 }
406 }
407
dc6dd55 @sorear Implement serialization for Frame, finally kill off hashtable lexicals
authored
408 public void Refs<T> (T[] x) {
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
409 if (x == null) {
410 Int(-1);
411 } else {
412 Int(x.Length);
413 foreach (T y in x)
414 ObjRef(y);
415 }
416 }
417
dc6dd55 @sorear Implement serialization for Frame, finally kill off hashtable lexicals
authored
418 public void Refs<T> (IList<T> x) {
3dc4789 @sorear Implement freezing for types
authored
419 if (x == null) {
420 Int(-1);
421 } else {
422 Int(x.Count);
423 foreach (T y in x)
424 ObjRef(y);
425 }
426 }
427
54921c8 @sorear Prevent choking when trying to serialize a multi-dispatch cache
authored
428 public void Ephemeralize() {
429 Byte((byte)SerializationCode.Null);
430 reg.DeleteLastObject(unit);
431 }
432
d832c02 @sorear Second draft of serialization code
authored
433 // This is the main routine you should call from your Freeze
434 // callbacks to freeze an object
ff557f5 @sorear Usability improvements for NIECZA_SER_TRACE, indenting
authored
435 static int depth;
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
436 public void ObjRef(object o) {
d832c02 @sorear Second draft of serialization code
authored
437 int id;
438 SerUnit altunit;
ff557f5 @sorear Usability improvements for NIECZA_SER_TRACE, indenting
authored
439 if (Config.SerTrace) {
440 Console.WriteLine("{0}Saving {1} at {2}:", new string(' ',depth), o, wpointer);
441 }
442
d832c02 @sorear Second draft of serialization code
authored
443 if (o == null) { // null pointers are special
444 Byte((byte)SerializationCode.Null);
445 return;
446 }
447
448 if (reg.CheckWriteObject(unit, o, out altunit, out id)) {
8184302 @sorear Start draft of serialization/deserialization code
authored
449 if (altunit == unit) {
450 Byte((byte)SerializationCode.SelfRef);
451 } else {
d832c02 @sorear Second draft of serialization code
authored
452 int altcode;
453 if (!unit_to_offset.TryGetValue(altunit, out altcode)) {
69f2cee @sorear A scheme for serializing CLR wrappers (fixes #117)
authored
454 Byte(altunit.fake ?
455 (byte)SerializationCode.FakeUnitRef :
456 (byte)SerializationCode.NewUnitRef);
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
457 String(altunit.name);
d832c02 @sorear Second draft of serialization code
authored
458 // save the hash too so stale refs can be caught
459 foreach (byte b in altunit.hash) Byte(b);
460
8184302 @sorear Start draft of serialization/deserialization code
authored
461 unit_to_offset[altunit] = usedunits++;
462 } else {
463 Byte((byte)SerializationCode.ForeignRef);
d832c02 @sorear Second draft of serialization code
authored
464 Int(altcode);
8184302 @sorear Start draft of serialization/deserialization code
authored
465 }
466 }
467 Int((int)id);
468 } else {
d832c02 @sorear Second draft of serialization code
authored
469 // must take responsibility for saving the tag
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
470 IFreeze f = o as IFreeze;
ff557f5 @sorear Usability improvements for NIECZA_SER_TRACE, indenting
authored
471 if (Config.SerTrace) depth++;
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
472 if (f != null) {
473 f.Freeze(this);
474 } else {
475 FallbackFreeze(o);
476 }
ff557f5 @sorear Usability improvements for NIECZA_SER_TRACE, indenting
authored
477 if (Config.SerTrace) depth--;
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
478 }
479 }
480
cdb4548 @sorear Checkpoint of global-variable inventory
authored
481 [Immutable]
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
482 internal static Type[] boxTypes = new Type[] {
483 null, typeof(Rat), typeof(FatRat), typeof(Complex),
7ae298f @sorear Make CC, LIHint serializable
authored
484 typeof(double), typeof(int), typeof(string), typeof(VarHash),
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
485 typeof(Variable[]), typeof(VarDeque), typeof(STable),
eba5eb3 @sorear Take a first crack at implementing constant folding
authored
486 typeof(BigInteger),
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
487 };
cdb4548 @sorear Checkpoint of global-variable inventory
authored
488 [Immutable]
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
489 internal static Func<P6opaque>[] boxCreate = new Func<P6opaque>[] {
490 P6opaque.Create, BoxObject<Rat>.Create, BoxObject<FatRat>.Create,
491 BoxObject<Complex>.Create, BoxObject<double>.Create,
492 BoxObject<int>.Create, BoxObject<string>.Create,
19ada5b @sorear Implement variable-length coding for serialization
authored
493 BoxObject<VarHash>.Create, BoxObject<Variable[]>.Create,
494 BoxObject<VarDeque>.Create, BoxObject<STable>.Create,
eba5eb3 @sorear Take a first crack at implementing constant folding
authored
495 BoxObject<BigInteger>.Create,
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
496 };
cdb4548 @sorear Checkpoint of global-variable inventory
authored
497 [Immutable]
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
498 static Type[] anyTypes = new Type[] {
499 typeof(string), typeof(P6any[]), typeof(Variable[]),
7ae298f @sorear Make CC, LIHint serializable
authored
500 typeof(string[]), typeof(CC[]),
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
501 typeof(bool), typeof(int), typeof(double), typeof(Type),
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
502 };
503
504 void FallbackFreeze(object o) {
505 int ix = 0;
506 Type t = o.GetType();
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
507 while (ix != anyTypes.Length && anyTypes[ix] != t) ix++;
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
508 Byte((byte)(((int)SerializationCode.String) + ix));
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
509
510 switch(ix) {
511 case 0:
512 String((string)o);
513 break;
514 case 1:
515 Refs((P6any[])o);
516 break;
517 case 2:
518 Refs((Variable[])o);
519 break;
520 case 3:
7ae298f @sorear Make CC, LIHint serializable
authored
521 Refs((string[])o);
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
522 break;
523 case 4:
7ae298f @sorear Make CC, LIHint serializable
authored
524 Refs((CC[])o);
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
525 break;
526 case 5:
7ae298f @sorear Make CC, LIHint serializable
authored
527 Byte((byte)((bool)o ? 1 : 0));
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
528 break;
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
529 case 6:
7ae298f @sorear Make CC, LIHint serializable
authored
530 Int((int)o);
531 break;
532 case 7:
533 Double((double)o);
534 break;
535 case 8:
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
536 String(((Type)o).AssemblyQualifiedName);
537 break;
d91ecdf @sorear Serialization for objects of type Rat, FatRat, Complex, BigInteger, I…
authored
538 default:
539 throw new NotImplementedException(t.FullName);
8184302 @sorear Start draft of serialization/deserialization code
authored
540 }
541 }
542 }
543
544 // Note that this interface only handles freezing - thaw is done using
545 // a switch statement.
1993029 @sorear Start implementing serialization for our objects
authored
546 public interface IFreeze {
8184302 @sorear Start draft of serialization/deserialization code
authored
547 void Freeze(FreezeBuffer fb);
548 }
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
549 // implement this if you need to copy in data from other objects, &c
550 interface IFixup {
eafdf64 @sorear Top removal: Parameter & Signature
authored
551 void Fixup(Compartment c);
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
552 }
8184302 @sorear Start draft of serialization/deserialization code
authored
553
554 class ThawBuffer {
555 byte[] data;
556 int rpointer;
b344401 @sorear ThawBuffer knows its setting
authored
557 internal readonly ObjectRegistry reg;
558 internal readonly Compartment setting;
8184302 @sorear Start draft of serialization/deserialization code
authored
559
d832c02 @sorear Second draft of serialization code
authored
560 SerUnit[] unit_map = new SerUnit[8];
8184302 @sorear Start draft of serialization/deserialization code
authored
561 int refed_units;
d832c02 @sorear Second draft of serialization code
authored
562 SerUnit unit;
8184302 @sorear Start draft of serialization/deserialization code
authored
563
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
564 List<IFixup> fixups_needed = new List<IFixup>();
2ff6525 @sorear Thaw routines for types
authored
565 List<object> revalidate = new List<object>();
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
566
288db48 @sorear Use precompiled IL when using a precompiled module
authored
567 public Type type;
568
b344401 @sorear ThawBuffer knows its setting
authored
569 internal ThawBuffer(Compartment setting, ObjectRegistry reg, SerUnit unit, byte[] data) {
570 this.data = data;
571 this.setting = setting;
572 this.reg = reg;
573 this.unit = unit;
8184302 @sorear Start draft of serialization/deserialization code
authored
574 }
575
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
576 internal void RunFixups() {
2ff6525 @sorear Thaw routines for types
authored
577 P6how.BulkRevalidate(revalidate);
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
578 foreach (IFixup f in fixups_needed)
eafdf64 @sorear Top removal: Parameter & Signature
authored
579 f.Fixup(setting);
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
580 fixups_needed.Clear();
581 }
582
583 internal void PushFixup(IFixup f) {
584 fixups_needed.Add(f);
585 }
586
2ff6525 @sorear Thaw routines for types
authored
587 internal void PushRevalidate(STable f) {
588 revalidate.Add(f);
589 }
590
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
591 public byte Byte() { return data[rpointer++]; }
592
19ada5b @sorear Implement variable-length coding for serialization
authored
593 public long Long() {
594 int shift = 0;
595 long accum = 0;
596 while (true) {
597 byte b = Byte();
598 accum |= (((long)(b & 127)) << shift);
599 shift += 7;
600 if ((b & 128) == 0) {
3a82e24 @sorear Fix deserialization of 64-bit values between -2**62-1 and -2**63
authored
601 if ((b & 64) != 0 && shift < 64) {
19ada5b @sorear Implement variable-length coding for serialization
authored
602 accum |= ((-1L) << shift);
603 }
604 //Console.WriteLine("Read {0} end {1}", accum, rpointer);
605 return accum;
606 }
607 }
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
608 }
609
19ada5b @sorear Implement variable-length coding for serialization
authored
610 public ulong ULong() {
611 int shift = 0;
612 ulong accum = 0;
613 while (true) {
614 byte b = Byte();
615 accum |= (((ulong)(b & 127)) << shift);
616 shift += 7;
617 if ((b & 128) == 0) {
618 //Console.WriteLine("Read {0} end {1}", accum, rpointer);
619 return accum;
620 }
621 }
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
622 }
623
19ada5b @sorear Implement variable-length coding for serialization
authored
624 public short Short() {
625 return checked((short)Long());
626 }
627
628 public int Int() {
629 return checked((int)Long());
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
630 }
631
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
632 public double Double() {
633 return BitConverter.Int64BitsToDouble(Long());
634 }
635
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
636 public string String() {
637 int l = Int();
638
639 if (l < 0) return null;
640 char[] cb = new char[l];
641
642 for (int i = 0; i < l; i++)
19ada5b @sorear Implement variable-length coding for serialization
authored
643 cb[i] = (char)ULong();
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
644
645 return new string(cb);
646 }
647
648 public byte[] Bytes(int k) {
649 byte[] buf = new byte[k];
650
651 for (int i = 0; i < k; i++)
652 buf[i] = Byte();
653
654 return buf;
655 }
656
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
657 public List<T> RefsL<T>() where T : class {
658 int ct = Int();
659 if (ct < 0) return null;
660 List<T> ret = new List<T>();
661 for (int i = 0; i < ct; i++)
662 ret.Add((T) ObjRef());
663 return ret;
664 }
665
2ff6525 @sorear Thaw routines for types
authored
666 public int[] Ints() {
667 int ct = Int();
668 if (ct < 0) return null;
669 int[] ret = new int[ct];
670 for (int i = 0; i < ct; i++) ret[i] = Int();
671 return ret;
672 }
673
674 public string[] Strings() {
675 int ct = Int();
676 if (ct < 0) return null;
677 string[] ret = new string[ct];
678 for (int i = 0; i < ct; i++) ret[i] = String();
679 return ret;
680 }
681
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
682 public T[] RefsA<T>() where T : class {
683 int ct = Int();
684 if (ct < 0) return null;
685 T[] ret = new T[ct];
686 for (int i = 0; i < ct; i++)
687 ret[i] = (T) ObjRef();
688 return ret;
689 }
690
604037a @sorear Fix generic thawing of array objects
authored
691 // used from ObjRef only so guaranteed non-null
692 T[] RefsARegister<T>() where T : class {
693 int ct = Int();
694 T[] ret = new T[ct];
695 Register(ret);
696 for (int i = 0; i < ct; i++)
697 ret[i] = (T) ObjRef();
698 return ret;
699 }
700
b25256f @sorear Add Serialize.cs to build, fix build errors
authored
701 public object ObjRef() {
8184302 @sorear Start draft of serialization/deserialization code
authored
702 var tag = (SerializationCode)Byte();
19ada5b @sorear Implement variable-length coding for serialization
authored
703 if (Config.SerTrace)
704 Console.WriteLine("Reading {0} from {1}...", tag, rpointer-1);
8184302 @sorear Start draft of serialization/deserialization code
authored
705 int i, j;
706 switch(tag) {
d832c02 @sorear Second draft of serialization code
authored
707 case SerializationCode.Null:
708 return null;
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
709
8184302 @sorear Start draft of serialization/deserialization code
authored
710 case SerializationCode.ForeignRef:
711 i = Int();
712 j = Int();
d832c02 @sorear Second draft of serialization code
authored
713 return unit_map[i].bynum[j];
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
714 case SerializationCode.SelfRef:
715 i = Int();
716 return unit.bynum[i];
8184302 @sorear Start draft of serialization/deserialization code
authored
717 case SerializationCode.NewUnitRef:
69f2cee @sorear A scheme for serializing CLR wrappers (fixes #117)
authored
718 return LoadNewUnit(false);
719 case SerializationCode.FakeUnitRef:
720 return LoadNewUnit(true);
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
721
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
722 case SerializationCode.RuntimeUnit:
723 return RuntimeUnit.Thaw(this);
2671ab4 @sorear Add thaw routine for SubInfo
authored
724 case SerializationCode.SubInfo:
725 return SubInfo.Thaw(this);
2ff6525 @sorear Thaw routines for types
authored
726 case SerializationCode.STable:
727 return STable.Thaw(this);
fe6e595 @sorear Thaw for SimpleVariable, StashEnt
authored
728 case SerializationCode.StashEnt:
729 return StashEnt.Thaw(this);
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
730 case SerializationCode.Rat:
731 return Rat.Thaw(this);
732 case SerializationCode.FatRat:
733 return FatRat.Thaw(this);
734 case SerializationCode.Complex:
735 return Complex.Thaw(this);
736 case SerializationCode.BigInteger:
737 return BigInteger.Thaw(this);
738 case SerializationCode.VarDeque:
739 return VarDeque.Thaw(this);
740 case SerializationCode.VarHash:
741 return VarHash.Thaw(this);
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
742 case SerializationCode.DispatchEnt:
743 return DispatchEnt.Thaw(this);
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
744 //case SerializationCode.RxFrame:
745 // return RxFrame.Thaw(this);
2ff6525 @sorear Thaw routines for types
authored
746 case SerializationCode.P6how:
747 return P6how.Thaw(this);
7ae298f @sorear Make CC, LIHint serializable
authored
748 case SerializationCode.CC:
749 return CC.Thaw(this);
e7d3f3f @sorear Reimplement regex_infix:<|> table generation
authored
750 case SerializationCode.AltInfo:
751 return AltInfo.Thaw(this);
10ba66d @sorear Turn Signatures into real objects
authored
752 case SerializationCode.Signature:
753 return Signature.Thaw(this);
754 case SerializationCode.Parameter:
755 return Parameter.Thaw(this);
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
756
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
757 case SerializationCode.ReflectObj:
758 return ReflectObj.Thaw(this);
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
759 case SerializationCode.P6opaque:
760 return P6opaque.Thaw(this);
9b6504a @sorear Thaw routines for Frame
authored
761 case SerializationCode.Frame:
762 return Frame.Thaw(this);
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
763 //Cursor,
764
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
765 case SerializationCode.String:
766 return Register(String());
767 case SerializationCode.ArrP6any:
604037a @sorear Fix generic thawing of array objects
authored
768 return RefsARegister<P6any>();
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
769 case SerializationCode.ArrVariable:
604037a @sorear Fix generic thawing of array objects
authored
770 return RefsARegister<Variable>();
7ae298f @sorear Make CC, LIHint serializable
authored
771 case SerializationCode.ArrString:
604037a @sorear Fix generic thawing of array objects
authored
772 return RefsARegister<string>();
7ae298f @sorear Make CC, LIHint serializable
authored
773 case SerializationCode.ArrCC:
604037a @sorear Fix generic thawing of array objects
authored
774 return RefsARegister<CC>();
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
775 case SerializationCode.Boolean:
776 return Register(Byte() != 0);
777 case SerializationCode.Int:
778 return Register(Int());
779 case SerializationCode.Double:
780 return Register(Double());
781 case SerializationCode.Type:
782 return Register(Type.GetType(String(), true));
8035d26 @sorear Thaw code for VarDeque, VarHash, BigInteger, Complex, Rat, FatRat
authored
783
40e1779 @sorear Split ListVariable out of SimpleVariable
authored
784 case SerializationCode.ListVariable:
785 return ListVariable.Thaw(this);
786 case SerializationCode.RWVariable:
787 case SerializationCode.RWVariable_1:
788 return RWVariable.Thaw(this,
789 (int)tag - (int)SerializationCode.RWVariable);
054561b @sorear Thaw code for all LAD, Variable, ViviHook subclasses
authored
790 case SerializationCode.SubstrLValue:
791 return SubstrLValue.Thaw(this);
792 case SerializationCode.TiedVariable:
793 return TiedVariable.Thaw(this);
037f4b7 @sorear Make * a "blackhole" container that ignores writes
authored
794 case SerializationCode.Blackhole:
795 return Builtins.Blackhole.Thaw(this);
054561b @sorear Thaw code for all LAD, Variable, ViviHook subclasses
authored
796
797 case SerializationCode.SubViviHook:
798 return SubViviHook.Thaw(this);
799 case SerializationCode.ArrayViviHook:
800 return ArrayViviHook.Thaw(this);
801 case SerializationCode.NewArrayViviHook:
802 return NewArrayViviHook.Thaw(this);
803 case SerializationCode.HashViviHook:
804 return HashViviHook.Thaw(this);
805 case SerializationCode.NewHashViviHook:
806 return NewHashViviHook.Thaw(this);
807
808 case SerializationCode.LADNone:
809 return Register(new LADNone());
810 case SerializationCode.LADNull:
811 return Register(new LADNull());
812 case SerializationCode.LADDot:
813 return Register(new LADDot());
814 case SerializationCode.LADDispatcher:
815 return Register(new LADDispatcher());
816 case SerializationCode.LADImp:
817 return Register(new LADImp());
818 case SerializationCode.LADStr:
819 return LADStr.Thaw(this);
820 case SerializationCode.LADStrNoCase:
821 return LADStrNoCase.Thaw(this);
822 case SerializationCode.LADMethod:
823 return LADMethod.Thaw(this);
824 case SerializationCode.LADParam:
825 return LADParam.Thaw(this);
b8a5ff0 @sorear Treat quantifiers as partially declarative whenever at all possible
authored
826 case SerializationCode.LADQuant:
827 return LADQuant.Thaw(this);
054561b @sorear Thaw code for all LAD, Variable, ViviHook subclasses
authored
828 case SerializationCode.LADSequence:
829 return LADSequence.Thaw(this);
830 case SerializationCode.LADAny:
831 return LADAny.Thaw(this);
832 case SerializationCode.LADCC:
833 return LADCC.Thaw(this);
8184302 @sorear Start draft of serialization/deserialization code
authored
834 default:
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
835 throw new ThawException("unexpected object tag " + tag);
8184302 @sorear Start draft of serialization/deserialization code
authored
836 }
837 }
d832c02 @sorear Second draft of serialization code
authored
838
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
839 // call this when thawing any new object
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
840 internal object Register(object o) {
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
841 reg.RegisterThawed(unit, o);
be108f9 @sorear Thaw routines for P6opaque, DispatchEnt, double, int, Type, string, b…
authored
842 return o;
1c5bb04 @sorear Small refactor to AssemblyBuilder setup, start thaw coding
authored
843 }
844
69f2cee @sorear A scheme for serializing CLR wrappers (fixes #117)
authored
845 object LoadNewUnit(bool fake) {
d832c02 @sorear Second draft of serialization code
authored
846 string name = String();
847 if (refed_units == unit_map.Length)
848 Array.Resize(ref unit_map, refed_units * 2);
849
69f2cee @sorear A scheme for serializing CLR wrappers (fixes #117)
authored
850 SerUnit su = reg.LoadUnit(name, fake);
d832c02 @sorear Second draft of serialization code
authored
851 unit_map[refed_units++] = su;
852
853 byte[] hash = Bytes(su.hash.Length);
854
855 for (int i = 0; i < hash.Length; i++)
856 if (hash[i] != su.hash[i])
857 goto badhash;
858
859 int ix = Int();
860 return su.bynum[ix];
861
862 badhash:
eee0cbb @sorear Add framework for detecting stale precompiled modules
authored
863 throw new ThawException(string.Format("Hash mismatch for " +
864 "unit {0} referenced from {1}, wanted {2}, got {3}",
865 su.name, unit.name, Utils.HashToStr(unit.hash),
866 Utils.HashToStr(su.hash)));
d832c02 @sorear Second draft of serialization code
authored
867 }
868 }
869
870 // Thrown to indicate data format problems in the serialized stream
871 // Not necessarily bugs; could also indicate stale files, including
872 // cases where the data format is changed and cases where a depended
873 // file was recreated
874 class ThawException : Exception {
875 public ThawException(string s) : base(s) { }
876 public ThawException() : base() { }
8184302 @sorear Start draft of serialization/deserialization code
authored
877 }
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
878
879 public class ReflectObj : IFreeze {
3d9f4b4 @sorear ContextHandlers know their setting and do not need to use Top
authored
880 internal Compartment setting = Compartment.Top;
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
881 protected virtual object[] GetData() { return new object[0]; }
882 protected virtual void SetData(object[] a) { }
883 void IFreeze.Freeze(FreezeBuffer fb) {
884 fb.Byte((byte)SerializationCode.ReflectObj);
885 fb.String(GetType().AssemblyQualifiedName);
886 fb.Refs(GetData());
887 }
888
889 internal static ReflectObj Thaw(ThawBuffer tb) {
ead51d9 @sorear Skeleton of -gen-app; use named methods for builtin methods to reduce…
authored
890 string nm = tb.String();
891 if (Backend.cross_level_load)
892 nm = nm.Replace("Run.", "");
893 Type nt = Type.GetType(nm, true);
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
894 ReflectObj n = (ReflectObj)
f0788e8 @sorear Small bugfixes, use correct form of Invoke for .net
authored
895 nt.GetConstructor(new Type[0]).Invoke(new object[0]);
3f80fca @sorear A procedure for serializing ContextHandler et al
authored
896 tb.Register(n);
897 n.SetData(tb.RefsA<object>());
898 return n;
899 }
900 }
8184302 @sorear Start draft of serialization/deserialization code
authored
901 }
Something went wrong with that request. Please try again.