1 /*
2  * This file is part of DGD, https://github.com/dworkin/dgd
3  * Copyright (C) 1993-2010 Dworkin B.V.
4  * Copyright (C) 2010-2013 DGD Authors (see the commit log for details)
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as
8  * published by the Free Software Foundation, either version 3 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 # include "swap.h"
21 
22 typedef struct _svalue_ svalue;
23 
24 typedef struct {
25     uindex oindex;		/* inherited object */
26     uindex progoffset;		/* program offset */
27     uindex funcoffset;		/* function call offset */
28     unsigned short varoffset;	/* variable offset */
29     bool priv;			/* privately inherited? */
30 } dinherit;
31 
32 typedef struct {
33     Uint index;			/* index in control block */
34     ssizet len;			/* string length */
35 } dstrconst;
36 
37 # define DSTR_LAYOUT	"it"
38 
39 typedef struct _dfuncdef_ {
40     char class;			/* function class */
41     char inherit;		/* function name inherit index */
42     unsigned short index;	/* function name index */
43     Uint offset;		/* offset in program text */
44 } dfuncdef;
45 
46 # define DF_LAYOUT	"ccsi"
47 
48 typedef struct {
49     char class;			/* variable class */
50     char type;			/* variable type */
51     char inherit;		/* variable name inherit index */
52     unsigned short index;	/* variable name index */
53 } dvardef;
54 
55 # define DV_LAYOUT	"cccs"
56 
57 typedef struct {
58     char inherit;		/* function object index */
59     char index;			/* function index */
60     unsigned short next;	/* next in hash table */
61 } dsymbol;
62 
63 # define DSYM_LAYOUT	"ccs"
64 
65 struct _control_ {
66     control *prev, *next;
67     uindex ndata;		/* # of data blocks using this control block */
68 
69     sector nsectors;		/* o # of sectors */
70     sector *sectors;		/* o vector with sectors */
71 
72     uindex oindex;		/* i object */
73 
74     short flags;		/* various bitflags */
75 
76     short ninherits;		/* i/o # inherited objects */
77     dinherit *inherits;		/* i/o inherit objects */
78     short progindex;		/* i/o program index */
79 
80     uindex imapsz;		/* i/o inherit map size */
81     char *imap;			/* i/o inherit map */
82 
83     Uint compiled;		/* time of compilation */
84 
85     char *prog;			/* i program text */
86     Uint progsize;		/* i/o program text size */
87     Uint progoffset;		/* o program text offset */
88 
89     unsigned short nstrings;	/* i/o # strings */
90     string **strings;		/* i/o? string table */
91     dstrconst *sstrings;	/* o sstrings */
92     char *stext;		/* o sstrings text */
93     Uint strsize;		/* o sstrings text size */
94     Uint stroffset;		/* o offset of string index table */
95 
96     unsigned short nfuncdefs;	/* i/o # function definitions */
97     dfuncdef *funcdefs;		/* i/o? function definition table */
98     Uint funcdoffset;		/* o offset of function definition table */
99 
100     unsigned short nvardefs;	/* i/o # variable definitions */
101     unsigned short nclassvars;	/* i/o # class variable definitions */
102     dvardef *vardefs;		/* i/o? variable definitions */
103     string **cvstrings;		/* variable class strings */
104     char *classvars;		/* variable classes */
105     Uint vardoffset;		/* o offset of variable definition table */
106 
107     uindex nfuncalls;		/* i/o # function calls */
108     char *funcalls;		/* i/o? function calls */
109     Uint funccoffset;		/* o offset of function call table */
110 
111     unsigned short nsymbols;	/* i/o # symbols */
112     dsymbol *symbols;		/* i/o? symbol table */
113     Uint symboffset;		/* o offset of symbol table */
114 
115     unsigned short nvariables;	/* i/o # variables */
116     char *vtypes;		/* i/o? variable types */
117     Uint vtypeoffset;		/* o offset of variable types */
118 
119     unsigned short vmapsize;	/* i/o size of variable mapping */
120     unsigned short *vmap;	/* variable mapping */
121 };
122 
123 # define NEW_INT		((unsigned short) -1)
124 # define NEW_FLOAT		((unsigned short) -2)
125 # define NEW_POINTER		((unsigned short) -3)
126 # define NEW_VAR(x)		((x) >= NEW_POINTER)
127 
128 typedef struct _strref_ {
129     string *str;		/* string value */
130     dataspace *data;		/* dataspace this string is in */
131     Uint ref;			/* # of refs */
132 } strref;
133 
134 typedef struct _arrref_ {
135     array *arr;			/* array value */
136     dataplane *plane;		/* value plane this array is in */
137     dataspace *data;		/* dataspace this array is in */
138     short state;		/* state of mapping */
139     Uint ref;			/* # of refs */
140 } arrref;
141 
142 struct _value_ {
143     char type;			/* value type */
144     bool modified;		/* dirty bit */
145     uindex oindex;		/* index in object table */
146     union {
147 	Int number;		/* number */
148 	Uint objcnt;		/* object creation count */
149 	string *string;		/* string */
150 	array *array;		/* array or mapping */
151 	value *lval;		/* lvalue: variable */
152     } u;
153 };
154 
155 typedef struct {
156     Uint time;			/* time of call */
157     unsigned short mtime;	/* time of call milliseconds */
158     uindex nargs;		/* number of arguments */
159     value val[4];		/* function name, 3 direct arguments */
160 } dcallout;
161 
162 # define co_prev	time
163 # define co_next	nargs
164 
165 struct _dataplane_ {
166     Int level;			/* dataplane level */
167 
168     short flags;		/* modification flags */
169     long schange;		/* # string changes */
170     long achange;		/* # array changes */
171     long imports;		/* # array imports */
172 
173     value *original;		/* original variables */
174     arrref alocal;		/* primary of new local arrays */
175     arrref *arrays;		/* i/o? arrays */
176     abchunk *achunk;		/* chunk of array backup info */
177     strref *strings;		/* i/o? string constant table */
178     struct _coptable_ *coptab;	/* callout patch table */
179 
180     dataplane *prev;		/* previous in per-dataspace linked list */
181     dataplane *plist;		/* next in per-level linked list */
182 };
183 
184 struct _dataspace_ {
185     dataspace *prev, *next;	/* swap list */
186     dataspace *gcprev, *gcnext;	/* garbage collection list */
187 
188     dataspace *iprev;		/* previous in import list */
189     dataspace *inext;		/* next in import list */
190 
191     sector *sectors;		/* o vector of sectors */
192     sector nsectors;		/* o # sectors */
193 
194     short flags;		/* various bitflags */
195     control *ctrl;		/* control block */
196     uindex oindex;		/* object this dataspace belongs to */
197 
198     unsigned short nvariables;	/* o # variables */
199     value *variables;		/* i/o variables */
200     struct _svalue_ *svariables;/* o svariables */
201     Uint varoffset;		/* o offset of variables in data space */
202 
203     Uint narrays;		/* i/o # arrays */
204     Uint eltsize;		/* o total size of array elements */
205     struct _sarray_ *sarrays;	/* o sarrays */
206     struct _svalue_ *selts;	/* o sarray elements */
207     array alist;		/* array linked list sentinel */
208     Uint arroffset;		/* o offset of array table in data space */
209 
210     Uint nstrings;		/* i/o # strings */
211     Uint strsize;		/* o total size of string text */
212     struct _sstring_ *sstrings;	/* o sstrings */
213     char *stext;		/* o sstrings text */
214     Uint stroffset;		/* o offset of string table */
215 
216     uindex ncallouts;		/* # callouts */
217     uindex fcallouts;		/* free callout list */
218     dcallout *callouts;		/* callouts */
219     struct _scallout_ *scallouts; /* o scallouts */
220     Uint cooffset;		/* offset of callout table */
221 
222     dataplane base;		/* basic value plane */
223     dataplane *plane;		/* current value plane */
224 
225     struct _parser_ *parser;	/* parse_string data */
226 };
227 
228 # define THISPLANE(a)		((a)->plane == (a)->data->plane)
229 # define SAMEPLANE(d1, d2)	((d1)->plane->level == (d2)->plane->level)
230 
231 /* sdata.c */
232 
233 extern void		d_init		 (void);
234 extern void		d_init_conv	 (int, int, int, int, int, int, int,
235 					    int, int);
236 
237 extern control	       *d_new_control	 (void);
238 extern dataspace       *d_new_dataspace  (object*);
239 extern control	       *d_load_control	 (object*);
240 extern dataspace       *d_load_dataspace (object*);
241 extern void		d_ref_control	 (control*);
242 extern void		d_ref_dataspace  (dataspace*);
243 
244 extern char	       *d_get_prog	 (control*);
245 extern string	       *d_get_strconst	 (control*, int, unsigned int);
246 extern dfuncdef        *d_get_funcdefs	 (control*);
247 extern dvardef	       *d_get_vardefs	 (control*);
248 extern char	       *d_get_funcalls	 (control*);
249 extern dsymbol	       *d_get_symbols	 (control*);
250 extern Uint		d_get_progsize	 (control*);
251 
252 extern void		d_new_variables	 (control*, value*);
253 extern value	       *d_get_variable	 (dataspace*, unsigned int);
254 extern value	       *d_get_elts	 (array*);
255 extern void		d_get_callouts	 (dataspace*);
256 
257 extern sector		d_swapout	 (unsigned int);
258 extern void		d_upgrade_mem	 (object*, object*);
259 extern control	       *d_restore_ctrl	 (object*,
260 					  void(*)(char*, sector*, Uint, Uint));
261 extern dataspace       *d_restore_data	 (object*, Uint*, uindex,
262 					  void(*)(char*, sector*, Uint, Uint));
263 extern void		d_restore_obj	 (object*, Uint*, uindex, bool, bool);
264 extern void		d_converted	 (void);
265 
266 extern void		d_free_control	 (control*);
267 extern void		d_free_dataspace (dataspace*);
268 
269 /* data.c */
270 
271 extern void		d_new_plane	(dataspace*, Int);
272 extern void		d_commit_plane	(Int, value*);
273 extern void		d_discard_plane	(Int);
274 extern abchunk	      **d_commit_arr	(array*, dataplane*, dataplane*);
275 extern void		d_discard_arr	(array*, dataplane*);
276 
277 extern void		d_ref_imports	(array*);
278 extern void		d_assign_var	(dataspace*, value*, value*);
279 extern value	       *d_get_extravar	(dataspace*);
280 extern void		d_set_extravar	(dataspace*, value*);
281 extern void		d_wipe_extravar	(dataspace*);
282 extern void		d_assign_elt	(dataspace*, array*, value*, value*);
283 extern void		d_change_map	(array*);
284 
285 extern uindex		d_new_call_out	(dataspace*, string*, Int,
286 					   unsigned int, frame*, int);
287 extern Int		d_del_call_out	(dataspace*, Uint, unsigned short*);
288 extern string	       *d_get_call_out	(dataspace*, unsigned int, frame*,
289 					   int*);
290 extern array	       *d_list_callouts	(dataspace*, dataspace*);
291 
292 extern void		d_set_varmap	(control*, unsigned short*);
293 extern void		d_upgrade_data	(dataspace*, unsigned int,
294 					   unsigned short*, object*);
295 extern void		d_upgrade_clone	(dataspace*);
296 extern object	       *d_upgrade_lwobj	(array*, object*);
297 extern void		d_export	(void);
298 
299 extern void		d_del_control	(control*);
300 extern void		d_del_dataspace	(dataspace*);
301 
302 
303 /* bit values for ctrl->flags */
304 # define CTRL_PROGCMP		0x003	/* program compressed */
305 # define CTRL_STRCMP		0x00c	/* strings compressed */
306 # define CTRL_UNDEFINED		0x010	/* has undefined functions */
307 # define CTRL_COMPILED		0x020	/* precompiled control block */
308 # define CTRL_VARMAP		0x040	/* varmap updated */
309 # define CTRL_CONVERTED		0x080	/* converted control block */
310 # define CTRL_OLDVM		0x100	/* uses old VM */
311 
312 /* bit values for dataspace->flags */
313 # define DATA_STRCMP		0x03	/* strings compressed */
314 
315 /* bit values for dataspace->plane->flags */
316 # define MOD_ALL		0x3f
317 # define MOD_VARIABLE		0x01	/* variable changed */
318 # define MOD_ARRAY		0x02	/* array element changed */
319 # define MOD_ARRAYREF		0x04	/* array reference changed */
320 # define MOD_STRINGREF		0x08	/* string reference changed */
321 # define MOD_CALLOUT		0x10	/* callout changed */
322 # define MOD_NEWCALLOUT		0x20	/* new callout added */
323 # define PLANE_MERGE		0x40	/* merge planes on commit */
324 # define MOD_SAVE		0x80	/* save on next full swapout */
325 
326 /* data compression */
327 # define CMP_TYPE		0x03
328 # define CMP_NONE		0x00	/* no compression */
329 # define CMP_PRED		0x01	/* predictor compression */
330 
331 # define ARR_MOD		0x80000000L	/* in arrref->ref */
332 
333 # define AR_UNCHANGED		0	/* mapping unchanged */
334 # define AR_CHANGED		1	/* mapping changed */
335