Print the faulty object upon invalid-keyword errors.
[bpt/guile.git] / libguile / vm-i-system.c
CommitLineData
581f410f 1/* Copyright (C) 2001,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
5e80f2ce 2 *
53e28ed9 3 * This library is free software; you can redistribute it and/or
53befeb7
NJ
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
a98cef7e 7 *
53befeb7
NJ
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
53e28ed9
AW
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
a98cef7e 12 *
53e28ed9
AW
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
53befeb7
NJ
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
53e28ed9
AW
17 */
18
a98cef7e
KN
19
20/* This file is included in vm_engine.c */
21
a98cef7e
KN
22\f
23/*
24 * Basic operations
25 */
26
53e28ed9 27VM_DEFINE_INSTRUCTION (0, nop, "nop", 0, 0, 0)
a98cef7e
KN
28{
29 NEXT;
30}
31
53e28ed9 32VM_DEFINE_INSTRUCTION (1, halt, "halt", 0, 0, 0)
a98cef7e 33{
53bdfcf0
AW
34 SCM ret;
35
a222b0fa 36 nvalues = SCM_I_INUM (*sp--);
11ea1aba 37 NULLSTACK (1);
53bdfcf0 38
a222b0fa 39 if (nvalues == 1)
53bdfcf0 40 POP (ret);
a222b0fa
AW
41 else
42 {
877ffa3f 43 SYNC_REGISTER ();
53bdfcf0
AW
44 sp -= nvalues;
45 CHECK_UNDERFLOW ();
46 ret = scm_c_values (sp + 1, nvalues);
47 NULLSTACK (nvalues);
a222b0fa
AW
48 }
49
1dc8f851 50 {
6c6a4439
AW
51#ifdef VM_ENABLE_STACK_NULLING
52 SCM *old_sp = sp;
53#endif
1dc8f851
AW
54
55 /* Restore registers */
56 sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
6c6a4439
AW
57 /* Setting the ip here doesn't actually affect control flow, as the calling
58 code will restore its own registers, but it does help when walking the
59 stack */
60 ip = SCM_FRAME_RETURN_ADDRESS (fp);
1dc8f851 61 fp = SCM_FRAME_DYNAMIC_LINK (fp);
6c6a4439 62 NULLSTACK (old_sp - sp);
1dc8f851 63 }
e06e857c 64
53bdfcf0
AW
65 SYNC_ALL ();
66 return ret;
a98cef7e
KN
67}
68
cf45ff03 69VM_DEFINE_INSTRUCTION (2, drop, "drop", 0, 1, 0)
a98cef7e 70{
17e90c5e 71 DROP ();
a98cef7e
KN
72 NEXT;
73}
74
cf45ff03 75VM_DEFINE_INSTRUCTION (3, dup, "dup", 0, 0, 1)
26403690 76{
f349065e
KN
77 SCM x = *sp;
78 PUSH (x);
26403690
KN
79 NEXT;
80}
81
17e90c5e
KN
82\f
83/*
84 * Object creation
85 */
a98cef7e 86
cf45ff03 87VM_DEFINE_INSTRUCTION (4, void, "void", 0, 0, 1)
a98cef7e 88{
17e90c5e 89 PUSH (SCM_UNSPECIFIED);
a98cef7e
KN
90 NEXT;
91}
92
cf45ff03 93VM_DEFINE_INSTRUCTION (5, make_true, "make-true", 0, 0, 1)
a98cef7e 94{
17e90c5e 95 PUSH (SCM_BOOL_T);
a98cef7e
KN
96 NEXT;
97}
98
cf45ff03 99VM_DEFINE_INSTRUCTION (6, make_false, "make-false", 0, 0, 1)
a98cef7e 100{
17e90c5e 101 PUSH (SCM_BOOL_F);
a98cef7e
KN
102 NEXT;
103}
104
cf45ff03 105VM_DEFINE_INSTRUCTION (7, make_nil, "make-nil", 0, 0, 1)
4530432e
DK
106{
107 PUSH (SCM_ELISP_NIL);
108 NEXT;
109}
110
cf45ff03 111VM_DEFINE_INSTRUCTION (8, make_eol, "make-eol", 0, 0, 1)
a98cef7e 112{
17e90c5e 113 PUSH (SCM_EOL);
a98cef7e
KN
114 NEXT;
115}
116
cf45ff03 117VM_DEFINE_INSTRUCTION (9, make_int8, "make-int8", 1, 0, 1)
a98cef7e 118{
2d80426a 119 PUSH (SCM_I_MAKINUM ((signed char) FETCH ()));
a98cef7e
KN
120 NEXT;
121}
122
cf45ff03 123VM_DEFINE_INSTRUCTION (10, make_int8_0, "make-int8:0", 0, 0, 1)
a98cef7e 124{
238e7a11 125 PUSH (SCM_INUM0);
a98cef7e
KN
126 NEXT;
127}
128
cf45ff03 129VM_DEFINE_INSTRUCTION (11, make_int8_1, "make-int8:1", 0, 0, 1)
a98cef7e 130{
238e7a11 131 PUSH (SCM_I_MAKINUM (1));
a98cef7e
KN
132 NEXT;
133}
134
cf45ff03 135VM_DEFINE_INSTRUCTION (12, make_int16, "make-int16", 2, 0, 1)
a98cef7e 136{
ea9b4b29
KN
137 int h = FETCH ();
138 int l = FETCH ();
2d80426a 139 PUSH (SCM_I_MAKINUM ((signed short) (h << 8) + l));
a98cef7e
KN
140 NEXT;
141}
142
cf45ff03 143VM_DEFINE_INSTRUCTION (13, make_int64, "make-int64", 8, 0, 1)
586cfdec
AW
144{
145 scm_t_uint64 v = 0;
146 v += FETCH ();
147 v <<= 8; v += FETCH ();
148 v <<= 8; v += FETCH ();
149 v <<= 8; v += FETCH ();
150 v <<= 8; v += FETCH ();
151 v <<= 8; v += FETCH ();
152 v <<= 8; v += FETCH ();
153 v <<= 8; v += FETCH ();
154 PUSH (scm_from_int64 ((scm_t_int64) v));
155 NEXT;
156}
157
cf45ff03 158VM_DEFINE_INSTRUCTION (14, make_uint64, "make-uint64", 8, 0, 1)
586cfdec
AW
159{
160 scm_t_uint64 v = 0;
161 v += FETCH ();
162 v <<= 8; v += FETCH ();
163 v <<= 8; v += FETCH ();
164 v <<= 8; v += FETCH ();
165 v <<= 8; v += FETCH ();
166 v <<= 8; v += FETCH ();
167 v <<= 8; v += FETCH ();
168 v <<= 8; v += FETCH ();
169 PUSH (scm_from_uint64 (v));
170 NEXT;
171}
172
cf45ff03 173VM_DEFINE_INSTRUCTION (15, make_char8, "make-char8", 1, 0, 1)
a98cef7e 174{
4c402b88
MG
175 scm_t_uint8 v = 0;
176 v = FETCH ();
177
178 PUSH (SCM_MAKE_CHAR (v));
179 /* Don't simplify this to PUSH (SCM_MAKE_CHAR (FETCH ())). The
180 contents of SCM_MAKE_CHAR may be evaluated more than once,
181 resulting in a double fetch. */
a98cef7e
KN
182 NEXT;
183}
184
cf45ff03 185VM_DEFINE_INSTRUCTION (16, make_char32, "make-char32", 4, 0, 1)
904a78f1
MG
186{
187 scm_t_wchar v = 0;
188 v += FETCH ();
189 v <<= 8; v += FETCH ();
190 v <<= 8; v += FETCH ();
191 v <<= 8; v += FETCH ();
192 PUSH (SCM_MAKE_CHAR (v));
193 NEXT;
194}
195
196
197
cf45ff03 198VM_DEFINE_INSTRUCTION (17, list, "list", 2, -1, 1)
cb4cca12 199{
23b587b0
LC
200 unsigned h = FETCH ();
201 unsigned l = FETCH ();
202 unsigned len = ((h << 8) + l);
203 POP_LIST (len);
cb4cca12
KN
204 NEXT;
205}
206
cf45ff03 207VM_DEFINE_INSTRUCTION (18, vector, "vector", 2, -1, 1)
cb4cca12 208{
23b587b0
LC
209 unsigned h = FETCH ();
210 unsigned l = FETCH ();
211 unsigned len = ((h << 8) + l);
5338b62b
AW
212 SCM vect;
213
877ffa3f 214 SYNC_REGISTER ();
5338b62b
AW
215 sp++; sp -= len;
216 CHECK_UNDERFLOW ();
217 vect = scm_make_vector (scm_from_uint (len), SCM_BOOL_F);
218 memcpy (SCM_I_VECTOR_WELTS(vect), sp, sizeof(SCM) * len);
219 NULLSTACK (len);
220 *sp = vect;
221
cb4cca12
KN
222 NEXT;
223}
224
a98cef7e
KN
225\f
226/*
17e90c5e 227 * Variable access
a98cef7e
KN
228 */
229
17e90c5e
KN
230#define OBJECT_REF(i) objects[i]
231#define OBJECT_SET(i,o) objects[i] = o
a98cef7e 232
af988bbf
KN
233#define LOCAL_REF(i) SCM_FRAME_VARIABLE (fp, i)
234#define LOCAL_SET(i,o) SCM_FRAME_VARIABLE (fp, i) = o
a98cef7e 235
2d80426a
LC
236/* For the variable operations, we _must_ obviously avoid function calls to
237 `scm_variable_ref ()', `scm_variable_bound_p ()' and friends which do
238 nothing more than the corresponding macros. */
239#define VARIABLE_REF(v) SCM_VARIABLE_REF (v)
240#define VARIABLE_SET(v,o) SCM_VARIABLE_SET (v, o)
d223c3fc 241#define VARIABLE_BOUNDP(v) (!scm_is_eq (VARIABLE_REF (v), SCM_UNDEFINED))
a98cef7e 242
6f16379e 243#define FREE_VARIABLE_REF(i) SCM_PROGRAM_FREE_VARIABLE_REF (program, i)
8d90b356 244
17e90c5e 245/* ref */
a98cef7e 246
cf45ff03 247VM_DEFINE_INSTRUCTION (19, object_ref, "object-ref", 1, 0, 1)
a98cef7e 248{
a52b2d3d 249 register unsigned objnum = FETCH ();
0b5f0e49
LC
250 CHECK_OBJECT (objnum);
251 PUSH (OBJECT_REF (objnum));
17e90c5e 252 NEXT;
a98cef7e
KN
253}
254
a5cfddd5 255/* FIXME: necessary? elt 255 of the vector could be a vector... */
cf45ff03 256VM_DEFINE_INSTRUCTION (20, long_object_ref, "long-object-ref", 2, 0, 1)
a5cfddd5
AW
257{
258 unsigned int objnum = FETCH ();
259 objnum <<= 8;
260 objnum += FETCH ();
261 CHECK_OBJECT (objnum);
262 PUSH (OBJECT_REF (objnum));
263 NEXT;
264}
265
cf45ff03 266VM_DEFINE_INSTRUCTION (21, local_ref, "local-ref", 1, 0, 1)
a98cef7e 267{
17e90c5e 268 PUSH (LOCAL_REF (FETCH ()));
a1a482e0 269 ASSERT_BOUND (*sp);
17e90c5e 270 NEXT;
a98cef7e
KN
271}
272
cf45ff03 273VM_DEFINE_INSTRUCTION (22, long_local_ref, "long-local-ref", 2, 0, 1)
a98cef7e 274{
80545853
AW
275 unsigned int i = FETCH ();
276 i <<= 8;
277 i += FETCH ();
28b119ee 278 PUSH (LOCAL_REF (i));
a1a482e0 279 ASSERT_BOUND (*sp);
a98cef7e
KN
280 NEXT;
281}
282
cf45ff03 283VM_DEFINE_INSTRUCTION (23, local_bound, "local-bound?", 1, 0, 1)
3092a14d 284{
d223c3fc 285 PUSH (scm_from_bool (!scm_is_eq (LOCAL_REF (FETCH ()), SCM_UNDEFINED)));
3092a14d
AW
286 NEXT;
287}
288
cf45ff03 289VM_DEFINE_INSTRUCTION (24, long_local_bound, "long-local-bound?", 2, 0, 1)
3092a14d
AW
290{
291 unsigned int i = FETCH ();
292 i <<= 8;
293 i += FETCH ();
d223c3fc 294 PUSH (scm_from_bool (!scm_is_eq (LOCAL_REF (i), SCM_UNDEFINED)));
3092a14d
AW
295 NEXT;
296}
297
cf45ff03 298VM_DEFINE_INSTRUCTION (25, variable_ref, "variable-ref", 0, 1, 1)
a98cef7e 299{
17e90c5e 300 SCM x = *sp;
238e7a11 301
dce0252b
AW
302 /* We don't use ASSERT_VARIABLE or ASSERT_BOUND_VARIABLE here because,
303 unlike in top-variable-ref, it really isn't an internal assertion
304 that can be optimized out -- the variable could be coming directly
305 from the user. */
53bdfcf0
AW
306 VM_ASSERT (SCM_VARIABLEP (x),
307 vm_error_not_a_variable ("variable-ref", x));
308
309 if (SCM_UNLIKELY (!VARIABLE_BOUNDP (x)))
17e90c5e 310 {
1af77230
LC
311 SCM var_name;
312
4cec6c22 313 SYNC_ALL ();
1af77230
LC
314 /* Attempt to provide the variable name in the error message. */
315 var_name = scm_module_reverse_lookup (scm_current_module (), x);
53bdfcf0 316 vm_error_unbound (program, scm_is_true (var_name) ? var_name : x);
17e90c5e 317 }
238e7a11
LC
318 else
319 {
2d80426a 320 SCM o = VARIABLE_REF (x);
238e7a11
LC
321 *sp = o;
322 }
323
a98cef7e
KN
324 NEXT;
325}
326
cf45ff03 327VM_DEFINE_INSTRUCTION (26, variable_bound, "variable-bound?", 0, 1, 1)
3092a14d 328{
dce0252b
AW
329 SCM x = *sp;
330
53bdfcf0
AW
331 VM_ASSERT (SCM_VARIABLEP (x),
332 vm_error_not_a_variable ("variable-bound?", x));
333
334 *sp = scm_from_bool (VARIABLE_BOUNDP (x));
3092a14d
AW
335 NEXT;
336}
337
cf45ff03 338VM_DEFINE_INSTRUCTION (27, toplevel_ref, "toplevel-ref", 1, 0, 1)
9cc649b8 339{
6297d229 340 unsigned objnum = FETCH ();
a39b116f 341 SCM what, resolved;
9cc649b8 342 CHECK_OBJECT (objnum);
fd358575 343 what = OBJECT_REF (objnum);
9cc649b8 344
45dc6b34 345 if (!SCM_VARIABLEP (what))
9cc649b8 346 {
d0168f3d 347 SYNC_REGISTER ();
45dc6b34 348 resolved = resolve_variable (what, scm_program_module (program));
53bdfcf0 349 VM_ASSERT (VARIABLE_BOUNDP (resolved), vm_error_unbound (program, what));
45dc6b34 350 what = resolved;
fd358575 351 OBJECT_SET (objnum, what);
9cc649b8
AW
352 }
353
fd358575 354 PUSH (VARIABLE_REF (what));
9cc649b8
AW
355 NEXT;
356}
357
cf45ff03 358VM_DEFINE_INSTRUCTION (28, long_toplevel_ref, "long-toplevel-ref", 2, 0, 1)
a5cfddd5 359{
a39b116f 360 SCM what, resolved;
a5cfddd5
AW
361 unsigned int objnum = FETCH ();
362 objnum <<= 8;
363 objnum += FETCH ();
364 CHECK_OBJECT (objnum);
365 what = OBJECT_REF (objnum);
366
45dc6b34 367 if (!SCM_VARIABLEP (what))
a5cfddd5
AW
368 {
369 SYNC_REGISTER ();
45dc6b34 370 resolved = resolve_variable (what, scm_program_module (program));
53bdfcf0
AW
371 VM_ASSERT (VARIABLE_BOUNDP (resolved),
372 vm_error_unbound (program, what));
45dc6b34 373 what = resolved;
a5cfddd5
AW
374 OBJECT_SET (objnum, what);
375 }
376
377 PUSH (VARIABLE_REF (what));
378 NEXT;
379}
380
17e90c5e
KN
381/* set */
382
cf45ff03 383VM_DEFINE_INSTRUCTION (29, local_set, "local-set", 1, 1, 0)
a98cef7e 384{
eae2438d
AW
385 SCM x;
386 POP (x);
387 LOCAL_SET (FETCH (), x);
a98cef7e
KN
388 NEXT;
389}
390
cf45ff03 391VM_DEFINE_INSTRUCTION (30, long_local_set, "long-local-set", 2, 1, 0)
a98cef7e 392{
eae2438d 393 SCM x;
80545853
AW
394 unsigned int i = FETCH ();
395 i <<= 8;
396 i += FETCH ();
eae2438d
AW
397 POP (x);
398 LOCAL_SET (i, x);
a98cef7e
KN
399 NEXT;
400}
401
cf45ff03 402VM_DEFINE_INSTRUCTION (31, variable_set, "variable-set", 0, 2, 0)
a98cef7e 403{
53bdfcf0
AW
404 VM_ASSERT (SCM_VARIABLEP (sp[0]),
405 vm_error_not_a_variable ("variable-set!", sp[0]));
2d80426a 406 VARIABLE_SET (sp[0], sp[-1]);
11ea1aba 407 DROPN (2);
a98cef7e
KN
408 NEXT;
409}
410
cf45ff03 411VM_DEFINE_INSTRUCTION (32, toplevel_set, "toplevel-set", 1, 1, 0)
9cc649b8 412{
6297d229 413 unsigned objnum = FETCH ();
fd358575 414 SCM what;
9cc649b8 415 CHECK_OBJECT (objnum);
fd358575 416 what = OBJECT_REF (objnum);
9cc649b8 417
fd358575 418 if (!SCM_VARIABLEP (what))
9cc649b8 419 {
6287726a 420 SYNC_BEFORE_GC ();
b7393ea1 421 what = resolve_variable (what, scm_program_module (program));
fd358575 422 OBJECT_SET (objnum, what);
9cc649b8
AW
423 }
424
fd358575 425 VARIABLE_SET (what, *sp);
9cc649b8
AW
426 DROP ();
427 NEXT;
428}
429
cf45ff03 430VM_DEFINE_INSTRUCTION (33, long_toplevel_set, "long-toplevel-set", 2, 1, 0)
a5cfddd5
AW
431{
432 SCM what;
433 unsigned int objnum = FETCH ();
434 objnum <<= 8;
435 objnum += FETCH ();
436 CHECK_OBJECT (objnum);
437 what = OBJECT_REF (objnum);
438
439 if (!SCM_VARIABLEP (what))
440 {
441 SYNC_BEFORE_GC ();
442 what = resolve_variable (what, scm_program_module (program));
443 OBJECT_SET (objnum, what);
444 }
445
446 VARIABLE_SET (what, *sp);
447 DROP ();
448 NEXT;
449}
450
a98cef7e
KN
451\f
452/*
453 * branch and jump
454 */
455
97fcf583 456/* offset must be at least 24 bits wide, and signed */
efbd5892 457#define FETCH_OFFSET(offset) \
17e90c5e 458{ \
97fcf583
AW
459 offset = FETCH () << 16; \
460 offset += FETCH () << 8; \
461 offset += FETCH (); \
462 offset -= (offset & (1<<23)) << 1; \
efbd5892
AW
463}
464
eae2438d 465#define BR(p) \
efbd5892 466{ \
97fcf583 467 scm_t_int32 offset; \
efbd5892 468 FETCH_OFFSET (offset); \
17e90c5e 469 if (p) \
97fcf583 470 ip += offset; \
5b09b37f
AW
471 if (offset < 0) \
472 VM_HANDLE_INTERRUPTS; \
a39b116f 473 NEXT; \
17e90c5e
KN
474}
475
cf45ff03 476VM_DEFINE_INSTRUCTION (34, br, "br", 3, 0, 0)
41f248a8 477{
97fcf583 478 scm_t_int32 offset;
e5dc27b8 479 FETCH_OFFSET (offset);
97fcf583 480 ip += offset;
5b09b37f
AW
481 if (offset < 0)
482 VM_HANDLE_INTERRUPTS;
41f248a8
KN
483 NEXT;
484}
485
cf45ff03 486VM_DEFINE_INSTRUCTION (35, br_if, "br-if", 3, 0, 0)
a98cef7e 487{
eae2438d
AW
488 SCM x;
489 POP (x);
490 BR (scm_is_true (x));
a98cef7e
KN
491}
492
cf45ff03 493VM_DEFINE_INSTRUCTION (36, br_if_not, "br-if-not", 3, 0, 0)
a98cef7e 494{
eae2438d
AW
495 SCM x;
496 POP (x);
497 BR (scm_is_false (x));
a98cef7e
KN
498}
499
cf45ff03 500VM_DEFINE_INSTRUCTION (37, br_if_eq, "br-if-eq", 3, 0, 0)
a98cef7e 501{
eae2438d
AW
502 SCM x, y;
503 POP2 (y, x);
504 BR (scm_is_eq (x, y));
a98cef7e
KN
505}
506
cf45ff03 507VM_DEFINE_INSTRUCTION (38, br_if_not_eq, "br-if-not-eq", 3, 0, 0)
a98cef7e 508{
eae2438d
AW
509 SCM x, y;
510 POP2 (y, x);
511 BR (!scm_is_eq (x, y));
17e90c5e
KN
512}
513
cf45ff03 514VM_DEFINE_INSTRUCTION (39, br_if_null, "br-if-null", 3, 0, 0)
17e90c5e 515{
eae2438d
AW
516 SCM x;
517 POP (x);
518 BR (scm_is_null (x));
17e90c5e
KN
519}
520
cf45ff03 521VM_DEFINE_INSTRUCTION (40, br_if_not_null, "br-if-not-null", 3, 0, 0)
17e90c5e 522{
eae2438d
AW
523 SCM x;
524 POP (x);
525 BR (!scm_is_null (x));
a98cef7e
KN
526}
527
a98cef7e
KN
528\f
529/*
530 * Subprogram call
531 */
532
cf45ff03 533VM_DEFINE_INSTRUCTION (41, br_if_nargs_ne, "br-if-nargs-ne", 5, 0, 0)
7e01997e
AW
534{
535 scm_t_ptrdiff n;
7f991c7d 536 scm_t_int32 offset;
7e01997e
AW
537 n = FETCH () << 8;
538 n += FETCH ();
7e01997e
AW
539 FETCH_OFFSET (offset);
540 if (sp - (fp - 1) != n)
541 ip += offset;
542 NEXT;
543}
544
cf45ff03 545VM_DEFINE_INSTRUCTION (42, br_if_nargs_lt, "br-if-nargs-lt", 5, 0, 0)
7e01997e
AW
546{
547 scm_t_ptrdiff n;
7f991c7d 548 scm_t_int32 offset;
7e01997e
AW
549 n = FETCH () << 8;
550 n += FETCH ();
7e01997e
AW
551 FETCH_OFFSET (offset);
552 if (sp - (fp - 1) < n)
553 ip += offset;
554 NEXT;
555}
556
cf45ff03 557VM_DEFINE_INSTRUCTION (43, br_if_nargs_gt, "br-if-nargs-gt", 5, 0, 0)
7e01997e
AW
558{
559 scm_t_ptrdiff n;
ff74e44e
AW
560 scm_t_int32 offset;
561
7e01997e
AW
562 n = FETCH () << 8;
563 n += FETCH ();
7e01997e
AW
564 FETCH_OFFSET (offset);
565 if (sp - (fp - 1) > n)
566 ip += offset;
567 NEXT;
568}
569
cf45ff03 570VM_DEFINE_INSTRUCTION (44, assert_nargs_ee, "assert-nargs-ee", 2, 0, 0)
1e2a8c26
AW
571{
572 scm_t_ptrdiff n;
573 n = FETCH () << 8;
574 n += FETCH ();
53bdfcf0
AW
575 VM_ASSERT (sp - (fp - 1) == n,
576 vm_error_wrong_num_args (program));
1e2a8c26
AW
577 NEXT;
578}
579
cf45ff03 580VM_DEFINE_INSTRUCTION (45, assert_nargs_ge, "assert-nargs-ge", 2, 0, 0)
1e2a8c26
AW
581{
582 scm_t_ptrdiff n;
583 n = FETCH () << 8;
584 n += FETCH ();
53bdfcf0
AW
585 VM_ASSERT (sp - (fp - 1) >= n,
586 vm_error_wrong_num_args (program));
1e2a8c26
AW
587 NEXT;
588}
589
cf45ff03 590VM_DEFINE_INSTRUCTION (46, bind_optionals, "bind-optionals", 2, -1, -1)
7e01997e
AW
591{
592 scm_t_ptrdiff n;
593 n = FETCH () << 8;
594 n += FETCH ();
595 while (sp - (fp - 1) < n)
596 PUSH (SCM_UNDEFINED);
597 NEXT;
598}
599
cf45ff03 600VM_DEFINE_INSTRUCTION (47, bind_optionals_shuffle, "bind-optionals/shuffle", 6, -1, -1)
7e01997e
AW
601{
602 SCM *walk;
603 scm_t_ptrdiff nreq, nreq_and_opt, ntotal;
604 nreq = FETCH () << 8;
605 nreq += FETCH ();
606 nreq_and_opt = FETCH () << 8;
607 nreq_and_opt += FETCH ();
608 ntotal = FETCH () << 8;
609 ntotal += FETCH ();
610
611 /* look in optionals for first keyword or last positional */
612 /* starting after the last required positional arg */
3092a14d 613 walk = fp + nreq;
7e01997e
AW
614 while (/* while we have args */
615 walk <= sp
616 /* and we still have positionals to fill */
3092a14d 617 && walk - fp < nreq_and_opt
7e01997e
AW
618 /* and we haven't reached a keyword yet */
619 && !scm_is_keyword (*walk))
620 /* bind this optional arg (by leaving it in place) */
621 walk++;
622 /* now shuffle up, from walk to ntotal */
623 {
3092a14d 624 scm_t_ptrdiff nshuf = sp - walk + 1, i;
7e01997e
AW
625 sp = (fp - 1) + ntotal + nshuf;
626 CHECK_OVERFLOW ();
3092a14d
AW
627 for (i = 0; i < nshuf; i++)
628 sp[-i] = walk[nshuf-i-1];
7e01997e
AW
629 }
630 /* and fill optionals & keyword args with SCM_UNDEFINED */
3092a14d 631 while (walk <= (fp - 1) + ntotal)
7e01997e
AW
632 *walk++ = SCM_UNDEFINED;
633
634 NEXT;
635}
636
581f410f
AW
637/* See also bind-optionals/shuffle-or-br below. */
638
ff74e44e
AW
639/* Flags that determine whether other keywords are allowed, and whether a
640 rest argument is expected. These values must match those used by the
641 glil->assembly compiler. */
642#define F_ALLOW_OTHER_KEYS 1
643#define F_REST 2
644
cf45ff03 645VM_DEFINE_INSTRUCTION (48, bind_kwargs, "bind-kwargs", 5, 0, 0)
7e01997e
AW
646{
647 scm_t_uint16 idx;
648 scm_t_ptrdiff nkw;
ff74e44e 649 int kw_and_rest_flags;
7e01997e
AW
650 SCM kw;
651 idx = FETCH () << 8;
652 idx += FETCH ();
ff74e44e 653 /* XXX: We don't actually use NKW. */
7e01997e
AW
654 nkw = FETCH () << 8;
655 nkw += FETCH ();
ff74e44e 656 kw_and_rest_flags = FETCH ();
7e01997e 657
53bdfcf0
AW
658 VM_ASSERT ((kw_and_rest_flags & F_REST)
659 || ((sp - (fp - 1) - nkw) % 2) == 0,
660 vm_error_kwargs_length_not_even (program))
7e01997e
AW
661
662 CHECK_OBJECT (idx);
663 kw = OBJECT_REF (idx);
ff74e44e
AW
664
665 /* Switch NKW to be a negative index below SP. */
666 for (nkw = -(sp - (fp - 1) - nkw) + 1; nkw < 0; nkw++)
7e01997e
AW
667 {
668 SCM walk;
ff74e44e
AW
669
670 if (scm_is_keyword (sp[nkw]))
671 {
672 for (walk = kw; scm_is_pair (walk); walk = SCM_CDR (walk))
673 {
674 if (scm_is_eq (SCM_CAAR (walk), sp[nkw]))
675 {
676 SCM si = SCM_CDAR (walk);
677 LOCAL_SET (SCM_I_INUMP (si) ? SCM_I_INUM (si) : scm_to_long (si),
678 sp[nkw + 1]);
679 break;
680 }
681 }
53bdfcf0
AW
682 VM_ASSERT (scm_is_pair (walk)
683 || (kw_and_rest_flags & F_ALLOW_OTHER_KEYS),
4af0d97e 684 vm_error_kwargs_unrecognized_keyword (program, sp[nkw]));
ff74e44e
AW
685 nkw++;
686 }
53bdfcf0
AW
687 else
688 VM_ASSERT (kw_and_rest_flags & F_REST,
4af0d97e 689 vm_error_kwargs_invalid_keyword (program, sp[nkw]));
7e01997e
AW
690 }
691
692 NEXT;
693}
694
ff74e44e
AW
695#undef F_ALLOW_OTHER_KEYS
696#undef F_REST
697
698
cf45ff03 699VM_DEFINE_INSTRUCTION (49, push_rest, "push-rest", 2, -1, -1)
1e2a8c26
AW
700{
701 scm_t_ptrdiff n;
a6f15a1e 702 SCM rest = SCM_EOL;
1e2a8c26
AW
703 n = FETCH () << 8;
704 n += FETCH ();
a6f15a1e 705 while (sp - (fp - 1) > n)
1e2a8c26
AW
706 /* No need to check for underflow. */
707 CONS (rest, *sp--, rest);
708 PUSH (rest);
1e2a8c26
AW
709 NEXT;
710}
711
cf45ff03 712VM_DEFINE_INSTRUCTION (50, bind_rest, "bind-rest", 4, -1, -1)
899d37a6
AW
713{
714 scm_t_ptrdiff n;
715 scm_t_uint32 i;
716 SCM rest = SCM_EOL;
717 n = FETCH () << 8;
718 n += FETCH ();
719 i = FETCH () << 8;
720 i += FETCH ();
721 while (sp - (fp - 1) > n)
722 /* No need to check for underflow. */
723 CONS (rest, *sp--, rest);
724 LOCAL_SET (i, rest);
725 NEXT;
726}
727
cf45ff03 728VM_DEFINE_INSTRUCTION (51, reserve_locals, "reserve-locals", 2, -1, -1)
b7946e9e 729{
258344b4 730 SCM *old_sp;
55d9bc94
AW
731 scm_t_int32 n;
732 n = FETCH () << 8;
733 n += FETCH ();
258344b4
AW
734 old_sp = sp;
735 sp = (fp - 1) + n;
736
737 if (old_sp < sp)
738 {
739 CHECK_OVERFLOW ();
740 while (old_sp < sp)
741 *++old_sp = SCM_UNDEFINED;
742 }
743 else
744 NULLSTACK (old_sp - sp);
745
55d9bc94
AW
746 NEXT;
747}
748
cf45ff03 749VM_DEFINE_INSTRUCTION (52, new_frame, "new-frame", 0, 0, 3)
b7946e9e 750{
6c6a4439
AW
751 /* NB: if you change this, see frames.c:vm-frame-num-locals */
752 /* and frames.h, vm-engine.c, etc of course */
9b709b0f
AW
753
754 /* We don't initialize the dynamic link here because we don't actually
755 know that this frame will point to the current fp: it could be
756 placed elsewhere on the stack if captured in a partial
757 continuation, and invoked from some other context. */
b2b33168
AW
758 PUSH (SCM_PACK (0)); /* dynamic link */
759 PUSH (SCM_PACK (0)); /* mvra */
760 PUSH (SCM_PACK (0)); /* ra */
b7946e9e
AW
761 NEXT;
762}
763
cf45ff03 764VM_DEFINE_INSTRUCTION (53, call, "call", 1, -1, 1)
a98cef7e 765{
17e90c5e 766 nargs = FETCH ();
a98cef7e
KN
767
768 vm_call:
e8c37772 769 VM_HANDLE_INTERRUPTS;
e311f5fa 770
9b709b0f
AW
771 {
772 SCM *old_fp = fp;
773
774 fp = sp - nargs + 1;
775
776 ASSERT (SCM_FRAME_DYNAMIC_LINK (fp) == 0);
777 ASSERT (SCM_FRAME_RETURN_ADDRESS (fp) == 0);
778 ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp) == 0);
779 SCM_FRAME_SET_DYNAMIC_LINK (fp, old_fp);
780 SCM_FRAME_SET_RETURN_ADDRESS (fp, ip);
781 SCM_FRAME_SET_MV_RETURN_ADDRESS (fp, 0);
782 }
783
c45d4d77 784 PUSH_CONTINUATION_HOOK ();
67b699cc
AW
785
786 program = fp[-1];
787
788 if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
789 goto apply;
790
791 CACHE_PROGRAM ();
792 ip = SCM_C_OBJCODE_BASE (bp);
793
75c3ed28
AW
794 APPLY_HOOK ();
795 NEXT;
a98cef7e
KN
796}
797
cf45ff03 798VM_DEFINE_INSTRUCTION (54, tail_call, "tail-call", 1, -1, 1)
a98cef7e 799{
17e90c5e 800 nargs = FETCH ();
75c3ed28 801
a5bbb22e 802 vm_tail_call:
e8c37772 803 VM_HANDLE_INTERRUPTS;
a98cef7e 804
67b699cc
AW
805 {
806 int i;
11ea1aba 807#ifdef VM_ENABLE_STACK_NULLING
67b699cc
AW
808 SCM *old_sp = sp;
809 CHECK_STACK_LEAK ();
11ea1aba 810#endif
28106f54 811
67b699cc
AW
812 /* shuffle down the program and the arguments */
813 for (i = -1, sp = sp - nargs + 1; i < nargs; i++)
814 SCM_FRAME_STACK_ADDRESS (fp)[i] = sp[i];
11ea1aba 815
67b699cc 816 sp = fp + i - 1;
28106f54 817
67b699cc
AW
818 NULLSTACK (old_sp - sp);
819 }
11ea1aba 820
67b699cc 821 program = fp[-1];
11ea1aba 822
67b699cc
AW
823 if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
824 goto apply;
825
826 CACHE_PROGRAM ();
827 ip = SCM_C_OBJCODE_BASE (bp);
828
829 APPLY_HOOK ();
830 NEXT;
17e90c5e
KN
831}
832
cf45ff03 833VM_DEFINE_INSTRUCTION (55, subr_call, "subr-call", 1, -1, -1)
fd629322 834{
5b46a8c2 835 SCM pointer, ret;
fd629322 836 SCM (*subr)();
5b46a8c2 837
fd629322 838 nargs = FETCH ();
5b46a8c2 839 POP (pointer);
fd629322 840
5b46a8c2 841 subr = SCM_POINTER_VALUE (pointer);
fd629322
AW
842
843 VM_HANDLE_INTERRUPTS;
844 SYNC_REGISTER ();
845
846 switch (nargs)
847 {
848 case 0:
849 ret = subr ();
850 break;
851 case 1:
852 ret = subr (sp[0]);
853 break;
854 case 2:
855 ret = subr (sp[-1], sp[0]);
856 break;
857 case 3:
858 ret = subr (sp[-2], sp[-1], sp[0]);
859 break;
860 case 4:
861 ret = subr (sp[-3], sp[-2], sp[-1], sp[0]);
862 break;
863 case 5:
864 ret = subr (sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
865 break;
866 case 6:
867 ret = subr (sp[-5], sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
868 break;
869 case 7:
870 ret = subr (sp[-6], sp[-5], sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
871 break;
872 case 8:
873 ret = subr (sp[-7], sp[-6], sp[-5], sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
874 break;
875 case 9:
876 ret = subr (sp[-8], sp[-7], sp[-6], sp[-5], sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
877 break;
878 case 10:
879 ret = subr (sp[-9], sp[-8], sp[-7], sp[-6], sp[-5], sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
880 break;
881 default:
882 abort ();
883 }
884
885 NULLSTACK_FOR_NONLOCAL_EXIT ();
fd629322
AW
886
887 if (SCM_UNLIKELY (SCM_VALUESP (ret)))
888 {
889 /* multiple values returned to continuation */
890 ret = scm_struct_ref (ret, SCM_INUM0);
891 nvalues = scm_ilength (ret);
892 PUSH_LIST (ret, scm_is_null);
893 goto vm_return_values;
894 }
895 else
896 {
897 PUSH (ret);
898 goto vm_return;
899 }
900}
901
cf45ff03 902VM_DEFINE_INSTRUCTION (56, smob_call, "smob-call", 1, -1, -1)
75c3ed28
AW
903{
904 SCM smob, ret;
905 SCM (*subr)();
906 nargs = FETCH ();
907 POP (smob);
908
909 subr = SCM_SMOB_DESCRIPTOR (smob).apply;
910
911 VM_HANDLE_INTERRUPTS;
912 SYNC_REGISTER ();
913
914 switch (nargs)
915 {
916 case 0:
917 ret = subr (smob);
918 break;
919 case 1:
920 ret = subr (smob, sp[0]);
921 break;
922 case 2:
923 ret = subr (smob, sp[-1], sp[0]);
924 break;
925 case 3:
926 ret = subr (smob, sp[-2], sp[-1], sp[0]);
927 break;
928 default:
929 abort ();
930 }
931
932 NULLSTACK_FOR_NONLOCAL_EXIT ();
75c3ed28
AW
933
934 if (SCM_UNLIKELY (SCM_VALUESP (ret)))
935 {
936 /* multiple values returned to continuation */
937 ret = scm_struct_ref (ret, SCM_INUM0);
938 nvalues = scm_ilength (ret);
939 PUSH_LIST (ret, scm_is_null);
940 goto vm_return_values;
941 }
942 else
943 {
944 PUSH (ret);
945 goto vm_return;
946 }
947}
948
cf45ff03 949VM_DEFINE_INSTRUCTION (57, foreign_call, "foreign-call", 1, -1, -1)
827dc8dc
AW
950{
951 SCM foreign, ret;
952 nargs = FETCH ();
953 POP (foreign);
954
955 VM_HANDLE_INTERRUPTS;
956 SYNC_REGISTER ();
957
4d9130a5 958 ret = scm_i_foreign_call (foreign, sp - nargs + 1);
827dc8dc
AW
959
960 NULLSTACK_FOR_NONLOCAL_EXIT ();
961
962 if (SCM_UNLIKELY (SCM_VALUESP (ret)))
963 {
964 /* multiple values returned to continuation */
965 ret = scm_struct_ref (ret, SCM_INUM0);
966 nvalues = scm_ilength (ret);
967 PUSH_LIST (ret, scm_is_null);
968 goto vm_return_values;
969 }
970 else
971 {
972 PUSH (ret);
973 goto vm_return;
974 }
975}
976
cf45ff03 977VM_DEFINE_INSTRUCTION (58, continuation_call, "continuation-call", 0, -1, 0)
1d1cae0e
AW
978{
979 SCM contregs;
980 POP (contregs);
d8873dfe 981
f7cea645 982 SYNC_ALL ();
d8873dfe
AW
983 scm_i_check_continuation (contregs);
984 vm_return_to_continuation (scm_i_contregs_vm (contregs),
985 scm_i_contregs_vm_cont (contregs),
986 sp - (fp - 1), fp);
987 scm_i_reinstate_continuation (contregs);
988
a39b116f 989 /* no NEXT */
1d1cae0e
AW
990 abort ();
991}
992
cf45ff03 993VM_DEFINE_INSTRUCTION (59, partial_cont_call, "partial-cont-call", 0, -1, 0)
cee1d22c 994{
adbdfd6d 995 SCM vmcont, intwinds, prevwinds;
eae2438d 996 POP2 (intwinds, vmcont);
07801437 997 SYNC_REGISTER ();
53bdfcf0
AW
998 VM_ASSERT (SCM_VM_CONT_REWINDABLE_P (vmcont),
999 vm_error_continuation_not_rewindable (vmcont));
adbdfd6d
AW
1000 prevwinds = scm_i_dynwinds ();
1001 vm_reinstate_partial_continuation (vm, vmcont, intwinds, sp + 1 - fp, fp,
1002 vm_cookie);
1003
1004 /* Rewind prompt jmpbuffers, if any. */
1005 {
1006 SCM winds = scm_i_dynwinds ();
1007 for (; !scm_is_eq (winds, prevwinds); winds = scm_cdr (winds))
1008 if (SCM_PROMPT_P (scm_car (winds)) && SCM_PROMPT_SETJMP (scm_car (winds)))
1009 break;
1010 }
1011
07801437
AW
1012 CACHE_REGISTER ();
1013 program = SCM_FRAME_PROGRAM (fp);
1014 CACHE_PROGRAM ();
cee1d22c
AW
1015 NEXT;
1016}
1017
cf45ff03 1018VM_DEFINE_INSTRUCTION (60, tail_call_nargs, "tail-call/nargs", 0, 0, 1)
efbd5892
AW
1019{
1020 SCM x;
1021 POP (x);
1022 nargs = scm_to_int (x);
d51406fe 1023 /* FIXME: should truncate values? */
a5bbb22e 1024 goto vm_tail_call;
efbd5892
AW
1025}
1026
cf45ff03 1027VM_DEFINE_INSTRUCTION (61, call_nargs, "call/nargs", 0, 0, 1)
efbd5892
AW
1028{
1029 SCM x;
1030 POP (x);
1031 nargs = scm_to_int (x);
d51406fe 1032 /* FIXME: should truncate values? */
efbd5892
AW
1033 goto vm_call;
1034}
1035
cf45ff03 1036VM_DEFINE_INSTRUCTION (62, mv_call, "mv-call", 4, -1, 1)
a222b0fa 1037{
97fcf583 1038 scm_t_int32 offset;
e5dc27b8 1039 scm_t_uint8 *mvra;
67b699cc 1040 SCM *old_fp = fp;
a222b0fa
AW
1041
1042 nargs = FETCH ();
efbd5892 1043 FETCH_OFFSET (offset);
97fcf583 1044 mvra = ip + offset;
a222b0fa 1045
7d94e4af
AW
1046 VM_HANDLE_INTERRUPTS;
1047
67b699cc
AW
1048 fp = sp - nargs + 1;
1049
1050 ASSERT (SCM_FRAME_DYNAMIC_LINK (fp) == 0);
1051 ASSERT (SCM_FRAME_RETURN_ADDRESS (fp) == 0);
1052 ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp) == 0);
1053 SCM_FRAME_SET_DYNAMIC_LINK (fp, old_fp);
1054 SCM_FRAME_SET_RETURN_ADDRESS (fp, ip);
1055 SCM_FRAME_SET_MV_RETURN_ADDRESS (fp, mvra);
1056
1057 PUSH_CONTINUATION_HOOK ();
a222b0fa 1058
67b699cc 1059 program = fp[-1];
9b709b0f 1060
67b699cc
AW
1061 if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
1062 goto apply;
9b709b0f 1063
67b699cc 1064 CACHE_PROGRAM ();
75c3ed28 1065 ip = SCM_C_OBJCODE_BASE (bp);
67b699cc 1066
75c3ed28
AW
1067 APPLY_HOOK ();
1068 NEXT;
a222b0fa
AW
1069}
1070
cf45ff03 1071VM_DEFINE_INSTRUCTION (63, apply, "apply", 1, -1, 1)
3616e9e9 1072{
c8b9df71
KN
1073 int len;
1074 SCM ls;
1075 POP (ls);
1076
1077 nargs = FETCH ();
9a8cc8e7 1078 ASSERT (nargs >= 2);
c8b9df71
KN
1079
1080 len = scm_ilength (ls);
53bdfcf0
AW
1081 VM_ASSERT (len >= 0,
1082 vm_error_apply_to_non_list (ls));
fb10a008 1083 PUSH_LIST (ls, SCM_NULL_OR_NIL_P);
c8b9df71
KN
1084
1085 nargs += len - 2;
1086 goto vm_call;
3616e9e9
KN
1087}
1088
cf45ff03 1089VM_DEFINE_INSTRUCTION (64, tail_apply, "tail-apply", 1, -1, 1)
f03c31db
AW
1090{
1091 int len;
1092 SCM ls;
1093 POP (ls);
1094
1095 nargs = FETCH ();
9a8cc8e7 1096 ASSERT (nargs >= 2);
f03c31db
AW
1097
1098 len = scm_ilength (ls);
53bdfcf0
AW
1099 VM_ASSERT (len >= 0,
1100 vm_error_apply_to_non_list (ls));
fb10a008 1101 PUSH_LIST (ls, SCM_NULL_OR_NIL_P);
f03c31db
AW
1102
1103 nargs += len - 2;
a5bbb22e 1104 goto vm_tail_call;
f03c31db
AW
1105}
1106
cf45ff03 1107VM_DEFINE_INSTRUCTION (65, call_cc, "call/cc", 0, 1, 1)
17e90c5e 1108{
76282387 1109 int first;
d8873dfe 1110 SCM proc, vm_cont, cont;
76282387
AW
1111 POP (proc);
1112 SYNC_ALL ();
cee1d22c 1113 vm_cont = scm_i_vm_capture_stack (vp->stack_base, fp, sp, ip, NULL, 0);
d8873dfe 1114 cont = scm_i_make_continuation (&first, vm, vm_cont);
76282387
AW
1115 if (first)
1116 {
b2b33168
AW
1117 PUSH (SCM_PACK (0)); /* dynamic link */
1118 PUSH (SCM_PACK (0)); /* mvra */
1119 PUSH (SCM_PACK (0)); /* ra */
76282387
AW
1120 PUSH (proc);
1121 PUSH (cont);
1122 nargs = 1;
1123 goto vm_call;
1124 }
d8873dfe 1125 else
76282387 1126 {
f3120251
AW
1127 /* Otherwise, the vm continuation was reinstated, and
1128 vm_return_to_continuation pushed on one value. We know only one
1129 value was returned because we are in value context -- the
1130 previous block jumped to vm_call, not vm_mv_call, after all.
1131
1132 So, pull our regs back down from the vp, and march on to the
1133 next instruction. */
d8873dfe
AW
1134 CACHE_REGISTER ();
1135 program = SCM_FRAME_PROGRAM (fp);
1136 CACHE_PROGRAM ();
f3120251 1137 RESTORE_CONTINUATION_HOOK ();
76282387
AW
1138 NEXT;
1139 }
a98cef7e
KN
1140}
1141
cf45ff03 1142VM_DEFINE_INSTRUCTION (66, tail_call_cc, "tail-call/cc", 0, 1, 1)
f03c31db 1143{
76282387 1144 int first;
d8873dfe 1145 SCM proc, vm_cont, cont;
76282387
AW
1146 POP (proc);
1147 SYNC_ALL ();
d8873dfe
AW
1148 /* In contrast to call/cc, tail-call/cc captures the continuation without the
1149 stack frame. */
cee1d22c
AW
1150 vm_cont = scm_i_vm_capture_stack (vp->stack_base,
1151 SCM_FRAME_DYNAMIC_LINK (fp),
1152 SCM_FRAME_LOWER_ADDRESS (fp) - 1,
1153 SCM_FRAME_RETURN_ADDRESS (fp),
1154 SCM_FRAME_MV_RETURN_ADDRESS (fp),
1155 0);
d8873dfe 1156 cont = scm_i_make_continuation (&first, vm, vm_cont);
76282387
AW
1157 if (first)
1158 {
1159 PUSH (proc);
1160 PUSH (cont);
1161 nargs = 1;
a5bbb22e 1162 goto vm_tail_call;
76282387 1163 }
76282387
AW
1164 else
1165 {
d8873dfe 1166 /* Otherwise, cache regs and NEXT, as above. Invoking the continuation
f3120251
AW
1167 does a return from the frame, either to the RA or
1168 MVRA. */
d8873dfe
AW
1169 CACHE_REGISTER ();
1170 program = SCM_FRAME_PROGRAM (fp);
1171 CACHE_PROGRAM ();
f3120251
AW
1172 /* Unfortunately we don't know whether we are at the RA, and thus
1173 have one value without an nvalues marker, or we are at the
1174 MVRA and thus have multiple values and the nvalues
1175 marker. Instead of adding heuristics here, we will let hook
1176 client code do that. */
1177 RESTORE_CONTINUATION_HOOK ();
d8873dfe 1178 NEXT;
76282387 1179 }
f03c31db
AW
1180}
1181
cf45ff03 1182VM_DEFINE_INSTRUCTION (67, return, "return", 0, 1, 1)
a98cef7e 1183{
a98cef7e 1184 vm_return:
c45d4d77 1185 POP_CONTINUATION_HOOK (1);
e8c37772
AW
1186
1187 VM_HANDLE_INTERRUPTS;
1188
f13c269b 1189 {
03e6c165 1190 SCM ret;
f13c269b
AW
1191
1192 POP (ret);
6c6a4439
AW
1193
1194#ifdef VM_ENABLE_STACK_NULLING
1195 SCM *old_sp = sp;
1196#endif
f13c269b
AW
1197
1198 /* Restore registers */
1199 sp = SCM_FRAME_LOWER_ADDRESS (fp);
03e6c165
AW
1200 ip = SCM_FRAME_RETURN_ADDRESS (fp);
1201 fp = SCM_FRAME_DYNAMIC_LINK (fp);
6c6a4439 1202
11ea1aba 1203#ifdef VM_ENABLE_STACK_NULLING
6c6a4439 1204 NULLSTACK (old_sp - sp);
11ea1aba 1205#endif
f13c269b
AW
1206
1207 /* Set return value (sp is already pushed) */
1208 *sp = ret;
1209 }
17e90c5e 1210
15df3447 1211 /* Restore the last program */
af988bbf 1212 program = SCM_FRAME_PROGRAM (fp);
499a4c07 1213 CACHE_PROGRAM ();
7e4760e4 1214 CHECK_IP ();
a98cef7e
KN
1215 NEXT;
1216}
17e90c5e 1217
cf45ff03 1218VM_DEFINE_INSTRUCTION (68, return_values, "return/values", 1, -1, -1)
a222b0fa 1219{
ef24c01b
AW
1220 /* nvalues declared at top level, because for some reason gcc seems to think
1221 that perhaps it might be used without declaration. Fooey to that, I say. */
ef24c01b
AW
1222 nvalues = FETCH ();
1223 vm_return_values:
c45d4d77 1224 POP_CONTINUATION_HOOK (nvalues);
ef24c01b 1225
7d94e4af
AW
1226 VM_HANDLE_INTERRUPTS;
1227
03e6c165 1228 if (nvalues != 1 && SCM_FRAME_MV_RETURN_ADDRESS (fp))
ef24c01b 1229 {
6c6a4439
AW
1230 /* A multiply-valued continuation */
1231 SCM *vals = sp - nvalues;
ef24c01b
AW
1232 int i;
1233 /* Restore registers */
1234 sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
03e6c165
AW
1235 ip = SCM_FRAME_MV_RETURN_ADDRESS (fp);
1236 fp = SCM_FRAME_DYNAMIC_LINK (fp);
5e80f2ce 1237
ef24c01b
AW
1238 /* Push return values, and the number of values */
1239 for (i = 0; i < nvalues; i++)
6c6a4439 1240 *++sp = vals[i+1];
ef24c01b 1241 *++sp = SCM_I_MAKINUM (nvalues);
a222b0fa 1242
6c6a4439
AW
1243 /* Finally null the end of the stack */
1244 NULLSTACK (vals + nvalues - sp);
ef24c01b
AW
1245 }
1246 else if (nvalues >= 1)
1247 {
1248 /* Multiple values for a single-valued continuation -- here's where I
1249 break with guile tradition and try and do something sensible. (Also,
1250 this block handles the single-valued return to an mv
1251 continuation.) */
6c6a4439 1252 SCM *vals = sp - nvalues;
ef24c01b
AW
1253 /* Restore registers */
1254 sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
03e6c165
AW
1255 ip = SCM_FRAME_RETURN_ADDRESS (fp);
1256 fp = SCM_FRAME_DYNAMIC_LINK (fp);
5e80f2ce 1257
ef24c01b 1258 /* Push first value */
6c6a4439 1259 *++sp = vals[1];
a222b0fa 1260
6c6a4439
AW
1261 /* Finally null the end of the stack */
1262 NULLSTACK (vals + nvalues - sp);
ef24c01b
AW
1263 }
1264 else
53bdfcf0
AW
1265 {
1266 SYNC_ALL ();
1267 vm_error_no_values ();
1268 }
a222b0fa
AW
1269
1270 /* Restore the last program */
1271 program = SCM_FRAME_PROGRAM (fp);
1272 CACHE_PROGRAM ();
a222b0fa
AW
1273 CHECK_IP ();
1274 NEXT;
1275}
1276
cf45ff03 1277VM_DEFINE_INSTRUCTION (69, return_values_star, "return/values*", 1, -1, -1)
ef24c01b
AW
1278{
1279 SCM l;
1280
1281 nvalues = FETCH ();
11ea1aba 1282 ASSERT (nvalues >= 1);
ef24c01b
AW
1283
1284 nvalues--;
1285 POP (l);
9bd48cb1 1286 while (scm_is_pair (l))
ef24c01b
AW
1287 {
1288 PUSH (SCM_CAR (l));
1289 l = SCM_CDR (l);
1290 nvalues++;
1291 }
53bdfcf0 1292 VM_ASSERT (SCM_NULL_OR_NIL_P (l), vm_error_improper_list (l));
ef24c01b
AW
1293
1294 goto vm_return_values;
1295}
1296
cf45ff03 1297VM_DEFINE_INSTRUCTION (70, return_nvalues, "return/nvalues", 0, 1, -1)
2d9260d1
AW
1298{
1299 SCM n;
1300 POP (n);
1301 nvalues = scm_to_int (n);
1302 ASSERT (nvalues >= 0);
1303 goto vm_return_values;
1304}
1305
cf45ff03 1306VM_DEFINE_INSTRUCTION (71, truncate_values, "truncate-values", 2, -1, -1)
d51406fe
AW
1307{
1308 SCM x;
1309 int nbinds, rest;
1310 POP (x);
1311 nvalues = scm_to_int (x);
1312 nbinds = FETCH ();
1313 rest = FETCH ();
1314
1315 if (rest)
1316 nbinds--;
1317
53bdfcf0 1318 VM_ASSERT (nvalues >= nbinds, vm_error_not_enough_values ());
d51406fe
AW
1319
1320 if (rest)
1321 POP_LIST (nvalues - nbinds);
1322 else
1323 DROPN (nvalues - nbinds);
1324
1325 NEXT;
1326}
1327
cf45ff03 1328VM_DEFINE_INSTRUCTION (72, box, "box", 1, 1, 0)
a9b0f876 1329{
8d90b356
AW
1330 SCM val;
1331 POP (val);
1332 SYNC_BEFORE_GC ();
1333 LOCAL_SET (FETCH (), scm_cell (scm_tc7_variable, SCM_UNPACK (val)));
a9b0f876
AW
1334 NEXT;
1335}
1336
8d90b356
AW
1337/* for letrec:
1338 (let ((a *undef*) (b *undef*) ...)
1339 (set! a (lambda () (b ...)))
1340 ...)
1341 */
cf45ff03 1342VM_DEFINE_INSTRUCTION (73, empty_box, "empty-box", 1, 0, 0)
a9b0f876 1343{
8d90b356
AW
1344 SYNC_BEFORE_GC ();
1345 LOCAL_SET (FETCH (),
1346 scm_cell (scm_tc7_variable, SCM_UNPACK (SCM_UNDEFINED)));
1347 NEXT;
1348}
a9b0f876 1349
cf45ff03 1350VM_DEFINE_INSTRUCTION (74, local_boxed_ref, "local-boxed-ref", 1, 0, 1)
8d90b356
AW
1351{
1352 SCM v = LOCAL_REF (FETCH ());
1353 ASSERT_BOUND_VARIABLE (v);
1354 PUSH (VARIABLE_REF (v));
1355 NEXT;
1356}
a9b0f876 1357
cf45ff03 1358VM_DEFINE_INSTRUCTION (75, local_boxed_set, "local-boxed-set", 1, 1, 0)
8d90b356
AW
1359{
1360 SCM v, val;
1361 v = LOCAL_REF (FETCH ());
1362 POP (val);
1363 ASSERT_VARIABLE (v);
1364 VARIABLE_SET (v, val);
a9b0f876
AW
1365 NEXT;
1366}
1367
cf45ff03 1368VM_DEFINE_INSTRUCTION (76, free_ref, "free-ref", 1, 0, 1)
a9b0f876 1369{
8d90b356
AW
1370 scm_t_uint8 idx = FETCH ();
1371
57ab0671
AW
1372 CHECK_FREE_VARIABLE (idx);
1373 PUSH (FREE_VARIABLE_REF (idx));
8d90b356
AW
1374 NEXT;
1375}
a9b0f876 1376
57ab0671 1377/* no free-set -- if a var is assigned, it should be in a box */
a9b0f876 1378
cf45ff03 1379VM_DEFINE_INSTRUCTION (77, free_boxed_ref, "free-boxed-ref", 1, 0, 1)
8d90b356
AW
1380{
1381 SCM v;
1382 scm_t_uint8 idx = FETCH ();
57ab0671
AW
1383 CHECK_FREE_VARIABLE (idx);
1384 v = FREE_VARIABLE_REF (idx);
8d90b356
AW
1385 ASSERT_BOUND_VARIABLE (v);
1386 PUSH (VARIABLE_REF (v));
1387 NEXT;
1388}
1389
cf45ff03 1390VM_DEFINE_INSTRUCTION (78, free_boxed_set, "free-boxed-set", 1, 1, 0)
8d90b356
AW
1391{
1392 SCM v, val;
1393 scm_t_uint8 idx = FETCH ();
1394 POP (val);
57ab0671
AW
1395 CHECK_FREE_VARIABLE (idx);
1396 v = FREE_VARIABLE_REF (idx);
8d90b356
AW
1397 ASSERT_BOUND_VARIABLE (v);
1398 VARIABLE_SET (v, val);
1399 NEXT;
1400}
1401
cf45ff03 1402VM_DEFINE_INSTRUCTION (79, make_closure, "make-closure", 2, -1, 1)
8d90b356 1403{
6f16379e
AW
1404 size_t n, len;
1405 SCM closure;
1406
1407 len = FETCH ();
1408 len <<= 8;
1409 len += FETCH ();
8d90b356 1410 SYNC_BEFORE_GC ();
6f16379e
AW
1411 closure = scm_words (scm_tc7_program | (len<<16), len + 3);
1412 SCM_SET_CELL_OBJECT_1 (closure, SCM_PROGRAM_OBJCODE (sp[-len]));
1413 SCM_SET_CELL_OBJECT_2 (closure, SCM_PROGRAM_OBJTABLE (sp[-len]));
1414 sp[-len] = closure;
1415 for (n = 0; n < len; n++)
1416 SCM_PROGRAM_FREE_VARIABLE_SET (closure, n, sp[-len + 1 + n]);
1417 DROPN (len);
a9b0f876
AW
1418 NEXT;
1419}
1420
cf45ff03 1421VM_DEFINE_INSTRUCTION (80, make_variable, "make-variable", 0, 0, 1)
80545853
AW
1422{
1423 SYNC_BEFORE_GC ();
1424 /* fixme underflow */
1425 PUSH (scm_cell (scm_tc7_variable, SCM_UNPACK (SCM_UNDEFINED)));
1426 NEXT;
1427}
1428
cf45ff03 1429VM_DEFINE_INSTRUCTION (81, fix_closure, "fix-closure", 2, -1, 0)
c21c89b1 1430{
6f16379e 1431 SCM x;
c21c89b1 1432 unsigned int i = FETCH ();
6f16379e 1433 size_t n, len;
c21c89b1
AW
1434 i <<= 8;
1435 i += FETCH ();
c21c89b1
AW
1436 /* FIXME CHECK_LOCAL (i) */
1437 x = LOCAL_REF (i);
1438 /* FIXME ASSERT_PROGRAM (x); */
6f16379e
AW
1439 len = SCM_PROGRAM_NUM_FREE_VARIABLES (x);
1440 for (n = 0; n < len; n++)
1441 SCM_PROGRAM_FREE_VARIABLE_SET (x, n, sp[-len + 1 + n]);
1442 DROPN (len);
c21c89b1
AW
1443 NEXT;
1444}
1445
cf45ff03 1446VM_DEFINE_INSTRUCTION (82, define, "define", 0, 0, 2)
94ff26b9
AW
1447{
1448 SCM sym, val;
eae2438d 1449 POP2 (sym, val);
94ff26b9 1450 SYNC_REGISTER ();
62e15979 1451 scm_define (sym, val);
94ff26b9
AW
1452 NEXT;
1453}
1454
cf45ff03 1455VM_DEFINE_INSTRUCTION (83, make_keyword, "make-keyword", 0, 1, 1)
94ff26b9
AW
1456{
1457 CHECK_UNDERFLOW ();
1458 SYNC_REGISTER ();
1459 *sp = scm_symbol_to_keyword (*sp);
1460 NEXT;
1461}
1462
cf45ff03 1463VM_DEFINE_INSTRUCTION (84, make_symbol, "make-symbol", 0, 1, 1)
94ff26b9
AW
1464{
1465 CHECK_UNDERFLOW ();
1466 SYNC_REGISTER ();
1467 *sp = scm_string_to_symbol (*sp);
1468 NEXT;
1469}
1470
cf45ff03 1471VM_DEFINE_INSTRUCTION (85, prompt, "prompt", 4, 2, 0)
4f66bcde
AW
1472{
1473 scm_t_int32 offset;
ea6b18e8 1474 scm_t_uint8 escape_only_p;
747022e4 1475 SCM k, prompt;
4f66bcde 1476
4f66bcde
AW
1477 escape_only_p = FETCH ();
1478 FETCH_OFFSET (offset);
4f66bcde
AW
1479 POP (k);
1480
1481 SYNC_REGISTER ();
d2964315 1482 /* Push the prompt onto the dynamic stack. */
adbdfd6d
AW
1483 prompt = scm_c_make_prompt (k, fp, sp, ip + offset, escape_only_p, vm_cookie,
1484 scm_i_dynwinds ());
1485 scm_i_set_dynwinds (scm_cons (prompt, SCM_PROMPT_DYNWINDS (prompt)));
adaf86ec 1486 if (SCM_PROMPT_SETJMP (prompt))
4f66bcde
AW
1487 {
1488 /* The prompt exited nonlocally. Cache the regs back from the vp, and go
ea6b18e8 1489 to the handler.
d2964315
AW
1490
1491 Note, at this point, we must assume that any variable local to
1492 vm_engine that can be assigned *has* been assigned. So we need to pull
1493 all our state back from the ip/fp/sp.
ea6b18e8 1494 */
d2964315
AW
1495 CACHE_REGISTER ();
1496 program = SCM_FRAME_PROGRAM (fp);
1497 CACHE_PROGRAM ();
f3120251
AW
1498 /* The stack contains the values returned to this prompt, along
1499 with a number-of-values marker -- like an MV return. */
1500 ABORT_CONTINUATION_HOOK ();
4f66bcde
AW
1501 NEXT;
1502 }
1503
1504 /* Otherwise setjmp returned for the first time, so we go to execute the
1505 prompt's body. */
1506 NEXT;
1507}
1508
cf45ff03 1509VM_DEFINE_INSTRUCTION (86, wind, "wind", 0, 2, 0)
4f66bcde
AW
1510{
1511 SCM wind, unwind;
eae2438d 1512 POP2 (unwind, wind);
4f66bcde
AW
1513 SYNC_REGISTER ();
1514 /* Push wind and unwind procedures onto the dynamic stack. Note that neither
1515 are actually called; the compiler should emit calls to wind and unwind for
1516 the normal dynamic-wind control flow. */
e9c898bf
LC
1517 VM_ASSERT (scm_to_bool (scm_thunk_p (wind)),
1518 vm_error_not_a_thunk ("dynamic-wind", wind));
1519 VM_ASSERT (scm_to_bool (scm_thunk_p (unwind)),
1520 vm_error_not_a_thunk ("dynamic-wind", unwind));
4f66bcde
AW
1521 scm_i_set_dynwinds (scm_cons (scm_cons (wind, unwind), scm_i_dynwinds ()));
1522 NEXT;
1523}
1524
cf45ff03 1525VM_DEFINE_INSTRUCTION (87, abort, "abort", 1, -1, -1)
4f66bcde
AW
1526{
1527 unsigned n = FETCH ();
4f66bcde 1528 SYNC_REGISTER ();
53bdfcf0 1529 PRE_CHECK_UNDERFLOW (n + 2);
cee1d22c 1530 vm_abort (vm, n, vm_cookie);
6e84cb95 1531 /* vm_abort should not return */
4f66bcde
AW
1532 abort ();
1533}
1534
cf45ff03 1535VM_DEFINE_INSTRUCTION (88, unwind, "unwind", 0, 0, 0)
4f66bcde
AW
1536{
1537 /* A normal exit from the dynamic extent of an expression. Pop the top entry
1538 off of the dynamic stack. */
1539 scm_i_set_dynwinds (scm_cdr (scm_i_dynwinds ()));
1540 NEXT;
1541}
1542
cf45ff03 1543VM_DEFINE_INSTRUCTION (89, wind_fluids, "wind-fluids", 1, -1, 0)
e084b27e
AW
1544{
1545 unsigned n = FETCH ();
1546 SCM wf;
1547
f7cea645 1548 SYNC_REGISTER ();
2b41a37b
AW
1549 sp -= 2 * n;
1550 CHECK_UNDERFLOW ();
1551 wf = scm_i_make_with_fluids (n, sp + 1, sp + 1 + n);
1552 NULLSTACK (2 * n);
1553
a2a6c0e3 1554 scm_i_swap_with_fluids (wf, current_thread->dynamic_state);
e084b27e
AW
1555 scm_i_set_dynwinds (scm_cons (wf, scm_i_dynwinds ()));
1556 NEXT;
1557}
1558
cf45ff03 1559VM_DEFINE_INSTRUCTION (90, unwind_fluids, "unwind-fluids", 0, 0, 0)
e084b27e
AW
1560{
1561 SCM wf;
1562 wf = scm_car (scm_i_dynwinds ());
1563 scm_i_set_dynwinds (scm_cdr (scm_i_dynwinds ()));
a2a6c0e3 1564 scm_i_swap_with_fluids (wf, current_thread->dynamic_state);
e084b27e
AW
1565 NEXT;
1566}
4f66bcde 1567
cf45ff03 1568VM_DEFINE_INSTRUCTION (91, fluid_ref, "fluid-ref", 0, 1, 1)
1e7a0337
AW
1569{
1570 size_t num;
1571 SCM fluids;
1572
1573 CHECK_UNDERFLOW ();
a2a6c0e3 1574 fluids = SCM_I_DYNAMIC_STATE_FLUIDS (current_thread->dynamic_state);
6f8d7b12 1575 if (SCM_UNLIKELY (!SCM_FLUID_P (*sp))
1e7a0337
AW
1576 || ((num = SCM_I_FLUID_NUM (*sp)) >= SCM_SIMPLE_VECTOR_LENGTH (fluids)))
1577 {
1578 /* Punt dynstate expansion and error handling to the C proc. */
1579 SYNC_REGISTER ();
1580 *sp = scm_fluid_ref (*sp);
1581 }
1582 else
ef94624e
BT
1583 {
1584 SCM val = SCM_SIMPLE_VECTOR_REF (fluids, num);
aafb4ed7
AW
1585 if (scm_is_eq (val, SCM_UNDEFINED))
1586 val = SCM_I_FLUID_DEFAULT (*sp);
53bdfcf0
AW
1587 VM_ASSERT (!scm_is_eq (val, SCM_UNDEFINED),
1588 vm_error_unbound_fluid (program, *sp));
ef94624e
BT
1589 *sp = val;
1590 }
1e7a0337
AW
1591
1592 NEXT;
1593}
1594
cf45ff03 1595VM_DEFINE_INSTRUCTION (92, fluid_set, "fluid-set", 0, 2, 0)
1e7a0337
AW
1596{
1597 size_t num;
1598 SCM val, fluid, fluids;
1599
eae2438d 1600 POP2 (val, fluid);
a2a6c0e3 1601 fluids = SCM_I_DYNAMIC_STATE_FLUIDS (current_thread->dynamic_state);
6f8d7b12 1602 if (SCM_UNLIKELY (!SCM_FLUID_P (fluid))
1e7a0337
AW
1603 || ((num = SCM_I_FLUID_NUM (fluid)) >= SCM_SIMPLE_VECTOR_LENGTH (fluids)))
1604 {
1605 /* Punt dynstate expansion and error handling to the C proc. */
1606 SYNC_REGISTER ();
1607 scm_fluid_set_x (fluid, val);
1608 }
1609 else
1610 SCM_SIMPLE_VECTOR_SET (fluids, num, val);
a39b116f 1611
1e7a0337
AW
1612 NEXT;
1613}
1614
cf45ff03 1615VM_DEFINE_INSTRUCTION (93, assert_nargs_ee_locals, "assert-nargs-ee/locals", 1, 0, 0)
de45d8ee
AW
1616{
1617 scm_t_ptrdiff n;
1618 SCM *old_sp;
1619
1620 /* nargs = n & 0x7, nlocs = nargs + (n >> 3) */
1621 n = FETCH ();
1622
53bdfcf0
AW
1623 VM_ASSERT (sp - (fp - 1) == (n & 0x7),
1624 vm_error_wrong_num_args (program));
de45d8ee
AW
1625
1626 old_sp = sp;
1627 sp += (n >> 3);
1628 CHECK_OVERFLOW ();
1629 while (old_sp < sp)
1630 *++old_sp = SCM_UNDEFINED;
1631
1632 NEXT;
1633}
1634
581f410f
AW
1635/* Like bind-optionals/shuffle, but if there are too many positional
1636 arguments, jumps to the next case-lambda clause. */
1637VM_DEFINE_INSTRUCTION (94, bind_optionals_shuffle_or_br, "bind-optionals/shuffle-or-br", 9, -1, -1)
1638{
1639 SCM *walk;
1640 scm_t_ptrdiff nreq, nreq_and_opt, ntotal;
1641 scm_t_int32 offset;
1642 nreq = FETCH () << 8;
1643 nreq += FETCH ();
1644 nreq_and_opt = FETCH () << 8;
1645 nreq_and_opt += FETCH ();
1646 ntotal = FETCH () << 8;
1647 ntotal += FETCH ();
1648 FETCH_OFFSET (offset);
1649
1650 /* look in optionals for first keyword or last positional */
1651 /* starting after the last required positional arg */
1652 walk = fp + nreq;
1653 while (/* while we have args */
1654 walk <= sp
1655 /* and we still have positionals to fill */
1656 && walk - fp < nreq_and_opt
1657 /* and we haven't reached a keyword yet */
1658 && !scm_is_keyword (*walk))
1659 /* bind this optional arg (by leaving it in place) */
1660 walk++;
1661 if (/* If we have filled all the positionals */
1662 walk - fp == nreq_and_opt
1663 /* and there are still more arguments */
1664 && walk <= sp
1665 /* and the next argument is not a keyword, */
1666 && !scm_is_keyword (*walk))
1667 {
1668 /* Jump to the next case-lambda* clause. */
1669 ip += offset;
1670 }
1671 else
1672 {
1673 /* Otherwise, finish as in bind-optionals/shuffle: shuffle up,
1674 from walk to ntotal */
1675 scm_t_ptrdiff nshuf = sp - walk + 1, i;
1676 sp = (fp - 1) + ntotal + nshuf;
1677 CHECK_OVERFLOW ();
1678 for (i = 0; i < nshuf; i++)
1679 sp[-i] = walk[nshuf-i-1];
1680
1681 /* and fill optionals & keyword args with SCM_UNDEFINED */
1682 while (walk <= (fp - 1) + ntotal)
1683 *walk++ = SCM_UNDEFINED;
1684 }
1685
1686 NEXT;
1687}
1688
8d90b356 1689
53e28ed9
AW
1690/*
1691(defun renumber-ops ()
1692 "start from top of buffer and renumber 'VM_DEFINE_FOO (\n' sequences"
1693 (interactive "")
1694 (save-excursion
1695 (let ((counter -1)) (goto-char (point-min))
1696 (while (re-search-forward "^VM_DEFINE_[^ ]+ (\\([^,]+\\)," (point-max) t)
1697 (replace-match
1698 (number-to-string (setq counter (1+ counter)))
1699 t t nil 1)))))
ff810079 1700(renumber-ops)
53e28ed9 1701*/
17e90c5e
KN
1702/*
1703 Local Variables:
1704 c-file-style: "gnu"
1705 End:
1706*/