altos/scheme: Add ports. Split scheme code up.
[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 #ifdef AO_SCHEME_FEATURE_SAVE
18 ao_poly
19 ao_scheme_do_save(struct ao_scheme_cons *cons)
20 {
21 #ifndef AO_SCHEME_MAKE_CONST
22         struct ao_scheme_os_save *os;
23
24         if (!ao_scheme_parse_args(_ao_scheme_atom_save, cons,
25                                   AO_SCHEME_ARG_END))
26                 return AO_SCHEME_NIL;
27
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 #else
39         (void) cons;
40 #endif
41         return _ao_scheme_bool_false;
42 }
43
44 ao_poly
45 ao_scheme_do_restore(struct ao_scheme_cons *cons)
46 {
47 #ifndef AO_SCHEME_MAKE_CONST
48         struct ao_scheme_os_save save;
49         struct ao_scheme_os_save *os = (struct ao_scheme_os_save *) (void *) &ao_scheme_pool[AO_SCHEME_POOL];
50         if (!ao_scheme_parse_args(_ao_scheme_atom_restore, cons,
51                                   AO_SCHEME_ARG_END))
52                 return AO_SCHEME_NIL;
53
54         os = (struct ao_scheme_os_save *) (void *) &ao_scheme_pool[AO_SCHEME_POOL];
55
56         if (!ao_scheme_os_restore_save(&save, AO_SCHEME_POOL))
57                 return ao_scheme_error(AO_SCHEME_INVALID, "header restore failed");
58
59         if (save.const_checksum != ao_scheme_const_checksum ||
60             save.const_checksum_inv != (uint16_t) ~ao_scheme_const_checksum)
61         {
62                 return ao_scheme_error(AO_SCHEME_INVALID, "image is corrupted or stale");
63         }
64
65         if (ao_scheme_os_restore()) {
66
67                 ao_scheme_atoms = ao_scheme_poly_atom(os->atoms);
68                 ao_scheme_frame_global = ao_scheme_poly_frame(os->globals);
69
70                 /* Clear the eval global variabls */
71                 ao_scheme_eval_clear_globals();
72
73                 /* Reset the allocator */
74                 ao_scheme_top = AO_SCHEME_POOL;
75                 ao_scheme_collect(AO_SCHEME_COLLECT_FULL);
76
77                 /* Re-create the evaluator stack */
78                 if (!ao_scheme_eval_restart())
79                         return _ao_scheme_bool_false;
80
81                 return _ao_scheme_bool_true;
82         }
83 #else
84         (void) cons;
85 #endif
86         return _ao_scheme_bool_false;
87 }
88
89 #endif /* AO_SCHEME_FEATURE_SAVE */