1
/* lispmach.c -- Interpreter for compiled Lisp forms
3
$Id: lispmach.c,v 1.108 2000/09/03 12:36:04 john Exp $
5
Copyright (C) 1993, 1994, 2000 John Harper <john@dcs.warwick.ac.uk>
7
This file is part of Jade.
9
Jade is free software; you can redistribute it and/or modify it
10
under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2, or (at your option)
14
Jade is distributed in the hope that it will be useful, but
15
WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with Jade; see the file COPYING. If not, write to
21
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25
/* Define this to check if the compiler gets things right */
28
/* Define this to bytecode use histograms */
29
#undef BYTECODE_PROFILE
31
/* Define this to cache top-of-stack in a register (not usually worth it) */
34
/* AIX requires this to be the first thing in the file. */
37
# define alloca __builtin_alloca
45
# ifndef alloca /* predefined by HP cc +Olibcalls */
55
DEFSYM(bytecode_error, "bytecode-error");
58
/* pull in the generic interpreter */
60
#ifdef BYTECODE_PROFILE
61
static int bytecode_profile[256];
65
# define ASSERT(x) assert(x)
70
#define BC_APPLY_SELF 0
78
rep_apply_bytecode (repv subr, int nargs, repv *args)
80
assert (rep_COMPILEDP (subr));
81
return inline_apply_bytecode (subr, nargs, args);
84
DEFUN("run-byte-code", Frun_byte_code, Srun_byte_code,
85
(repv code, repv consts, repv stkreq), rep_Subr3)
87
int v_stkreq, b_stkreq, s_stkreq;
89
if (rep_STRUCTUREP (code))
91
/* install ourselves in this structure */
92
rep_STRUCTURE (code)->apply_bytecode = 0;
96
rep_DECLARE1(code, rep_STRINGP);
97
rep_DECLARE2(consts, rep_VECTORP);
98
rep_DECLARE3(stkreq, rep_INTP);
100
v_stkreq = rep_INT (stkreq) & 0x3ff;
101
b_stkreq = (rep_INT (stkreq) >> 10) & 0x3ff;
102
s_stkreq = rep_INT (stkreq) >> 20;
104
return vm (code, consts, 0, 0, v_stkreq, b_stkreq, s_stkreq);
107
DEFUN("validate-byte-code", Fvalidate_byte_code, Svalidate_byte_code, (repv bc_major, repv bc_minor), rep_Subr2) /*
108
::doc:rep.vm.interpreter#validate-byte-code::
109
validate-byte-code BC-MAJOR BC-MINOR
111
Check that byte codes from instruction set BC-MAJOR.BC-MINOR, may be
112
executed. If not, an error will be signalled.
115
if(!rep_INTP(bc_major) || !rep_INTP(bc_minor)
116
|| rep_INT(bc_major) != BYTECODE_MAJOR_VERSION
117
|| rep_INT(bc_minor) > BYTECODE_MINOR_VERSION)
119
DEFSTRING (err, "File needs recompiling for current virtual machine");
120
return Fsignal (Qbytecode_error,
121
rep_LIST_2 (rep_VAL (&err),
122
Fsymbol_value (Qload_filename, Qt)));
128
DEFUN("make-byte-code-subr", Fmake_byte_code_subr, Smake_byte_code_subr, (repv args), rep_SubrN) /*
129
::doc:rep.vm.interpreter#make-byte-code-subr::
130
make-byte-code-subr CODE CONSTANTS STACK [DOC] [INTERACTIVE]
132
Return an object that can be used as the function value of a symbol.
135
int len = rep_list_length(args);
139
if(len < rep_COMPILED_MIN_SLOTS)
140
return rep_signal_missing_arg(len + 1);
142
if(!rep_STRINGP(rep_CAR(args)))
143
return rep_signal_arg_error(rep_CAR(args), 2);
144
obj[0] = rep_CAR(args); args = rep_CDR(args);
145
if(!rep_VECTORP(rep_CAR(args)))
146
return rep_signal_arg_error(rep_CAR(args), 3);
147
obj[1] = rep_CAR(args); args = rep_CDR(args);
148
if(!rep_INTP(rep_CAR(args)))
149
return rep_signal_arg_error(rep_CAR(args), 4);
150
obj[2] = rep_CAR(args); args = rep_CDR(args);
155
obj[used++] = rep_CAR(args); args = rep_CDR(args);
158
obj[used++] = rep_CAR(args); args = rep_CDR(args);
159
if(rep_NILP(obj[used - 1]))
162
if(used == 4 && rep_NILP(obj[used - 1]))
166
vec = Fmake_vector(rep_MAKE_INT(used), Qnil);
170
rep_COMPILED(vec)->car = ((rep_COMPILED(vec)->car
171
& ~rep_CELL8_TYPE_MASK) | rep_Compiled);
172
for(i = 0; i < used; i++)
173
rep_VECTI(vec, i) = obj[i];
178
DEFUN("bytecodep", Fbytecodep, Sbytecodep, (repv arg), rep_Subr1) /*
179
::doc:rep.vm.interpreter#bytecodep::
182
Returns t if ARG is a byte code subroutine (i.e. compiled Lisp code).
185
return rep_COMPILEDP(arg) ? Qt : Qnil;
188
#ifdef BYTECODE_PROFILE
190
print_bytecode_profile (void)
193
for (i = 0; i < 256; i++)
194
printf ("%8d %8d\n", i, bytecode_profile[i]);
197
DEFUN ("bytecode-profile", Fbytecode_profile,
198
Sbytecode_profile, (repv reset), rep_Subr1)
201
memset (bytecode_profile, 0, sizeof (bytecode_profile));
203
print_bytecode_profile ();
209
rep_lispmach_init(void)
211
repv tem = rep_push_structure ("rep.vm.interpreter");
212
rep_ADD_SUBR(Srun_byte_code);
213
rep_ADD_SUBR(Svalidate_byte_code);
214
rep_ADD_SUBR(Smake_byte_code_subr);
215
rep_ADD_SUBR(Sbytecodep);
216
#ifdef BYTECODE_PROFILE
217
rep_ADD_SUBR(Sbytecode_profile);
218
atexit (print_bytecode_profile);
220
rep_INTERN(bytecode_error); rep_ERROR(bytecode_error);
221
rep_pop_structure (tem);
225
rep_lispmach_kill(void)