Imported Upstream version 0.2.0+beta
[debian/yforth] / vm.c
1 /* yForth? - A Forth interpreter written in ANSI C
2  * Copyright (C) 2012 Luca Padovani
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 3 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,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  * ------------------------------------------------------------------------
17  * Module name:     vm.c
18  * Abstract:        The Virtual Machine on which is based the whole
19  *                  forth interpreter.
20  */
21
22 #include <stdio.h>
23 #include <signal.h>
24 #include "yforth.h"
25 #include "core.h"
26
27 /* "ip" is the Instruction Pointer of the Virtual Machine. "ip" points to
28  * an array of "pfp", which stands for "primitive function pointer",
29  * in other words an array of pointers to primitive functions.
30  * Roughly speaking, primitive functions are the valid instructions of
31  * the Virtual Machine.
32  */
33
34 pfp *ip;                        /* Instruction Pointer */
35
36 Cell *sp, *sp_top, *sp_base;    /* various stack pointers... */
37 Cell *rp, *rp_top, *rp_base;
38 Real *fp, *fp_top, *fp_base;
39 Cell *bp;
40
41 #ifdef DCELL_MEM
42 static union double_cell dcell; /* Used for double-cell transfer */
43 #endif
44
45 /* stacks_recovery: called when an exception occurs, it sets all stack
46  * ptrs to their original value.
47  */
48 void 
49 stacks_recovery (void)
50 {
51   sp = sp_top;
52   rp = rp_top;
53   fp = fp_top;
54 }
55
56 /* If double-cell transfer is realized with memory-copying, the following
57  * auxiliary procedures are needed
58  */
59 #ifdef DCELL_MEM
60 DCell 
61 get_dcell (Cell * ptr)
62 {
63   dcell.d2.high = *ptr;
64   dcell.d2.low = *(ptr + 1);
65   return (dcell.d1);
66 }
67
68 void 
69 put_dcell (Cell * ptr, DCell d)
70 {
71   dcell.d1 = d;
72   *ptr = dcell.d2.high;
73   *(ptr + 1) = dcell.d2.low;
74 }
75 #endif
76
77 /* sig_fpe_handler: signal handler for math exceptions */
78 void 
79 sig_fpe_handler (int sig)
80 {
81   signal (SIGFPE, sig_fpe_handler);
82   _error = E_FPE;
83   _view_error_msg();
84   longjmp(warm_start_jump, 1);
85 }
86
87 /* sig_segv_handler: signal handler for segmentation violation */
88 void 
89 sig_segv_handler (int sig)
90 {
91   signal (SIGSEGV, sig_segv_handler);
92   _error = E_SEGV;
93   _view_error_msg();
94   longjmp(warm_start_jump, 1);
95 }
96
97 /* init_signal: initialize signal handlers */
98 void 
99 init_signals ()
100 {
101   signal (SIGFPE, sig_fpe_handler);
102   signal (SIGSEGV, sig_segv_handler);
103 }