scm_call_N doesn't cons for calling programs
[bpt/guile.git] / libguile / vm-engine.c
CommitLineData
8f5cfc81 1/* Copyright (C) 2001 Free Software Foundation, Inc.
a98cef7e
KN
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
6d14383e
AW
42/* This file is included in vm.c multiple times */
43
44#if (VM_ENGINE == SCM_VM_REGULAR_ENGINE)
45#define VM_USE_HOOKS 0 /* Various hooks */
46#define VM_USE_CLOCK 0 /* Bogoclock */
47#define VM_CHECK_EXTERNAL 1 /* Check external link */
48#define VM_CHECK_OBJECT 1 /* Check object table */
49#elif (VM_ENGINE == SCM_VM_DEBUG_ENGINE)
50#define VM_USE_HOOKS 1
51#define VM_USE_CLOCK 1
52#define VM_CHECK_EXTERNAL 1
53#define VM_CHECK_OBJECT 1
54#else
55#error unknown debug engine VM_ENGINE
56#endif
a98cef7e 57
83495480 58#include "vm-engine.h"
a98cef7e 59
238e7a11 60
a98cef7e 61static SCM
6d14383e 62VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int nargs)
a98cef7e 63{
17e90c5e
KN
64 /* VM registers */
65 register scm_byte_t *ip IP_REG; /* instruction pointer */
66 register SCM *sp SP_REG; /* stack pointer */
67 register SCM *fp FP_REG; /* frame pointer */
a98cef7e 68
d608d68d 69 /* Cache variables */
53e28ed9 70 struct scm_objcode *bp = NULL; /* program base pointer */
41f248a8 71 SCM external = SCM_EOL; /* external environment */
17e90c5e 72 SCM *objects = NULL; /* constant objects */
2fda0242 73 size_t object_count = 0; /* length of OBJECTS */
3d5ee0cd
KN
74 SCM *stack_base = vp->stack_base; /* stack base address */
75 SCM *stack_limit = vp->stack_limit; /* stack limit address */
a98cef7e 76
d608d68d 77 /* Internal variables */
ef24c01b 78 int nvalues = 0;
3d5ee0cd 79 long start_time = scm_c_get_internal_run_time ();
17e90c5e
KN
80 SCM err_msg;
81 SCM err_args;
82#if VM_USE_HOOKS
6d14383e 83 SCM hook_args = SCM_EOL;
a98cef7e 84#endif
17d1b4bf 85
53e28ed9
AW
86#ifdef HAVE_LABELS_AS_VALUES
87 static void **jump_table = NULL;
88
89 if (SCM_UNLIKELY (!jump_table))
90 {
91 int i;
f775e51b 92 jump_table = malloc (SCM_VM_NUM_INSTRUCTIONS * sizeof(void*));
53e28ed9
AW
93 for (i = 0; i < SCM_VM_NUM_INSTRUCTIONS; i++)
94 jump_table[i] = &&vm_error_bad_instruction;
95#define VM_INSTRUCTION_TO_LABEL 1
96#include "vm-expand.h"
97#include "vm-i-system.i"
98#include "vm-i-scheme.i"
99#include "vm-i-loader.i"
100#undef VM_INSTRUCTION_TO_LABEL
101 }
102#endif
103
3d5ee0cd
KN
104 /* Initialization */
105 {
499a4c07
KN
106 SCM prog = program;
107
108 /* Boot program */
6d14383e 109 program = vm_make_boot_program (nargs);
a98cef7e 110
3d5ee0cd
KN
111 /* Initial frame */
112 CACHE_REGISTER ();
499a4c07 113 CACHE_PROGRAM ();
3616e9e9 114 PUSH (program);
3d5ee0cd 115 NEW_FRAME ();
17e90c5e 116
3d5ee0cd 117 /* Initial arguments */
3616e9e9 118 PUSH (prog);
6d14383e
AW
119 if (SCM_UNLIKELY (sp + nargs >= stack_limit))
120 goto vm_error_too_many_args;
121 while (nargs--)
122 PUSH (*argv++);
3d5ee0cd 123 }
a98cef7e
KN
124
125 /* Let's go! */
17e90c5e 126 BOOT_HOOK ();
53e28ed9 127 NEXT;
a98cef7e
KN
128
129#ifndef HAVE_LABELS_AS_VALUES
17e90c5e 130 vm_start:
53e28ed9 131 switch ((*ip++) & SCM_VM_INSTRUCTION_MASK) {
a98cef7e
KN
132#endif
133
83495480
AW
134#include "vm-expand.h"
135#include "vm-i-system.c"
136#include "vm-i-scheme.c"
137#include "vm-i-loader.c"
a98cef7e
KN
138
139#ifndef HAVE_LABELS_AS_VALUES
53e28ed9
AW
140 default:
141 goto vm_error_bad_instruction;
a98cef7e
KN
142 }
143#endif
144
17e90c5e
KN
145 /* Errors */
146 {
53e28ed9
AW
147 vm_error_bad_instruction:
148 err_msg = scm_from_locale_string ("VM: Bad instruction: ~A");
149 err_args = SCM_LIST1 (scm_from_uchar (ip[-1]));
150 goto vm_error;
151
17e90c5e 152 vm_error_unbound:
fa19602c 153 err_msg = scm_from_locale_string ("VM: Unbound variable: ~A");
17e90c5e
KN
154 goto vm_error;
155
4c9ad01d 156 vm_error_wrong_type_arg:
fa19602c 157 err_msg = scm_from_locale_string ("VM: Wrong type argument");
4c9ad01d
KN
158 err_args = SCM_EOL;
159 goto vm_error;
160
6d14383e
AW
161 vm_error_too_many_args:
162 err_msg = scm_from_locale_string ("VM: Too many arguments");
163 err_args = SCM_LIST1 (scm_from_int (nargs));
164 goto vm_error;
165
17e90c5e 166 vm_error_wrong_num_args:
9a8cc8e7 167 /* nargs and program are valid */
0570c3f1 168 SYNC_ALL ();
9a8cc8e7
AW
169 scm_wrong_num_args (program);
170 /* shouldn't get here */
17e90c5e
KN
171 goto vm_error;
172
173 vm_error_wrong_type_apply:
0b5f0e49
LC
174 err_msg = scm_from_locale_string ("VM: Wrong type to apply: ~S "
175 "[IP offset: ~a]");
176 err_args = SCM_LIST2 (program,
177 SCM_I_MAKINUM (ip - bp->base));
17e90c5e
KN
178 goto vm_error;
179
ac02b386 180 vm_error_stack_overflow:
fa19602c 181 err_msg = scm_from_locale_string ("VM: Stack overflow");
17e90c5e
KN
182 err_args = SCM_EOL;
183 goto vm_error;
17e90c5e 184
ac02b386 185 vm_error_stack_underflow:
fa19602c 186 err_msg = scm_from_locale_string ("VM: Stack underflow");
17e90c5e
KN
187 err_args = SCM_EOL;
188 goto vm_error;
189
1f40459f
AW
190 vm_error_improper_list:
191 err_msg = scm_from_locale_string ("VM: Attempt to unroll an improper list: tail is ~A");
192 goto vm_error;
193
5e390de6
AW
194 vm_error_not_a_pair:
195 SYNC_ALL ();
196 scm_wrong_type_arg_msg (FUNC_NAME, 1, err_args, "pair");
197 /* shouldn't get here */
198 goto vm_error;
199
a222b0fa
AW
200 vm_error_no_values:
201 err_msg = scm_from_locale_string ("VM: 0-valued return");
202 err_args = SCM_EOL;
203 goto vm_error;
204
d51406fe
AW
205 vm_error_not_enough_values:
206 err_msg = scm_from_locale_string ("VM: Not enough values for mv-bind");
207 err_args = SCM_EOL;
208 goto vm_error;
209
fd358575
AW
210 vm_error_no_such_module:
211 err_msg = scm_from_locale_string ("VM: No such module: ~A");
212 goto vm_error;
213
ac02b386
KN
214#if VM_CHECK_IP
215 vm_error_invalid_address:
fa19602c 216 err_msg = scm_from_locale_string ("VM: Invalid program address");
17e90c5e
KN
217 err_args = SCM_EOL;
218 goto vm_error;
ac02b386
KN
219#endif
220
221#if VM_CHECK_EXTERNAL
222 vm_error_external:
fa19602c 223 err_msg = scm_from_locale_string ("VM: Invalid external access");
ac02b386
KN
224 err_args = SCM_EOL;
225 goto vm_error;
226#endif
17e90c5e 227
0b5f0e49
LC
228#if VM_CHECK_OBJECT
229 vm_error_object:
230 err_msg = scm_from_locale_string ("VM: Invalid object table access");
231 err_args = SCM_EOL;
232 goto vm_error;
233#endif
234
17e90c5e
KN
235 vm_error:
236 SYNC_ALL ();
a52b2d3d 237
ac99cb0c 238 scm_ithrow (sym_vm_error, SCM_LIST3 (sym_vm_run, err_msg, err_args), 1);
17e90c5e
KN
239 }
240
a98cef7e
KN
241 abort (); /* never reached */
242}
6d14383e
AW
243
244#undef VM_USE_HOOKS
245#undef VM_USE_CLOCK
246#undef VM_CHECK_EXTERNAL
247#undef VM_CHECK_OBJECT
17e90c5e
KN
248
249/*
250 Local Variables:
251 c-file-style: "gnu"
252 End:
253*/