3a595d71319beecdb28cf81e2acbc94402f7a1d5
[fw/altos] / src / scheme / ao_scheme_save.c
1 /*
2  * Copyright © 2016 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14
15 #include "ao_scheme.h"
16
17 ao_poly
18 ao_scheme_do_save(struct ao_scheme_cons *cons)
19 {
20 #ifdef AO_SCHEME_SAVE
21         struct ao_scheme_os_save *os;
22 #endif
23
24         if (!ao_scheme_check_argc(_ao_scheme_atom_save, cons, 0, 0))
25                 return AO_SCHEME_NIL;
26
27 #ifdef AO_SCHEME_SAVE
28         os = (struct ao_scheme_os_save *) (void *) &ao_scheme_pool[AO_SCHEME_POOL];
29
30         ao_scheme_collect(AO_SCHEME_COLLECT_FULL);
31         os->atoms = ao_scheme_atom_poly(ao_scheme_atoms);
32         os->globals = ao_scheme_frame_poly(ao_scheme_frame_global);
33         os->const_checksum = ao_scheme_const_checksum;
34         os->const_checksum_inv = (uint16_t) ~ao_scheme_const_checksum;
35
36         if (ao_scheme_os_save())
37                 return _ao_scheme_bool_true;
38 #endif
39         return _ao_scheme_bool_false;
40 }
41
42 ao_poly
43 ao_scheme_do_restore(struct ao_scheme_cons *cons)
44 {
45 #ifdef AO_SCHEME_SAVE
46         struct ao_scheme_os_save save;
47         struct ao_scheme_os_save *os = (struct ao_scheme_os_save *) (void *) &ao_scheme_pool[AO_SCHEME_POOL];
48 #endif
49         if (!ao_scheme_check_argc(_ao_scheme_atom_save, cons, 0, 0))
50                 return AO_SCHEME_NIL;
51
52 #ifdef AO_SCHEME_SAVE
53         os = (struct ao_scheme_os_save *) (void *) &ao_scheme_pool[AO_SCHEME_POOL];
54
55         if (!ao_scheme_os_restore_save(&save, AO_SCHEME_POOL))
56                 return ao_scheme_error(AO_SCHEME_INVALID, "header restore failed");
57
58         if (save.const_checksum != ao_scheme_const_checksum ||
59             save.const_checksum_inv != (uint16_t) ~ao_scheme_const_checksum)
60         {
61                 return ao_scheme_error(AO_SCHEME_INVALID, "image is corrupted or stale");
62         }
63
64         if (ao_scheme_os_restore()) {
65
66                 ao_scheme_atoms = ao_scheme_poly_atom(os->atoms);
67                 ao_scheme_frame_global = ao_scheme_poly_frame(os->globals);
68
69                 /* Clear the eval global variabls */
70                 ao_scheme_eval_clear_globals();
71
72                 /* Reset the allocator */
73                 ao_scheme_top = AO_SCHEME_POOL;
74                 ao_scheme_collect(AO_SCHEME_COLLECT_FULL);
75
76                 /* Re-create the evaluator stack */
77                 if (!ao_scheme_eval_restart())
78                         return _ao_scheme_bool_false;
79
80                 return _ao_scheme_bool_true;
81         }
82 #endif
83         return _ao_scheme_bool_false;
84 }