Commit | Line | Data |
---|---|---|
a98cef7e KN |
1 | /* Copyright (C) 2000 Free Software Foundation, Inc. |
2 | * | |
3 | * This program is free software; you can redistribute it and/or modify | |
4 | * it under the terms of the GNU General Public License as published by | |
5 | * the Free Software Foundation; either version 2, or (at your option) | |
6 | * any later version. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU General Public License | |
14 | * along with this software; see the file COPYING. If not, write to | |
15 | * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |
16 | * Boston, MA 02111-1307 USA | |
17 | * | |
18 | * As a special exception, the Free Software Foundation gives permission | |
19 | * for additional uses of the text contained in its release of GUILE. | |
20 | * | |
21 | * The exception is that, if you link the GUILE library with other files | |
22 | * to produce an executable, this does not by itself cause the | |
23 | * resulting executable to be covered by the GNU General Public License. | |
24 | * Your use of that executable is in no way restricted on account of | |
25 | * linking the GUILE library code into it. | |
26 | * | |
27 | * This exception does not however invalidate any other reasons why | |
28 | * the executable file might be covered by the GNU General Public License. | |
29 | * | |
30 | * This exception applies only to the code released by the | |
31 | * Free Software Foundation under the name GUILE. If you copy | |
32 | * code from other Free Software Foundation releases into a copy of | |
33 | * GUILE, as the General Public License permits, the exception does | |
34 | * not apply to the code that you add in this way. To avoid misleading | |
35 | * anyone as to the status of such modified files, you must delete | |
36 | * this exception notice from them. | |
37 | * | |
38 | * If you write modifications of your own for GUILE, it is your choice | |
39 | * whether to permit this exception to apply to your modifications. | |
40 | * If you do not wish that, delete this exception notice. */ | |
41 | ||
42 | #ifndef VM_H | |
43 | #define VM_H | |
44 | ||
45 | #include <libguile.h> | |
46 | ||
47 | \f | |
48 | /* | |
49 | * Instruction | |
50 | */ | |
51 | ||
52 | /* Opcode */ | |
53 | enum scm_opcode { | |
54 | #include "vm_system.op" | |
55 | #include "vm_scheme.op" | |
56 | #include "vm_number.op" | |
57 | op_last | |
58 | }; | |
59 | ||
60 | /* Argument type */ | |
61 | /* Modify `mark_bytecode', `scm_make_bytecode', and `scm_bytecode_decode'! */ | |
62 | enum scm_inst_type { | |
63 | INST_NONE, /* no argument */ | |
64 | INST_INUM, /* fixed integer */ | |
65 | INST_SCM, /* scheme object */ | |
66 | INST_EXT, /* external offset */ | |
67 | INST_TOP, /* top-level variable */ | |
68 | INST_CODE, /* program code */ | |
69 | INST_ADDR /* program address */ | |
70 | }; | |
71 | ||
72 | struct scm_instruction { | |
73 | enum scm_opcode opcode; /* opcode */ | |
74 | enum scm_inst_type type; /* argument type */ | |
75 | char *name; /* instruction name */ | |
76 | void *addr; /* instruction address */ | |
77 | SCM obj; /* instruction object */ | |
78 | /* fields for VM functions */ | |
79 | char *sname; /* Scheme procedure name */ | |
80 | char nargs; /* the number of arguments */ | |
81 | char restp; /* have a rest argument or not */ | |
82 | }; | |
83 | ||
84 | #define SCM_INSTRUCTION_P(OBJ) SCM_SMOB_PREDICATE (scm_instruction_tag, OBJ) | |
85 | #define SCM_INSTRUCTION_DATA(INST) ((struct scm_instruction *) SCM_SMOB_DATA (INST)) | |
86 | #define SCM_VALIDATE_INSTRUCTION(POS,OBJ) SCM_MAKE_VALIDATE (POS, OBJ, INSTRUCTION_P) | |
87 | ||
88 | #define SCM_SYSTEM_INSTRUCTION_P(OBJ) \ | |
89 | (SCM_INSTRUCTION_P (OBJ) && !SCM_INSTRUCTION_DATA(OBJ)->sname) | |
90 | #define SCM_FUNCTIONAL_INSTRUCTION_P(OBJ) \ | |
91 | (SCM_INSTRUCTION_P (OBJ) && SCM_INSTRUCTION_DATA(OBJ)->sname) | |
92 | ||
93 | #define SCM_ADDR_TO_CODE(ADDR) SCM_PACK (ADDR) | |
94 | #define SCM_CODE_TO_ADDR(CODE) ((void *) SCM_UNPACK (CODE)) | |
95 | #define SCM_CODE_TO_DEBUG_ADDR(CODE) instruction_code_to_debug_addr (CODE) | |
96 | ||
97 | \f | |
98 | /* | |
99 | * Bytecode | |
100 | */ | |
101 | ||
102 | struct scm_bytecode { | |
103 | int size; /* the size of the bytecode */ | |
104 | char nreqs; /* the number of required arguments */ | |
105 | char restp; /* have a rest argument or not */ | |
106 | char nvars; /* the number of local variables */ | |
107 | char nexts; /* the number of external variables */ | |
108 | int *exts; /* externalized arguments */ | |
109 | SCM base[0]; /* base address (must be the last!) */ | |
110 | }; | |
111 | ||
112 | #define SCM_BYTECODE_P(OBJ) SCM_SMOB_PREDICATE (scm_bytecode_tag, OBJ) | |
113 | #define SCM_BYTECODE_DATA(BC) ((struct scm_bytecode *) SCM_SMOB_DATA (BC)) | |
114 | #define SCM_VALIDATE_BYTECODE(POS,OBJ) SCM_MAKE_VALIDATE (POS, OBJ, BYTECODE_P) | |
115 | ||
116 | #define SCM_BYTECODE_SIZE(BC) SCM_BYTECODE_DATA (BC)->size | |
117 | #define SCM_BYTECODE_NREQS(BC) SCM_BYTECODE_DATA (BC)->nreqs | |
118 | #define SCM_BYTECODE_RESTP(BC) SCM_BYTECODE_DATA (BC)->restp | |
119 | #define SCM_BYTECODE_NVARS(BC) SCM_BYTECODE_DATA (BC)->nvars | |
120 | #define SCM_BYTECODE_NEXTS(BC) SCM_BYTECODE_DATA (BC)->nexts | |
121 | #define SCM_BYTECODE_EXTS(BC) SCM_BYTECODE_DATA (BC)->exts | |
122 | #define SCM_BYTECODE_BASE(BC) SCM_BYTECODE_DATA (BC)->base | |
123 | ||
124 | extern SCM scm_bytecode_p (SCM obj); | |
125 | extern SCM scm_make_bytecode (SCM code); | |
126 | extern SCM scm_bytecode_decode (SCM bytecode); | |
127 | ||
128 | \f | |
129 | /* | |
130 | * Program | |
131 | */ | |
132 | ||
133 | #define SCM_MAKE_PROGRAM(CODE,ENV) make_program (CODE, ENV) | |
134 | #define SCM_PROGRAM_P(OBJ) SCM_SMOB_PREDICATE (scm_program_tag, OBJ) | |
135 | #define SCM_PROGRAM_CODE(PROG) SCM_CELL_OBJECT_1 (PROG) | |
136 | #define SCM_PROGRAM_ENV(PROG) SCM_CELL_OBJECT_2 (PROG) | |
137 | #define SCM_VALIDATE_PROGRAM(POS,PROG) SCM_MAKE_VALIDATE (POS, PROG, PROGRAM_P) | |
138 | ||
139 | /* Abbreviations */ | |
140 | #define SCM_PROGRAM_SIZE(PROG) SCM_BYTECODE_SIZE (SCM_PROGRAM_CODE (PROG)) | |
141 | #define SCM_PROGRAM_NREQS(PROG) SCM_BYTECODE_NREQS (SCM_PROGRAM_CODE (PROG)) | |
142 | #define SCM_PROGRAM_RESTP(PROG) SCM_BYTECODE_RESTP (SCM_PROGRAM_CODE (PROG)) | |
143 | #define SCM_PROGRAM_NVARS(PROG) SCM_BYTECODE_NVARS (SCM_PROGRAM_CODE (PROG)) | |
144 | #define SCM_PROGRAM_NEXTS(PROG) SCM_BYTECODE_NEXTS (SCM_PROGRAM_CODE (PROG)) | |
145 | #define SCM_PROGRAM_EXTS(PROG) SCM_BYTECODE_EXTS (SCM_PROGRAM_CODE (PROG)) | |
146 | #define SCM_PROGRAM_BASE(PROG) SCM_BYTECODE_BASE (SCM_PROGRAM_CODE (PROG)) | |
147 | ||
148 | extern SCM scm_program_p (SCM obj); | |
149 | extern SCM scm_make_program (SCM bytecode, SCM env); | |
150 | extern SCM scm_program_code (SCM program); | |
151 | extern SCM scm_program_base (SCM program); | |
152 | ||
153 | \f | |
154 | /* | |
155 | * VM Address | |
156 | */ | |
157 | ||
158 | #define SCM_VM_MAKE_ADDRESS(ADDR) SCM_MAKINUM ((long) (ADDR)) | |
159 | #define SCM_VM_ADDRESS(OBJ) ((SCM *) SCM_INUM (OBJ)) | |
160 | ||
161 | \f | |
162 | /* | |
163 | * VM External | |
164 | */ | |
165 | ||
166 | /* VM external maintains a set of variables outside of the stack. | |
167 | This is used to implement external chain of the environment. */ | |
168 | ||
169 | #define SCM_VM_MAKE_EXTERNAL(SIZE) scm_make_vector (SCM_MAKINUM ((SIZE) + 1), SCM_UNDEFINED) | |
170 | #define SCM_VM_EXTERNAL_LINK(EXT) (SCM_VELTS (EXT)[0]) | |
171 | #define SCM_VM_EXTERNAL_VARIABLE(EXT,N) (SCM_VELTS (EXT)[(N) + 1]) | |
172 | ||
173 | \f | |
174 | /* | |
175 | * VM Continuation | |
176 | */ | |
177 | ||
178 | #define SCM_VM_CONT_P(OBJ) SCM_SMOB_PREDICATE (scm_vm_cont_tag, OBJ) | |
179 | #define SCM_VM_CONT_VMP(CONT) ((struct scm_vm *) SCM_CELL_WORD_1 (CONT)) | |
180 | ||
181 | #define SCM_VM_CAPTURE_CONT(VMP) capture_vm_cont (VMP) | |
182 | #define SCM_VM_REINSTATE_CONT(VMP,CONT) reinstate_vm_cont (VMP, CONT) | |
183 | ||
184 | \f | |
185 | /* | |
186 | * VM Frame | |
187 | */ | |
188 | ||
189 | /* VM frame is allocated in the stack */ | |
190 | /* NOTE: Modify make_vm_frame and VM_NEW_FRAME too! */ | |
191 | #define SCM_VM_FRAME_DATA_SIZE 5 | |
192 | #define SCM_VM_FRAME_VARIABLE(FP,N) (FP[N]) | |
193 | #define SCM_VM_FRAME_SIZE(FP) (FP[-1]) | |
194 | #define SCM_VM_FRAME_PROGRAM(FP) (FP[-2]) | |
195 | #define SCM_VM_FRAME_DYNAMIC_LINK(FP) (FP[-3]) | |
196 | #define SCM_VM_FRAME_STACK_POINTER(FP) (FP[-4]) | |
197 | #define SCM_VM_FRAME_RETURN_ADDRESS(FP) (FP[-5]) | |
198 | ||
199 | \f | |
200 | /* | |
201 | * VM | |
202 | */ | |
203 | ||
204 | /* Modify make_vm, mark_vm, and SYNC, too! */ | |
205 | struct scm_vm { | |
206 | SCM ac; /* Accumulator */ | |
207 | SCM *pc; /* Program counter */ | |
208 | SCM *sp; /* Stack pointer */ | |
209 | SCM *fp; /* Frame pointer */ | |
210 | int stack_size; | |
211 | SCM *stack_base; | |
212 | SCM *stack_limit; | |
213 | SCM options; | |
214 | SCM boot_hook, halt_hook, next_hook; | |
215 | SCM call_hook, apply_hook, return_hook; | |
216 | }; | |
217 | ||
218 | #define SCM_VM_P(OBJ) SCM_SMOB_PREDICATE (scm_vm_tag, OBJ) | |
219 | #define SCM_VM_DATA(VM) ((struct scm_vm *) SCM_SMOB_DATA (VM)) | |
220 | #define SCM_VALIDATE_VM(POS,OBJ) SCM_MAKE_VALIDATE (POS, OBJ, VM_P) | |
221 | ||
222 | /* Engine types */ | |
223 | #define SCM_VM_REGULAR_ENGINE 0 /* Fail safe and fast enough */ | |
224 | #define SCM_VM_DEBUG_ENGINE 1 /* Functional but very slow */ | |
225 | ||
226 | #endif /* not VM_H */ |