texdumpdata.h /size: 4723 b    last modification: 2024-01-16 10:22
1/*
2    See license.txt in the root of this project.
3*/
4
5# ifndef LMT_DUMPDATA_H
6# define LMT_DUMPDATA_H
7
8/*tex
9
10    Originally the dump file was a memory dump, in \TEX\ called a format and in \NETAFONT\ a base
11    and in \METAPOST\ a mem file. The \TEX\ program could reload that dump file and have a fast
12    start. In addition a pool file was used to store strings. Because it was a memory dump. It was
13    also pretty system dependent.
14
15    When \WEBC\ showed up, \TEX\ installations got distributed on \CDROM\ and later \DVD, and
16    because one could run them from that medium, format files were shared. In order to do that the
17    file had to be endian neutral. Unfortunately the choice was such that for the most commonly
18    architecture (intel) the dump items had to be swapped. This could slow down a startup, depending
19    on how rigourous a compiler of operating system was in testing (it is a reason why startup on
20    \MSWINDOWS\ was somewhat slower).
21
22    Because in \LUATEX\ we can also store \LUA\ bytecodes it made no sense to take that portability
23    aspect into account. The format file also got gzipped which at that time sped up loading. Later
24    in the project the endian swappign was removed so we gained a bit more.
25
26    Because a format file that doesn't match an engine can actually result in a crash, we decided to
27    come up with amore robust approach: we use a magic number to register the version of the format!
28    Normally this number only increments when we add a new primitive of change command codes. At
29    some point in \LUATEX\ development we started with 907 which is the sum of the values of the
30    bytes of \quote {don knuth}.
31
32    We sometimes also bump when the binary format (bytecode) of \LUA\ has changed in such a way that
33    the loader doesn't detect it. But that doesn't always help either because the cache is still
34    problematic then. There we actually hard code a different number then (a simple patch of a \LUA\
35    file).
36
37    By the time that the \LUAMETATEX\ code as in a state to be released, it became time to think
38    about a number that was definitely different from \LUATEX\ so here it is:
39
40    \starttyping
41    initial = 2020//4 - 2020//100 + 2020//400 = 490
42    \stoptyping
43
44    Although \LUAMETATEX\ is already a bit older, we sort of released in leapyear 2020 so we take
45    the number of leapyears since zero (which is kind of \type {\undefined} as starting point). This
46    number actually jumps whenever something affects the format file (which can be an extra command or
47    some reshuffling of codes) so it is not always an indication of something really need.
48
49    So to summarize: we don't share formats across architectures and operating systems, we use the
50    native endian property of an architecture, we don't compress, and we bump a magic number so that
51    we can intercept a potential crash. So much for a bit of history.
52
53    We also bump the fingerprint when we have a new version of \LUA, just to play safe in case some 
54    bytecodes have changed. 
55
56*/
57
58# define luametatex_format_fingerprint 698
59
60/* These end up in the string pool. */
61
62typedef struct dump_state_info {
63    int fingerprint;
64    int padding;
65} dump_state_info;
66
67extern dump_state_info lmt_dump_state;
68
69extern void tex_store_fmt_file         (void);
70extern int  tex_load_fmt_file          (void);
71extern int  tex_fatal_undump_error     (const char *s);
72extern void tex_initialize_dump_state  (void);
73
74//define   dump_items(f,p,item_size,nitems)       fwrite((void *) p, (size_t) item_size, (size_t) nitems, f)
75//define undump_items(f,p,item_size,nitems) { if (fread ((void *) p, (size_t) item_size, (size_t) nitems, f)) { } }
76
77# define   dump_items(f,p,item_size,nitems) fwrite((void *) p, (size_t) item_size, (size_t) nitems, f)
78# define undump_items(f,p,item_size,nitems) fread ((void *) p, (size_t) item_size, (size_t) nitems, f)
79
80# define   dump_things(f,base,len)   dump_items(f, (char *) &(base), sizeof (base), (int) (len))
81# define undump_things(f,base,len) undump_items(f, (char *) &(base), sizeof (base), (int) (len))
82
83# define   dump_int(f,x)   dump_things(f,x,1)
84# define undump_int(f,x) undump_things(f,x,1)
85
86/*tex
87
88    Because sometimes we dump constants or the result of a function call we have |dump_via_int|
89    that puts the number into a variable first. Most integers come from structs and arrays.
90    Performance wise there is not that much gain.
91
92*/
93
94# define dump_via_int(f,x) do { \
95    int x_val = (x); \
96    dump_int(f,x_val); \
97} while (0)
98
99# define dump_string(f,a) \
100    if (a) { \
101        int x = (int)strlen(a) + 1; \
102        dump_int(f,x); \
103        dump_things(f,*a, x); \
104    } else { \
105        dump_via_int(f,0); \
106    }
107
108# endif
109