1 /* Copyright (C) 2001,2008,2009,2010,2011,2012 Free Software Foundation, Inc.
3 * This library is free software; you can redistribute it and/or
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.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
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
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 /* This file is included in vm_engine.c */
27 VM_DEFINE_INSTRUCTION (0, nop
, "nop", 0, 0, 0)
32 VM_DEFINE_INSTRUCTION (1, halt
, "halt", 0, 0, 0)
36 nvalues
= SCM_I_INUM (*sp
--);
46 ret
= scm_c_values (sp
+ 1, nvalues
);
51 #ifdef VM_ENABLE_STACK_NULLING
55 /* Restore registers */
56 sp
= SCM_FRAME_LOWER_ADDRESS (fp
) - 1;
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
60 ip
= SCM_FRAME_RETURN_ADDRESS (fp
);
61 fp
= SCM_FRAME_DYNAMIC_LINK (fp
);
62 NULLSTACK (old_sp
- sp
);
69 VM_DEFINE_INSTRUCTION (2, drop
, "drop", 0, 1, 0)
75 VM_DEFINE_INSTRUCTION (3, dup
, "dup", 0, 0, 1)
87 VM_DEFINE_INSTRUCTION (4, void, "void", 0, 0, 1)
89 PUSH (SCM_UNSPECIFIED
);
93 VM_DEFINE_INSTRUCTION (5, make_true
, "make-true", 0, 0, 1)
99 VM_DEFINE_INSTRUCTION (6, make_false
, "make-false", 0, 0, 1)
105 VM_DEFINE_INSTRUCTION (7, make_nil
, "make-nil", 0, 0, 1)
107 PUSH (SCM_ELISP_NIL
);
111 VM_DEFINE_INSTRUCTION (8, make_eol
, "make-eol", 0, 0, 1)
117 VM_DEFINE_INSTRUCTION (9, make_int8
, "make-int8", 1, 0, 1)
119 PUSH (SCM_I_MAKINUM ((signed char) FETCH ()));
123 VM_DEFINE_INSTRUCTION (10, make_int8_0
, "make-int8:0", 0, 0, 1)
129 VM_DEFINE_INSTRUCTION (11, make_int8_1
, "make-int8:1", 0, 0, 1)
131 PUSH (SCM_I_MAKINUM (1));
135 VM_DEFINE_INSTRUCTION (12, make_int16
, "make-int16", 2, 0, 1)
139 PUSH (SCM_I_MAKINUM ((signed short) (h
<< 8) + l
));
143 VM_DEFINE_INSTRUCTION (13, make_int64
, "make-int64", 8, 0, 1)
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
));
158 VM_DEFINE_INSTRUCTION (14, make_uint64
, "make-uint64", 8, 0, 1)
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
));
173 VM_DEFINE_INSTRUCTION (15, make_char8
, "make-char8", 1, 0, 1)
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. */
185 VM_DEFINE_INSTRUCTION (16, make_char32
, "make-char32", 4, 0, 1)
189 v
<<= 8; v
+= FETCH ();
190 v
<<= 8; v
+= FETCH ();
191 v
<<= 8; v
+= FETCH ();
192 PUSH (SCM_MAKE_CHAR (v
));
198 VM_DEFINE_INSTRUCTION (17, list
, "list", 2, -1, 1)
200 unsigned h
= FETCH ();
201 unsigned l
= FETCH ();
202 unsigned len
= ((h
<< 8) + l
);
207 VM_DEFINE_INSTRUCTION (18, vector
, "vector", 2, -1, 1)
209 unsigned h
= FETCH ();
210 unsigned l
= FETCH ();
211 unsigned len
= ((h
<< 8) + l
);
217 vect
= scm_make_vector (scm_from_uint (len
), SCM_BOOL_F
);
218 memcpy (SCM_I_VECTOR_WELTS(vect
), sp
, sizeof(SCM
) * len
);
230 #define OBJECT_REF(i) objects[i]
231 #define OBJECT_SET(i,o) objects[i] = o
233 #define LOCAL_REF(i) SCM_FRAME_VARIABLE (fp, i)
234 #define LOCAL_SET(i,o) SCM_FRAME_VARIABLE (fp, i) = o
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)
241 #define VARIABLE_BOUNDP(v) (!scm_is_eq (VARIABLE_REF (v), SCM_UNDEFINED))
243 #define FREE_VARIABLE_REF(i) SCM_PROGRAM_FREE_VARIABLE_REF (program, i)
247 VM_DEFINE_INSTRUCTION (19, object_ref
, "object-ref", 1, 0, 1)
249 register unsigned objnum
= FETCH ();
250 CHECK_OBJECT (objnum
);
251 PUSH (OBJECT_REF (objnum
));
255 /* FIXME: necessary? elt 255 of the vector could be a vector... */
256 VM_DEFINE_INSTRUCTION (20, long_object_ref
, "long-object-ref", 2, 0, 1)
258 unsigned int objnum
= FETCH ();
261 CHECK_OBJECT (objnum
);
262 PUSH (OBJECT_REF (objnum
));
266 VM_DEFINE_INSTRUCTION (21, local_ref
, "local-ref", 1, 0, 1)
268 PUSH (LOCAL_REF (FETCH ()));
273 VM_DEFINE_INSTRUCTION (22, long_local_ref
, "long-local-ref", 2, 0, 1)
275 unsigned int i
= FETCH ();
278 PUSH (LOCAL_REF (i
));
283 VM_DEFINE_INSTRUCTION (23, local_bound
, "local-bound?", 1, 0, 1)
285 PUSH (scm_from_bool (!scm_is_eq (LOCAL_REF (FETCH ()), SCM_UNDEFINED
)));
289 VM_DEFINE_INSTRUCTION (24, long_local_bound
, "long-local-bound?", 2, 0, 1)
291 unsigned int i
= FETCH ();
294 PUSH (scm_from_bool (!scm_is_eq (LOCAL_REF (i
), SCM_UNDEFINED
)));
298 VM_DEFINE_INSTRUCTION (25, variable_ref
, "variable-ref", 0, 1, 1)
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
306 VM_ASSERT (SCM_VARIABLEP (x
),
307 vm_error_not_a_variable ("variable-ref", x
));
309 if (SCM_UNLIKELY (!VARIABLE_BOUNDP (x
)))
314 /* Attempt to provide the variable name in the error message. */
315 var_name
= scm_module_reverse_lookup (scm_current_module (), x
);
316 vm_error_unbound (program
, scm_is_true (var_name
) ? var_name
: x
);
320 SCM o
= VARIABLE_REF (x
);
327 VM_DEFINE_INSTRUCTION (26, variable_bound
, "variable-bound?", 0, 1, 1)
331 VM_ASSERT (SCM_VARIABLEP (x
),
332 vm_error_not_a_variable ("variable-bound?", x
));
334 *sp
= scm_from_bool (VARIABLE_BOUNDP (x
));
338 VM_DEFINE_INSTRUCTION (27, toplevel_ref
, "toplevel-ref", 1, 0, 1)
340 unsigned objnum
= FETCH ();
342 CHECK_OBJECT (objnum
);
343 what
= OBJECT_REF (objnum
);
345 if (!SCM_VARIABLEP (what
))
348 resolved
= resolve_variable (what
, scm_program_module (program
));
349 VM_ASSERT (VARIABLE_BOUNDP (resolved
), vm_error_unbound (program
, what
));
351 OBJECT_SET (objnum
, what
);
354 PUSH (VARIABLE_REF (what
));
358 VM_DEFINE_INSTRUCTION (28, long_toplevel_ref
, "long-toplevel-ref", 2, 0, 1)
361 unsigned int objnum
= FETCH ();
364 CHECK_OBJECT (objnum
);
365 what
= OBJECT_REF (objnum
);
367 if (!SCM_VARIABLEP (what
))
370 resolved
= resolve_variable (what
, scm_program_module (program
));
371 VM_ASSERT (VARIABLE_BOUNDP (resolved
),
372 vm_error_unbound (program
, what
));
374 OBJECT_SET (objnum
, what
);
377 PUSH (VARIABLE_REF (what
));
383 VM_DEFINE_INSTRUCTION (29, local_set
, "local-set", 1, 1, 0)
387 LOCAL_SET (FETCH (), x
);
391 VM_DEFINE_INSTRUCTION (30, long_local_set
, "long-local-set", 2, 1, 0)
394 unsigned int i
= FETCH ();
402 VM_DEFINE_INSTRUCTION (31, variable_set
, "variable-set", 0, 2, 0)
404 VM_ASSERT (SCM_VARIABLEP (sp
[0]),
405 vm_error_not_a_variable ("variable-set!", sp
[0]));
406 VARIABLE_SET (sp
[0], sp
[-1]);
411 VM_DEFINE_INSTRUCTION (32, toplevel_set
, "toplevel-set", 1, 1, 0)
413 unsigned objnum
= FETCH ();
415 CHECK_OBJECT (objnum
);
416 what
= OBJECT_REF (objnum
);
418 if (!SCM_VARIABLEP (what
))
421 what
= resolve_variable (what
, scm_program_module (program
));
422 OBJECT_SET (objnum
, what
);
425 VARIABLE_SET (what
, *sp
);
430 VM_DEFINE_INSTRUCTION (33, long_toplevel_set
, "long-toplevel-set", 2, 1, 0)
433 unsigned int objnum
= FETCH ();
436 CHECK_OBJECT (objnum
);
437 what
= OBJECT_REF (objnum
);
439 if (!SCM_VARIABLEP (what
))
442 what
= resolve_variable (what
, scm_program_module (program
));
443 OBJECT_SET (objnum
, what
);
446 VARIABLE_SET (what
, *sp
);
456 /* offset must be at least 24 bits wide, and signed */
457 #define FETCH_OFFSET(offset) \
459 offset = FETCH () << 16; \
460 offset += FETCH () << 8; \
461 offset += FETCH (); \
462 offset -= (offset & (1<<23)) << 1; \
467 scm_t_int32 offset; \
468 FETCH_OFFSET (offset); \
472 VM_HANDLE_INTERRUPTS; \
476 VM_DEFINE_INSTRUCTION (34, br
, "br", 3, 0, 0)
479 FETCH_OFFSET (offset
);
482 VM_HANDLE_INTERRUPTS
;
486 VM_DEFINE_INSTRUCTION (35, br_if
, "br-if", 3, 0, 0)
490 BR (scm_is_true (x
));
493 VM_DEFINE_INSTRUCTION (36, br_if_not
, "br-if-not", 3, 0, 0)
497 BR (scm_is_false (x
));
500 VM_DEFINE_INSTRUCTION (37, br_if_eq
, "br-if-eq", 3, 0, 0)
504 BR (scm_is_eq (x
, y
));
507 VM_DEFINE_INSTRUCTION (38, br_if_not_eq
, "br-if-not-eq", 3, 0, 0)
511 BR (!scm_is_eq (x
, y
));
514 VM_DEFINE_INSTRUCTION (39, br_if_null
, "br-if-null", 3, 0, 0)
518 BR (scm_is_null (x
));
521 VM_DEFINE_INSTRUCTION (40, br_if_not_null
, "br-if-not-null", 3, 0, 0)
525 BR (!scm_is_null (x
));
533 VM_DEFINE_INSTRUCTION (41, br_if_nargs_ne
, "br-if-nargs-ne", 5, 0, 0)
539 FETCH_OFFSET (offset
);
540 if (sp
- (fp
- 1) != n
)
545 VM_DEFINE_INSTRUCTION (42, br_if_nargs_lt
, "br-if-nargs-lt", 5, 0, 0)
551 FETCH_OFFSET (offset
);
552 if (sp
- (fp
- 1) < n
)
557 VM_DEFINE_INSTRUCTION (43, br_if_nargs_gt
, "br-if-nargs-gt", 5, 0, 0)
564 FETCH_OFFSET (offset
);
565 if (sp
- (fp
- 1) > n
)
570 VM_DEFINE_INSTRUCTION (44, assert_nargs_ee
, "assert-nargs-ee", 2, 0, 0)
575 VM_ASSERT (sp
- (fp
- 1) == n
,
576 vm_error_wrong_num_args (program
));
580 VM_DEFINE_INSTRUCTION (45, assert_nargs_ge
, "assert-nargs-ge", 2, 0, 0)
585 VM_ASSERT (sp
- (fp
- 1) >= n
,
586 vm_error_wrong_num_args (program
));
590 VM_DEFINE_INSTRUCTION (46, bind_optionals
, "bind-optionals", 2, -1, -1)
595 while (sp
- (fp
- 1) < n
)
596 PUSH (SCM_UNDEFINED
);
600 VM_DEFINE_INSTRUCTION (47, bind_optionals_shuffle
, "bind-optionals/shuffle", 6, -1, -1)
603 scm_t_ptrdiff nreq
, nreq_and_opt
, ntotal
;
604 nreq
= FETCH () << 8;
606 nreq_and_opt
= FETCH () << 8;
607 nreq_and_opt
+= FETCH ();
608 ntotal
= FETCH () << 8;
611 /* look in optionals for first keyword or last positional */
612 /* starting after the last required positional arg */
614 while (/* while we have args */
616 /* and we still have positionals to fill */
617 && walk
- fp
< nreq_and_opt
618 /* and we haven't reached a keyword yet */
619 && !scm_is_keyword (*walk
))
620 /* bind this optional arg (by leaving it in place) */
622 /* now shuffle up, from walk to ntotal */
624 scm_t_ptrdiff nshuf
= sp
- walk
+ 1, i
;
625 sp
= (fp
- 1) + ntotal
+ nshuf
;
627 for (i
= 0; i
< nshuf
; i
++)
628 sp
[-i
] = walk
[nshuf
-i
-1];
630 /* and fill optionals & keyword args with SCM_UNDEFINED */
631 while (walk
<= (fp
- 1) + ntotal
)
632 *walk
++ = SCM_UNDEFINED
;
637 /* Flags that determine whether other keywords are allowed, and whether a
638 rest argument is expected. These values must match those used by the
639 glil->assembly compiler. */
640 #define F_ALLOW_OTHER_KEYS 1
643 VM_DEFINE_INSTRUCTION (48, bind_kwargs
, "bind-kwargs", 5, 0, 0)
647 int kw_and_rest_flags
;
651 /* XXX: We don't actually use NKW. */
654 kw_and_rest_flags
= FETCH ();
656 VM_ASSERT ((kw_and_rest_flags
& F_REST
)
657 || ((sp
- (fp
- 1) - nkw
) % 2) == 0,
658 vm_error_kwargs_length_not_even (program
))
661 kw
= OBJECT_REF (idx
);
663 /* Switch NKW to be a negative index below SP. */
664 for (nkw
= -(sp
- (fp
- 1) - nkw
) + 1; nkw
< 0; nkw
++)
668 if (scm_is_keyword (sp
[nkw
]))
670 for (walk
= kw
; scm_is_pair (walk
); walk
= SCM_CDR (walk
))
672 if (scm_is_eq (SCM_CAAR (walk
), sp
[nkw
]))
674 SCM si
= SCM_CDAR (walk
);
675 LOCAL_SET (SCM_I_INUMP (si
) ? SCM_I_INUM (si
) : scm_to_long (si
),
680 VM_ASSERT (scm_is_pair (walk
)
681 || (kw_and_rest_flags
& F_ALLOW_OTHER_KEYS
),
682 vm_error_kwargs_unrecognized_keyword (program
));
686 VM_ASSERT (kw_and_rest_flags
& F_REST
,
687 vm_error_kwargs_invalid_keyword (program
));
693 #undef F_ALLOW_OTHER_KEYS
697 VM_DEFINE_INSTRUCTION (49, push_rest
, "push-rest", 2, -1, -1)
703 while (sp
- (fp
- 1) > n
)
704 /* No need to check for underflow. */
705 CONS (rest
, *sp
--, rest
);
710 VM_DEFINE_INSTRUCTION (50, bind_rest
, "bind-rest", 4, -1, -1)
719 while (sp
- (fp
- 1) > n
)
720 /* No need to check for underflow. */
721 CONS (rest
, *sp
--, rest
);
726 VM_DEFINE_INSTRUCTION (51, reserve_locals
, "reserve-locals", 2, -1, -1)
739 *++old_sp
= SCM_UNDEFINED
;
742 NULLSTACK (old_sp
- sp
);
747 VM_DEFINE_INSTRUCTION (52, new_frame
, "new-frame", 0, 0, 3)
749 /* NB: if you change this, see frames.c:vm-frame-num-locals */
750 /* and frames.h, vm-engine.c, etc of course */
752 /* We don't initialize the dynamic link here because we don't actually
753 know that this frame will point to the current fp: it could be
754 placed elsewhere on the stack if captured in a partial
755 continuation, and invoked from some other context. */
756 PUSH (SCM_PACK (0)); /* dynamic link */
757 PUSH (SCM_PACK (0)); /* mvra */
758 PUSH (SCM_PACK (0)); /* ra */
762 VM_DEFINE_INSTRUCTION (53, call
, "call", 1, -1, 1)
767 VM_HANDLE_INTERRUPTS
;
774 ASSERT (SCM_FRAME_DYNAMIC_LINK (fp
) == 0);
775 ASSERT (SCM_FRAME_RETURN_ADDRESS (fp
) == 0);
776 ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp
) == 0);
777 SCM_FRAME_SET_DYNAMIC_LINK (fp
, old_fp
);
778 SCM_FRAME_SET_RETURN_ADDRESS (fp
, ip
);
779 SCM_FRAME_SET_MV_RETURN_ADDRESS (fp
, 0);
782 PUSH_CONTINUATION_HOOK ();
786 if (SCM_UNLIKELY (!SCM_PROGRAM_P (program
)))
790 ip
= SCM_C_OBJCODE_BASE (bp
);
796 VM_DEFINE_INSTRUCTION (54, tail_call
, "tail-call", 1, -1, 1)
801 VM_HANDLE_INTERRUPTS
;
805 #ifdef VM_ENABLE_STACK_NULLING
810 /* shuffle down the program and the arguments */
811 for (i
= -1, sp
= sp
- nargs
+ 1; i
< nargs
; i
++)
812 SCM_FRAME_STACK_ADDRESS (fp
)[i
] = sp
[i
];
816 NULLSTACK (old_sp
- sp
);
821 if (SCM_UNLIKELY (!SCM_PROGRAM_P (program
)))
825 ip
= SCM_C_OBJCODE_BASE (bp
);
831 VM_DEFINE_INSTRUCTION (55, subr_call
, "subr-call", 1, -1, -1)
839 subr
= SCM_POINTER_VALUE (pointer
);
841 VM_HANDLE_INTERRUPTS
;
853 ret
= subr (sp
[-1], sp
[0]);
856 ret
= subr (sp
[-2], sp
[-1], sp
[0]);
859 ret
= subr (sp
[-3], sp
[-2], sp
[-1], sp
[0]);
862 ret
= subr (sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
865 ret
= subr (sp
[-5], sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
868 ret
= subr (sp
[-6], sp
[-5], sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
871 ret
= subr (sp
[-7], sp
[-6], sp
[-5], sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
874 ret
= subr (sp
[-8], sp
[-7], sp
[-6], sp
[-5], sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
877 ret
= subr (sp
[-9], sp
[-8], sp
[-7], sp
[-6], sp
[-5], sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
883 NULLSTACK_FOR_NONLOCAL_EXIT ();
885 if (SCM_UNLIKELY (SCM_VALUESP (ret
)))
887 /* multiple values returned to continuation */
888 ret
= scm_struct_ref (ret
, SCM_INUM0
);
889 nvalues
= scm_ilength (ret
);
890 PUSH_LIST (ret
, scm_is_null
);
891 goto vm_return_values
;
900 VM_DEFINE_INSTRUCTION (56, smob_call
, "smob-call", 1, -1, -1)
907 subr
= SCM_SMOB_DESCRIPTOR (smob
).apply
;
909 VM_HANDLE_INTERRUPTS
;
918 ret
= subr (smob
, sp
[0]);
921 ret
= subr (smob
, sp
[-1], sp
[0]);
924 ret
= subr (smob
, sp
[-2], sp
[-1], sp
[0]);
930 NULLSTACK_FOR_NONLOCAL_EXIT ();
932 if (SCM_UNLIKELY (SCM_VALUESP (ret
)))
934 /* multiple values returned to continuation */
935 ret
= scm_struct_ref (ret
, SCM_INUM0
);
936 nvalues
= scm_ilength (ret
);
937 PUSH_LIST (ret
, scm_is_null
);
938 goto vm_return_values
;
947 VM_DEFINE_INSTRUCTION (57, foreign_call
, "foreign-call", 1, -1, -1)
953 VM_HANDLE_INTERRUPTS
;
956 ret
= scm_i_foreign_call (foreign
, sp
- nargs
+ 1);
958 NULLSTACK_FOR_NONLOCAL_EXIT ();
960 if (SCM_UNLIKELY (SCM_VALUESP (ret
)))
962 /* multiple values returned to continuation */
963 ret
= scm_struct_ref (ret
, SCM_INUM0
);
964 nvalues
= scm_ilength (ret
);
965 PUSH_LIST (ret
, scm_is_null
);
966 goto vm_return_values
;
975 VM_DEFINE_INSTRUCTION (58, continuation_call
, "continuation-call", 0, -1, 0)
981 scm_i_check_continuation (contregs
);
982 vm_return_to_continuation (scm_i_contregs_vm (contregs
),
983 scm_i_contregs_vm_cont (contregs
),
985 scm_i_reinstate_continuation (contregs
);
991 VM_DEFINE_INSTRUCTION (59, partial_cont_call
, "partial-cont-call", 0, -1, 0)
993 SCM vmcont
, intwinds
, prevwinds
;
994 POP2 (intwinds
, vmcont
);
996 VM_ASSERT (SCM_VM_CONT_REWINDABLE_P (vmcont
),
997 vm_error_continuation_not_rewindable (vmcont
));
998 prevwinds
= scm_i_dynwinds ();
999 vm_reinstate_partial_continuation (vm
, vmcont
, intwinds
, sp
+ 1 - fp
, fp
,
1002 /* Rewind prompt jmpbuffers, if any. */
1004 SCM winds
= scm_i_dynwinds ();
1005 for (; !scm_is_eq (winds
, prevwinds
); winds
= scm_cdr (winds
))
1006 if (SCM_PROMPT_P (scm_car (winds
)) && SCM_PROMPT_SETJMP (scm_car (winds
)))
1011 program
= SCM_FRAME_PROGRAM (fp
);
1016 VM_DEFINE_INSTRUCTION (60, tail_call_nargs
, "tail-call/nargs", 0, 0, 1)
1020 nargs
= scm_to_int (x
);
1021 /* FIXME: should truncate values? */
1025 VM_DEFINE_INSTRUCTION (61, call_nargs
, "call/nargs", 0, 0, 1)
1029 nargs
= scm_to_int (x
);
1030 /* FIXME: should truncate values? */
1034 VM_DEFINE_INSTRUCTION (62, mv_call
, "mv-call", 4, -1, 1)
1041 FETCH_OFFSET (offset
);
1044 VM_HANDLE_INTERRUPTS
;
1046 fp
= sp
- nargs
+ 1;
1048 ASSERT (SCM_FRAME_DYNAMIC_LINK (fp
) == 0);
1049 ASSERT (SCM_FRAME_RETURN_ADDRESS (fp
) == 0);
1050 ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp
) == 0);
1051 SCM_FRAME_SET_DYNAMIC_LINK (fp
, old_fp
);
1052 SCM_FRAME_SET_RETURN_ADDRESS (fp
, ip
);
1053 SCM_FRAME_SET_MV_RETURN_ADDRESS (fp
, mvra
);
1055 PUSH_CONTINUATION_HOOK ();
1059 if (SCM_UNLIKELY (!SCM_PROGRAM_P (program
)))
1063 ip
= SCM_C_OBJCODE_BASE (bp
);
1069 VM_DEFINE_INSTRUCTION (63, apply
, "apply", 1, -1, 1)
1076 ASSERT (nargs
>= 2);
1078 len
= scm_ilength (ls
);
1079 VM_ASSERT (len
>= 0,
1080 vm_error_apply_to_non_list (ls
));
1081 PUSH_LIST (ls
, SCM_NULL_OR_NIL_P
);
1087 VM_DEFINE_INSTRUCTION (64, tail_apply
, "tail-apply", 1, -1, 1)
1094 ASSERT (nargs
>= 2);
1096 len
= scm_ilength (ls
);
1097 VM_ASSERT (len
>= 0,
1098 vm_error_apply_to_non_list (ls
));
1099 PUSH_LIST (ls
, SCM_NULL_OR_NIL_P
);
1105 VM_DEFINE_INSTRUCTION (65, call_cc
, "call/cc", 0, 1, 1)
1108 SCM proc
, vm_cont
, cont
;
1111 vm_cont
= scm_i_vm_capture_stack (vp
->stack_base
, fp
, sp
, ip
, NULL
, 0);
1112 cont
= scm_i_make_continuation (&first
, vm
, vm_cont
);
1115 PUSH (SCM_PACK (0)); /* dynamic link */
1116 PUSH (SCM_PACK (0)); /* mvra */
1117 PUSH (SCM_PACK (0)); /* ra */
1125 /* Otherwise, the vm continuation was reinstated, and
1126 vm_return_to_continuation pushed on one value. We know only one
1127 value was returned because we are in value context -- the
1128 previous block jumped to vm_call, not vm_mv_call, after all.
1130 So, pull our regs back down from the vp, and march on to the
1131 next instruction. */
1133 program
= SCM_FRAME_PROGRAM (fp
);
1135 RESTORE_CONTINUATION_HOOK ();
1140 VM_DEFINE_INSTRUCTION (66, tail_call_cc
, "tail-call/cc", 0, 1, 1)
1143 SCM proc
, vm_cont
, cont
;
1146 /* In contrast to call/cc, tail-call/cc captures the continuation without the
1148 vm_cont
= scm_i_vm_capture_stack (vp
->stack_base
,
1149 SCM_FRAME_DYNAMIC_LINK (fp
),
1150 SCM_FRAME_LOWER_ADDRESS (fp
) - 1,
1151 SCM_FRAME_RETURN_ADDRESS (fp
),
1152 SCM_FRAME_MV_RETURN_ADDRESS (fp
),
1154 cont
= scm_i_make_continuation (&first
, vm
, vm_cont
);
1164 /* Otherwise, cache regs and NEXT, as above. Invoking the continuation
1165 does a return from the frame, either to the RA or
1168 program
= SCM_FRAME_PROGRAM (fp
);
1170 /* Unfortunately we don't know whether we are at the RA, and thus
1171 have one value without an nvalues marker, or we are at the
1172 MVRA and thus have multiple values and the nvalues
1173 marker. Instead of adding heuristics here, we will let hook
1174 client code do that. */
1175 RESTORE_CONTINUATION_HOOK ();
1180 VM_DEFINE_INSTRUCTION (67, return, "return", 0, 1, 1)
1183 POP_CONTINUATION_HOOK (1);
1185 VM_HANDLE_INTERRUPTS
;
1192 #ifdef VM_ENABLE_STACK_NULLING
1196 /* Restore registers */
1197 sp
= SCM_FRAME_LOWER_ADDRESS (fp
);
1198 ip
= SCM_FRAME_RETURN_ADDRESS (fp
);
1199 fp
= SCM_FRAME_DYNAMIC_LINK (fp
);
1201 #ifdef VM_ENABLE_STACK_NULLING
1202 NULLSTACK (old_sp
- sp
);
1205 /* Set return value (sp is already pushed) */
1209 /* Restore the last program */
1210 program
= SCM_FRAME_PROGRAM (fp
);
1216 VM_DEFINE_INSTRUCTION (68, return_values
, "return/values", 1, -1, -1)
1218 /* nvalues declared at top level, because for some reason gcc seems to think
1219 that perhaps it might be used without declaration. Fooey to that, I say. */
1222 POP_CONTINUATION_HOOK (nvalues
);
1224 VM_HANDLE_INTERRUPTS
;
1226 if (nvalues
!= 1 && SCM_FRAME_MV_RETURN_ADDRESS (fp
))
1228 /* A multiply-valued continuation */
1229 SCM
*vals
= sp
- nvalues
;
1231 /* Restore registers */
1232 sp
= SCM_FRAME_LOWER_ADDRESS (fp
) - 1;
1233 ip
= SCM_FRAME_MV_RETURN_ADDRESS (fp
);
1234 fp
= SCM_FRAME_DYNAMIC_LINK (fp
);
1236 /* Push return values, and the number of values */
1237 for (i
= 0; i
< nvalues
; i
++)
1239 *++sp
= SCM_I_MAKINUM (nvalues
);
1241 /* Finally null the end of the stack */
1242 NULLSTACK (vals
+ nvalues
- sp
);
1244 else if (nvalues
>= 1)
1246 /* Multiple values for a single-valued continuation -- here's where I
1247 break with guile tradition and try and do something sensible. (Also,
1248 this block handles the single-valued return to an mv
1250 SCM
*vals
= sp
- nvalues
;
1251 /* Restore registers */
1252 sp
= SCM_FRAME_LOWER_ADDRESS (fp
) - 1;
1253 ip
= SCM_FRAME_RETURN_ADDRESS (fp
);
1254 fp
= SCM_FRAME_DYNAMIC_LINK (fp
);
1256 /* Push first value */
1259 /* Finally null the end of the stack */
1260 NULLSTACK (vals
+ nvalues
- sp
);
1265 vm_error_no_values ();
1268 /* Restore the last program */
1269 program
= SCM_FRAME_PROGRAM (fp
);
1275 VM_DEFINE_INSTRUCTION (69, return_values_star
, "return/values*", 1, -1, -1)
1280 ASSERT (nvalues
>= 1);
1284 while (scm_is_pair (l
))
1290 VM_ASSERT (SCM_NULL_OR_NIL_P (l
), vm_error_improper_list (l
));
1292 goto vm_return_values
;
1295 VM_DEFINE_INSTRUCTION (70, return_nvalues
, "return/nvalues", 0, 1, -1)
1299 nvalues
= scm_to_int (n
);
1300 ASSERT (nvalues
>= 0);
1301 goto vm_return_values
;
1304 VM_DEFINE_INSTRUCTION (71, truncate_values
, "truncate-values", 2, -1, -1)
1309 nvalues
= scm_to_int (x
);
1316 VM_ASSERT (nvalues
>= nbinds
, vm_error_not_enough_values ());
1319 POP_LIST (nvalues
- nbinds
);
1321 DROPN (nvalues
- nbinds
);
1326 VM_DEFINE_INSTRUCTION (72, box
, "box", 1, 1, 0)
1331 LOCAL_SET (FETCH (), scm_cell (scm_tc7_variable
, SCM_UNPACK (val
)));
1336 (let ((a *undef*) (b *undef*) ...)
1337 (set! a (lambda () (b ...)))
1340 VM_DEFINE_INSTRUCTION (73, empty_box
, "empty-box", 1, 0, 0)
1343 LOCAL_SET (FETCH (),
1344 scm_cell (scm_tc7_variable
, SCM_UNPACK (SCM_UNDEFINED
)));
1348 VM_DEFINE_INSTRUCTION (74, local_boxed_ref
, "local-boxed-ref", 1, 0, 1)
1350 SCM v
= LOCAL_REF (FETCH ());
1351 ASSERT_BOUND_VARIABLE (v
);
1352 PUSH (VARIABLE_REF (v
));
1356 VM_DEFINE_INSTRUCTION (75, local_boxed_set
, "local-boxed-set", 1, 1, 0)
1359 v
= LOCAL_REF (FETCH ());
1361 ASSERT_VARIABLE (v
);
1362 VARIABLE_SET (v
, val
);
1366 VM_DEFINE_INSTRUCTION (76, free_ref
, "free-ref", 1, 0, 1)
1368 scm_t_uint8 idx
= FETCH ();
1370 CHECK_FREE_VARIABLE (idx
);
1371 PUSH (FREE_VARIABLE_REF (idx
));
1375 /* no free-set -- if a var is assigned, it should be in a box */
1377 VM_DEFINE_INSTRUCTION (77, free_boxed_ref
, "free-boxed-ref", 1, 0, 1)
1380 scm_t_uint8 idx
= FETCH ();
1381 CHECK_FREE_VARIABLE (idx
);
1382 v
= FREE_VARIABLE_REF (idx
);
1383 ASSERT_BOUND_VARIABLE (v
);
1384 PUSH (VARIABLE_REF (v
));
1388 VM_DEFINE_INSTRUCTION (78, free_boxed_set
, "free-boxed-set", 1, 1, 0)
1391 scm_t_uint8 idx
= FETCH ();
1393 CHECK_FREE_VARIABLE (idx
);
1394 v
= FREE_VARIABLE_REF (idx
);
1395 ASSERT_BOUND_VARIABLE (v
);
1396 VARIABLE_SET (v
, val
);
1400 VM_DEFINE_INSTRUCTION (79, make_closure
, "make-closure", 2, -1, 1)
1409 closure
= scm_words (scm_tc7_program
| (len
<<16), len
+ 3);
1410 SCM_SET_CELL_OBJECT_1 (closure
, SCM_PROGRAM_OBJCODE (sp
[-len
]));
1411 SCM_SET_CELL_OBJECT_2 (closure
, SCM_PROGRAM_OBJTABLE (sp
[-len
]));
1413 for (n
= 0; n
< len
; n
++)
1414 SCM_PROGRAM_FREE_VARIABLE_SET (closure
, n
, sp
[-len
+ 1 + n
]);
1419 VM_DEFINE_INSTRUCTION (80, make_variable
, "make-variable", 0, 0, 1)
1422 /* fixme underflow */
1423 PUSH (scm_cell (scm_tc7_variable
, SCM_UNPACK (SCM_UNDEFINED
)));
1427 VM_DEFINE_INSTRUCTION (81, fix_closure
, "fix-closure", 2, -1, 0)
1430 unsigned int i
= FETCH ();
1434 /* FIXME CHECK_LOCAL (i) */
1436 /* FIXME ASSERT_PROGRAM (x); */
1437 len
= SCM_PROGRAM_NUM_FREE_VARIABLES (x
);
1438 for (n
= 0; n
< len
; n
++)
1439 SCM_PROGRAM_FREE_VARIABLE_SET (x
, n
, sp
[-len
+ 1 + n
]);
1444 VM_DEFINE_INSTRUCTION (82, define
, "define", 0, 0, 2)
1449 VARIABLE_SET (scm_sym2var (sym
, scm_current_module_lookup_closure (),
1455 VM_DEFINE_INSTRUCTION (83, make_keyword
, "make-keyword", 0, 1, 1)
1459 *sp
= scm_symbol_to_keyword (*sp
);
1463 VM_DEFINE_INSTRUCTION (84, make_symbol
, "make-symbol", 0, 1, 1)
1467 *sp
= scm_string_to_symbol (*sp
);
1471 VM_DEFINE_INSTRUCTION (85, prompt
, "prompt", 4, 2, 0)
1474 scm_t_uint8 escape_only_p
;
1477 escape_only_p
= FETCH ();
1478 FETCH_OFFSET (offset
);
1482 /* Push the prompt onto the dynamic stack. */
1483 prompt
= scm_c_make_prompt (k
, fp
, sp
, ip
+ offset
, escape_only_p
, vm_cookie
,
1485 scm_i_set_dynwinds (scm_cons (prompt
, SCM_PROMPT_DYNWINDS (prompt
)));
1486 if (SCM_PROMPT_SETJMP (prompt
))
1488 /* The prompt exited nonlocally. Cache the regs back from the vp, and go
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.
1496 program
= SCM_FRAME_PROGRAM (fp
);
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 ();
1504 /* Otherwise setjmp returned for the first time, so we go to execute the
1509 VM_DEFINE_INSTRUCTION (86, wind
, "wind", 0, 2, 0)
1512 POP2 (unwind
, wind
);
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. */
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
));
1521 scm_i_set_dynwinds (scm_cons (scm_cons (wind
, unwind
), scm_i_dynwinds ()));
1525 VM_DEFINE_INSTRUCTION (87, abort
, "abort", 1, -1, -1)
1527 unsigned n
= FETCH ();
1529 PRE_CHECK_UNDERFLOW (n
+ 2);
1530 vm_abort (vm
, n
, vm_cookie
);
1531 /* vm_abort should not return */
1535 VM_DEFINE_INSTRUCTION (88, unwind
, "unwind", 0, 0, 0)
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 ()));
1543 VM_DEFINE_INSTRUCTION (89, wind_fluids
, "wind-fluids", 1, -1, 0)
1545 unsigned n
= FETCH ();
1551 wf
= scm_i_make_with_fluids (n
, sp
+ 1, sp
+ 1 + n
);
1554 scm_i_swap_with_fluids (wf
, current_thread
->dynamic_state
);
1555 scm_i_set_dynwinds (scm_cons (wf
, scm_i_dynwinds ()));
1559 VM_DEFINE_INSTRUCTION (90, unwind_fluids
, "unwind-fluids", 0, 0, 0)
1562 wf
= scm_car (scm_i_dynwinds ());
1563 scm_i_set_dynwinds (scm_cdr (scm_i_dynwinds ()));
1564 scm_i_swap_with_fluids (wf
, current_thread
->dynamic_state
);
1568 VM_DEFINE_INSTRUCTION (91, fluid_ref
, "fluid-ref", 0, 1, 1)
1574 fluids
= SCM_I_DYNAMIC_STATE_FLUIDS (current_thread
->dynamic_state
);
1575 if (SCM_UNLIKELY (!SCM_FLUID_P (*sp
))
1576 || ((num
= SCM_I_FLUID_NUM (*sp
)) >= SCM_SIMPLE_VECTOR_LENGTH (fluids
)))
1578 /* Punt dynstate expansion and error handling to the C proc. */
1580 *sp
= scm_fluid_ref (*sp
);
1584 SCM val
= SCM_SIMPLE_VECTOR_REF (fluids
, num
);
1585 if (scm_is_eq (val
, SCM_UNDEFINED
))
1586 val
= SCM_I_FLUID_DEFAULT (*sp
);
1587 VM_ASSERT (!scm_is_eq (val
, SCM_UNDEFINED
),
1588 vm_error_unbound_fluid (program
, *sp
));
1595 VM_DEFINE_INSTRUCTION (92, fluid_set
, "fluid-set", 0, 2, 0)
1598 SCM val
, fluid
, fluids
;
1601 fluids
= SCM_I_DYNAMIC_STATE_FLUIDS (current_thread
->dynamic_state
);
1602 if (SCM_UNLIKELY (!SCM_FLUID_P (fluid
))
1603 || ((num
= SCM_I_FLUID_NUM (fluid
)) >= SCM_SIMPLE_VECTOR_LENGTH (fluids
)))
1605 /* Punt dynstate expansion and error handling to the C proc. */
1607 scm_fluid_set_x (fluid
, val
);
1610 SCM_SIMPLE_VECTOR_SET (fluids
, num
, val
);
1615 VM_DEFINE_INSTRUCTION (93, assert_nargs_ee_locals
, "assert-nargs-ee/locals", 1, 0, 0)
1620 /* nargs = n & 0x7, nlocs = nargs + (n >> 3) */
1623 VM_ASSERT (sp
- (fp
- 1) == (n
& 0x7),
1624 vm_error_wrong_num_args (program
));
1630 *++old_sp
= SCM_UNDEFINED
;
1637 (defun renumber-ops ()
1638 "start from top of buffer and renumber 'VM_DEFINE_FOO (\n' sequences"
1641 (let ((counter -1)) (goto-char (point-min))
1642 (while (re-search-forward "^VM_DEFINE_[^ ]+ (\\([^,]+\\)," (point-max) t)
1644 (number-to-string (setq counter (1+ counter)))