1 /* Copyright (C) 2001,2008,2009,2010,2011,2012,2013 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
));
528 VM_DEFINE_INSTRUCTION (41, br_if_nil
, "br-if-nil", 3, 0, 0)
532 BR (scm_is_lisp_false (x
));
535 VM_DEFINE_INSTRUCTION (42, br_if_not_nil
, "br-if-not-nil", 3, 0, 0)
539 BR (!scm_is_lisp_false (x
));
546 VM_DEFINE_INSTRUCTION (43, br_if_nargs_ne
, "br-if-nargs-ne", 5, 0, 0)
552 FETCH_OFFSET (offset
);
553 if (sp
- (fp
- 1) != n
)
558 VM_DEFINE_INSTRUCTION (44, br_if_nargs_lt
, "br-if-nargs-lt", 5, 0, 0)
564 FETCH_OFFSET (offset
);
565 if (sp
- (fp
- 1) < n
)
570 VM_DEFINE_INSTRUCTION (45, br_if_nargs_gt
, "br-if-nargs-gt", 5, 0, 0)
577 FETCH_OFFSET (offset
);
578 if (sp
- (fp
- 1) > n
)
583 VM_DEFINE_INSTRUCTION (46, assert_nargs_ee
, "assert-nargs-ee", 2, 0, 0)
588 VM_ASSERT (sp
- (fp
- 1) == n
,
589 vm_error_wrong_num_args (program
));
593 VM_DEFINE_INSTRUCTION (47, assert_nargs_ge
, "assert-nargs-ge", 2, 0, 0)
598 VM_ASSERT (sp
- (fp
- 1) >= n
,
599 vm_error_wrong_num_args (program
));
603 VM_DEFINE_INSTRUCTION (48, bind_optionals
, "bind-optionals", 2, -1, -1)
608 while (sp
- (fp
- 1) < n
)
609 PUSH (SCM_UNDEFINED
);
613 VM_DEFINE_INSTRUCTION (49, bind_optionals_shuffle
, "bind-optionals/shuffle", 6, -1, -1)
616 scm_t_ptrdiff nreq
, nreq_and_opt
, ntotal
;
617 nreq
= FETCH () << 8;
619 nreq_and_opt
= FETCH () << 8;
620 nreq_and_opt
+= FETCH ();
621 ntotal
= FETCH () << 8;
624 /* look in optionals for first keyword or last positional */
625 /* starting after the last required positional arg */
627 while (/* while we have args */
629 /* and we still have positionals to fill */
630 && walk
- fp
< nreq_and_opt
631 /* and we haven't reached a keyword yet */
632 && !scm_is_keyword (*walk
))
633 /* bind this optional arg (by leaving it in place) */
635 /* now shuffle up, from walk to ntotal */
637 scm_t_ptrdiff nshuf
= sp
- walk
+ 1, i
;
638 sp
= (fp
- 1) + ntotal
+ nshuf
;
640 for (i
= 0; i
< nshuf
; i
++)
641 sp
[-i
] = walk
[nshuf
-i
-1];
643 /* and fill optionals & keyword args with SCM_UNDEFINED */
644 while (walk
<= (fp
- 1) + ntotal
)
645 *walk
++ = SCM_UNDEFINED
;
650 /* See also bind-optionals/shuffle-or-br below. */
652 /* Flags that determine whether other keywords are allowed, and whether a
653 rest argument is expected. These values must match those used by the
654 glil->assembly compiler. */
655 #define F_ALLOW_OTHER_KEYS 1
658 VM_DEFINE_INSTRUCTION (50, bind_kwargs
, "bind-kwargs", 5, 0, 0)
662 int kw_and_rest_flags
;
666 /* XXX: We don't actually use NKW. */
669 kw_and_rest_flags
= FETCH ();
671 VM_ASSERT ((kw_and_rest_flags
& F_REST
)
672 || ((sp
- (fp
- 1) - nkw
) % 2) == 0,
673 vm_error_kwargs_length_not_even (program
))
676 kw
= OBJECT_REF (idx
);
678 /* Switch NKW to be a negative index below SP. */
679 for (nkw
= -(sp
- (fp
- 1) - nkw
) + 1; nkw
< 0; nkw
++)
683 if (scm_is_keyword (sp
[nkw
]))
685 for (walk
= kw
; scm_is_pair (walk
); walk
= SCM_CDR (walk
))
687 if (scm_is_eq (SCM_CAAR (walk
), sp
[nkw
]))
689 SCM si
= SCM_CDAR (walk
);
690 LOCAL_SET (SCM_I_INUMP (si
) ? SCM_I_INUM (si
) : scm_to_long (si
),
695 VM_ASSERT (scm_is_pair (walk
)
696 || (kw_and_rest_flags
& F_ALLOW_OTHER_KEYS
),
697 vm_error_kwargs_unrecognized_keyword (program
));
701 VM_ASSERT (kw_and_rest_flags
& F_REST
,
702 vm_error_kwargs_invalid_keyword (program
));
708 #undef F_ALLOW_OTHER_KEYS
712 VM_DEFINE_INSTRUCTION (51, push_rest
, "push-rest", 2, -1, -1)
718 while (sp
- (fp
- 1) > n
)
719 /* No need to check for underflow. */
720 CONS (rest
, *sp
--, rest
);
725 VM_DEFINE_INSTRUCTION (52, bind_rest
, "bind-rest", 4, -1, -1)
734 while (sp
- (fp
- 1) > n
)
735 /* No need to check for underflow. */
736 CONS (rest
, *sp
--, rest
);
741 VM_DEFINE_INSTRUCTION (53, reserve_locals
, "reserve-locals", 2, -1, -1)
754 *++old_sp
= SCM_UNDEFINED
;
757 NULLSTACK (old_sp
- sp
);
762 VM_DEFINE_INSTRUCTION (54, new_frame
, "new-frame", 0, 0, 3)
764 /* NB: if you change this, see frames.c:vm-frame-num-locals */
765 /* and frames.h, vm-engine.c, etc of course */
767 /* We don't initialize the dynamic link here because we don't actually
768 know that this frame will point to the current fp: it could be
769 placed elsewhere on the stack if captured in a partial
770 continuation, and invoked from some other context. */
771 PUSH (SCM_PACK (0)); /* dynamic link */
772 PUSH (SCM_PACK (0)); /* mvra */
773 PUSH (SCM_PACK (0)); /* ra */
777 VM_DEFINE_INSTRUCTION (55, call
, "call", 1, -1, 1)
782 VM_HANDLE_INTERRUPTS
;
789 ASSERT (SCM_FRAME_DYNAMIC_LINK (fp
) == 0);
790 ASSERT (SCM_FRAME_RETURN_ADDRESS (fp
) == 0);
791 ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp
) == 0);
792 SCM_FRAME_SET_DYNAMIC_LINK (fp
, old_fp
);
793 SCM_FRAME_SET_RETURN_ADDRESS (fp
, ip
);
794 SCM_FRAME_SET_MV_RETURN_ADDRESS (fp
, 0);
797 PUSH_CONTINUATION_HOOK ();
801 if (SCM_UNLIKELY (!SCM_PROGRAM_P (program
)))
805 ip
= SCM_C_OBJCODE_BASE (bp
);
811 VM_DEFINE_INSTRUCTION (56, tail_call
, "tail-call", 1, -1, 1)
816 VM_HANDLE_INTERRUPTS
;
820 #ifdef VM_ENABLE_STACK_NULLING
825 /* shuffle down the program and the arguments */
826 for (i
= -1, sp
= sp
- nargs
+ 1; i
< nargs
; i
++)
827 SCM_FRAME_STACK_ADDRESS (fp
)[i
] = sp
[i
];
831 NULLSTACK (old_sp
- sp
);
836 if (SCM_UNLIKELY (!SCM_PROGRAM_P (program
)))
840 ip
= SCM_C_OBJCODE_BASE (bp
);
846 VM_DEFINE_INSTRUCTION (57, subr_call
, "subr-call", 1, -1, -1)
854 subr
= SCM_POINTER_VALUE (pointer
);
856 VM_HANDLE_INTERRUPTS
;
868 ret
= subr (sp
[-1], sp
[0]);
871 ret
= subr (sp
[-2], sp
[-1], sp
[0]);
874 ret
= subr (sp
[-3], sp
[-2], sp
[-1], sp
[0]);
877 ret
= subr (sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
880 ret
= subr (sp
[-5], sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
883 ret
= subr (sp
[-6], sp
[-5], sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
886 ret
= subr (sp
[-7], sp
[-6], sp
[-5], sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
889 ret
= subr (sp
[-8], sp
[-7], sp
[-6], sp
[-5], sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
892 ret
= subr (sp
[-9], sp
[-8], sp
[-7], sp
[-6], sp
[-5], sp
[-4], sp
[-3], sp
[-2], sp
[-1], sp
[0]);
898 NULLSTACK_FOR_NONLOCAL_EXIT ();
900 if (SCM_UNLIKELY (SCM_VALUESP (ret
)))
902 /* multiple values returned to continuation */
903 ret
= scm_struct_ref (ret
, SCM_INUM0
);
904 nvalues
= scm_ilength (ret
);
905 PUSH_LIST (ret
, scm_is_null
);
906 goto vm_return_values
;
915 /* Instruction 58 used to be smob-call. */
917 VM_DEFINE_INSTRUCTION (59, foreign_call
, "foreign-call", 1, -1, -1)
923 VM_HANDLE_INTERRUPTS
;
926 ret
= scm_i_foreign_call (foreign
, sp
- nargs
+ 1);
928 NULLSTACK_FOR_NONLOCAL_EXIT ();
930 if (SCM_UNLIKELY (SCM_VALUESP (ret
)))
932 /* multiple values returned to continuation */
933 ret
= scm_struct_ref (ret
, SCM_INUM0
);
934 nvalues
= scm_ilength (ret
);
935 PUSH_LIST (ret
, scm_is_null
);
936 goto vm_return_values
;
945 VM_DEFINE_INSTRUCTION (60, continuation_call
, "continuation-call", 0, -1, 0)
951 scm_i_check_continuation (contregs
);
952 vm_return_to_continuation (scm_i_contregs_vm (contregs
),
953 scm_i_contregs_vm_cont (contregs
),
955 scm_i_reinstate_continuation (contregs
);
961 VM_DEFINE_INSTRUCTION (61, partial_cont_call
, "partial-cont-call", 0, -1, 0)
966 VM_ASSERT (SCM_VM_CONT_REWINDABLE_P (vmcont
),
967 vm_error_continuation_not_rewindable (vmcont
));
968 vm_reinstate_partial_continuation (vm
, vmcont
, sp
+ 1 - fp
, fp
,
969 ¤t_thread
->dynstack
,
973 program
= SCM_FRAME_PROGRAM (fp
);
978 VM_DEFINE_INSTRUCTION (62, tail_call_nargs
, "tail-call/nargs", 0, 0, 1)
982 nargs
= scm_to_int (x
);
983 /* FIXME: should truncate values? */
987 VM_DEFINE_INSTRUCTION (63, call_nargs
, "call/nargs", 0, 0, 1)
991 nargs
= scm_to_int (x
);
992 /* FIXME: should truncate values? */
996 VM_DEFINE_INSTRUCTION (64, mv_call
, "mv-call", 4, -1, 1)
1003 FETCH_OFFSET (offset
);
1006 VM_HANDLE_INTERRUPTS
;
1008 fp
= sp
- nargs
+ 1;
1010 ASSERT (SCM_FRAME_DYNAMIC_LINK (fp
) == 0);
1011 ASSERT (SCM_FRAME_RETURN_ADDRESS (fp
) == 0);
1012 ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp
) == 0);
1013 SCM_FRAME_SET_DYNAMIC_LINK (fp
, old_fp
);
1014 SCM_FRAME_SET_RETURN_ADDRESS (fp
, ip
);
1015 SCM_FRAME_SET_MV_RETURN_ADDRESS (fp
, mvra
);
1017 PUSH_CONTINUATION_HOOK ();
1021 if (SCM_UNLIKELY (!SCM_PROGRAM_P (program
)))
1025 ip
= SCM_C_OBJCODE_BASE (bp
);
1031 VM_DEFINE_INSTRUCTION (65, apply
, "apply", 1, -1, 1)
1038 ASSERT (nargs
>= 2);
1040 len
= scm_ilength (ls
);
1041 VM_ASSERT (len
>= 0,
1042 vm_error_apply_to_non_list (ls
));
1043 PUSH_LIST (ls
, SCM_NULL_OR_NIL_P
);
1049 VM_DEFINE_INSTRUCTION (66, tail_apply
, "tail-apply", 1, -1, 1)
1056 ASSERT (nargs
>= 2);
1058 len
= scm_ilength (ls
);
1059 VM_ASSERT (len
>= 0,
1060 vm_error_apply_to_non_list (ls
));
1061 PUSH_LIST (ls
, SCM_NULL_OR_NIL_P
);
1067 VM_DEFINE_INSTRUCTION (67, call_cc
, "call/cc", 0, 1, 1)
1070 SCM proc
, vm_cont
, cont
;
1071 scm_t_dynstack
*dynstack
;
1074 dynstack
= scm_dynstack_capture_all (¤t_thread
->dynstack
);
1075 vm_cont
= scm_i_vm_capture_stack (vp
->stack_base
, fp
, sp
, ip
, NULL
,
1077 cont
= scm_i_make_continuation (&first
, vm
, vm_cont
);
1080 PUSH (SCM_PACK (0)); /* dynamic link */
1081 PUSH (SCM_PACK (0)); /* mvra */
1082 PUSH (SCM_PACK (0)); /* ra */
1090 /* Otherwise, the vm continuation was reinstated, and
1091 vm_return_to_continuation pushed on one value. We know only one
1092 value was returned because we are in value context -- the
1093 previous block jumped to vm_call, not vm_mv_call, after all.
1095 So, pull our regs back down from the vp, and march on to the
1096 next instruction. */
1098 program
= SCM_FRAME_PROGRAM (fp
);
1100 RESTORE_CONTINUATION_HOOK ();
1105 VM_DEFINE_INSTRUCTION (68, tail_call_cc
, "tail-call/cc", 0, 1, 1)
1108 SCM proc
, vm_cont
, cont
;
1109 scm_t_dynstack
*dynstack
;
1112 /* In contrast to call/cc, tail-call/cc captures the continuation without the
1114 dynstack
= scm_dynstack_capture_all (¤t_thread
->dynstack
);
1115 vm_cont
= scm_i_vm_capture_stack (vp
->stack_base
,
1116 SCM_FRAME_DYNAMIC_LINK (fp
),
1117 SCM_FRAME_LOWER_ADDRESS (fp
) - 1,
1118 SCM_FRAME_RETURN_ADDRESS (fp
),
1119 SCM_FRAME_MV_RETURN_ADDRESS (fp
),
1122 cont
= scm_i_make_continuation (&first
, vm
, vm_cont
);
1132 /* Otherwise, cache regs and NEXT, as above. Invoking the continuation
1133 does a return from the frame, either to the RA or
1136 program
= SCM_FRAME_PROGRAM (fp
);
1138 /* Unfortunately we don't know whether we are at the RA, and thus
1139 have one value without an nvalues marker, or we are at the
1140 MVRA and thus have multiple values and the nvalues
1141 marker. Instead of adding heuristics here, we will let hook
1142 client code do that. */
1143 RESTORE_CONTINUATION_HOOK ();
1148 VM_DEFINE_INSTRUCTION (69, return, "return", 0, 1, 1)
1151 POP_CONTINUATION_HOOK (1);
1153 VM_HANDLE_INTERRUPTS
;
1160 #ifdef VM_ENABLE_STACK_NULLING
1164 /* Restore registers */
1165 sp
= SCM_FRAME_LOWER_ADDRESS (fp
);
1166 ip
= SCM_FRAME_RETURN_ADDRESS (fp
);
1167 fp
= SCM_FRAME_DYNAMIC_LINK (fp
);
1169 #ifdef VM_ENABLE_STACK_NULLING
1170 NULLSTACK (old_sp
- sp
);
1173 /* Set return value (sp is already pushed) */
1177 /* Restore the last program */
1178 program
= SCM_FRAME_PROGRAM (fp
);
1184 VM_DEFINE_INSTRUCTION (70, return_values
, "return/values", 1, -1, -1)
1186 /* nvalues declared at top level, because for some reason gcc seems to think
1187 that perhaps it might be used without declaration. Fooey to that, I say. */
1190 POP_CONTINUATION_HOOK (nvalues
);
1192 VM_HANDLE_INTERRUPTS
;
1194 if (nvalues
!= 1 && SCM_FRAME_MV_RETURN_ADDRESS (fp
))
1196 /* A multiply-valued continuation */
1197 SCM
*vals
= sp
- nvalues
;
1199 /* Restore registers */
1200 sp
= SCM_FRAME_LOWER_ADDRESS (fp
) - 1;
1201 ip
= SCM_FRAME_MV_RETURN_ADDRESS (fp
);
1202 fp
= SCM_FRAME_DYNAMIC_LINK (fp
);
1204 /* Push return values, and the number of values */
1205 for (i
= 0; i
< nvalues
; i
++)
1207 *++sp
= SCM_I_MAKINUM (nvalues
);
1209 /* Finally null the end of the stack */
1210 NULLSTACK (vals
+ nvalues
- sp
);
1212 else if (nvalues
>= 1)
1214 /* Multiple values for a single-valued continuation -- here's where I
1215 break with guile tradition and try and do something sensible. (Also,
1216 this block handles the single-valued return to an mv
1218 SCM
*vals
= sp
- nvalues
;
1219 /* Restore registers */
1220 sp
= SCM_FRAME_LOWER_ADDRESS (fp
) - 1;
1221 ip
= SCM_FRAME_RETURN_ADDRESS (fp
);
1222 fp
= SCM_FRAME_DYNAMIC_LINK (fp
);
1224 /* Push first value */
1227 /* Finally null the end of the stack */
1228 NULLSTACK (vals
+ nvalues
- sp
);
1233 vm_error_no_values ();
1236 /* Restore the last program */
1237 program
= SCM_FRAME_PROGRAM (fp
);
1243 VM_DEFINE_INSTRUCTION (71, return_values_star
, "return/values*", 1, -1, -1)
1248 ASSERT (nvalues
>= 1);
1252 while (scm_is_pair (l
))
1258 VM_ASSERT (SCM_NULL_OR_NIL_P (l
), vm_error_improper_list (l
));
1260 goto vm_return_values
;
1263 VM_DEFINE_INSTRUCTION (72, return_nvalues
, "return/nvalues", 0, 1, -1)
1267 nvalues
= scm_to_int (n
);
1268 ASSERT (nvalues
>= 0);
1269 goto vm_return_values
;
1272 VM_DEFINE_INSTRUCTION (73, truncate_values
, "truncate-values", 2, -1, -1)
1277 nvalues
= scm_to_int (x
);
1284 VM_ASSERT (nvalues
>= nbinds
, vm_error_not_enough_values ());
1287 POP_LIST (nvalues
- nbinds
);
1289 DROPN (nvalues
- nbinds
);
1294 VM_DEFINE_INSTRUCTION (74, box
, "box", 1, 1, 0)
1299 LOCAL_SET (FETCH (), scm_cell (scm_tc7_variable
, SCM_UNPACK (val
)));
1304 (let ((a *undef*) (b *undef*) ...)
1305 (set! a (lambda () (b ...)))
1308 VM_DEFINE_INSTRUCTION (75, empty_box
, "empty-box", 1, 0, 0)
1311 LOCAL_SET (FETCH (),
1312 scm_cell (scm_tc7_variable
, SCM_UNPACK (SCM_UNDEFINED
)));
1316 VM_DEFINE_INSTRUCTION (76, local_boxed_ref
, "local-boxed-ref", 1, 0, 1)
1318 SCM v
= LOCAL_REF (FETCH ());
1319 ASSERT_BOUND_VARIABLE (v
);
1320 PUSH (VARIABLE_REF (v
));
1324 VM_DEFINE_INSTRUCTION (77, local_boxed_set
, "local-boxed-set", 1, 1, 0)
1327 v
= LOCAL_REF (FETCH ());
1329 ASSERT_VARIABLE (v
);
1330 VARIABLE_SET (v
, val
);
1334 VM_DEFINE_INSTRUCTION (78, free_ref
, "free-ref", 1, 0, 1)
1336 scm_t_uint8 idx
= FETCH ();
1338 CHECK_FREE_VARIABLE (idx
);
1339 PUSH (FREE_VARIABLE_REF (idx
));
1343 /* no free-set -- if a var is assigned, it should be in a box */
1345 VM_DEFINE_INSTRUCTION (79, free_boxed_ref
, "free-boxed-ref", 1, 0, 1)
1348 scm_t_uint8 idx
= FETCH ();
1349 CHECK_FREE_VARIABLE (idx
);
1350 v
= FREE_VARIABLE_REF (idx
);
1351 ASSERT_BOUND_VARIABLE (v
);
1352 PUSH (VARIABLE_REF (v
));
1356 VM_DEFINE_INSTRUCTION (80, free_boxed_set
, "free-boxed-set", 1, 1, 0)
1359 scm_t_uint8 idx
= FETCH ();
1361 CHECK_FREE_VARIABLE (idx
);
1362 v
= FREE_VARIABLE_REF (idx
);
1363 ASSERT_BOUND_VARIABLE (v
);
1364 VARIABLE_SET (v
, val
);
1368 VM_DEFINE_INSTRUCTION (81, make_closure
, "make-closure", 2, -1, 1)
1377 closure
= scm_words (scm_tc7_program
| (len
<<16), len
+ 3);
1378 SCM_SET_CELL_OBJECT_1 (closure
, SCM_PROGRAM_OBJCODE (sp
[-len
]));
1379 SCM_SET_CELL_OBJECT_2 (closure
, SCM_PROGRAM_OBJTABLE (sp
[-len
]));
1381 for (n
= 0; n
< len
; n
++)
1382 SCM_PROGRAM_FREE_VARIABLE_SET (closure
, n
, sp
[-len
+ 1 + n
]);
1387 VM_DEFINE_INSTRUCTION (82, make_variable
, "make-variable", 0, 0, 1)
1390 /* fixme underflow */
1391 PUSH (scm_cell (scm_tc7_variable
, SCM_UNPACK (SCM_UNDEFINED
)));
1395 VM_DEFINE_INSTRUCTION (83, fix_closure
, "fix-closure", 2, -1, 0)
1398 unsigned int i
= FETCH ();
1402 /* FIXME CHECK_LOCAL (i) */
1404 /* FIXME ASSERT_PROGRAM (x); */
1405 len
= SCM_PROGRAM_NUM_FREE_VARIABLES (x
);
1406 for (n
= 0; n
< len
; n
++)
1407 SCM_PROGRAM_FREE_VARIABLE_SET (x
, n
, sp
[-len
+ 1 + n
]);
1412 VM_DEFINE_INSTRUCTION (84, define
, "define", 0, 0, 2)
1417 scm_define (sym
, val
);
1421 VM_DEFINE_INSTRUCTION (85, make_keyword
, "make-keyword", 0, 1, 1)
1425 *sp
= scm_symbol_to_keyword (*sp
);
1429 VM_DEFINE_INSTRUCTION (86, make_symbol
, "make-symbol", 0, 1, 1)
1433 *sp
= scm_string_to_symbol (*sp
);
1437 VM_DEFINE_INSTRUCTION (87, prompt
, "prompt", 4, 2, 0)
1440 scm_t_uint8 escape_only_p
;
1442 scm_t_dynstack_prompt_flags flags
;
1444 escape_only_p
= FETCH ();
1445 FETCH_OFFSET (offset
);
1449 /* Push the prompt onto the dynamic stack. */
1450 flags
= escape_only_p
? SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY
: 0;
1451 scm_dynstack_push_prompt (¤t_thread
->dynstack
, flags
, k
,
1452 fp
, sp
, ip
+ offset
, ®isters
);
1456 VM_DEFINE_INSTRUCTION (88, wind
, "wind", 0, 2, 0)
1459 POP2 (unwind
, wind
);
1461 /* Push wind and unwind procedures onto the dynamic stack. Note that neither
1462 are actually called; the compiler should emit calls to wind and unwind for
1463 the normal dynamic-wind control flow. Also note that the compiler
1464 should have inserted checks that they wind and unwind procs are
1465 thunks, if it could not prove that to be the case. */
1466 scm_dynstack_push_dynwind (¤t_thread
->dynstack
, wind
, unwind
);
1470 VM_DEFINE_INSTRUCTION (89, abort
, "abort", 1, -1, -1)
1472 unsigned n
= FETCH ();
1474 PRE_CHECK_UNDERFLOW (n
+ 2);
1475 vm_abort (vm
, n
, ®isters
);
1476 /* vm_abort should not return */
1480 VM_DEFINE_INSTRUCTION (90, unwind
, "unwind", 0, 0, 0)
1482 /* A normal exit from the dynamic extent of an expression. Pop the top entry
1483 off of the dynamic stack. */
1484 scm_dynstack_pop (¤t_thread
->dynstack
);
1488 VM_DEFINE_INSTRUCTION (91, wind_fluids
, "wind-fluids", 1, -1, 0)
1490 unsigned n
= FETCH ();
1495 scm_dynstack_push_fluids (¤t_thread
->dynstack
, n
, sp
+ 1, sp
+ 1 + n
,
1496 current_thread
->dynamic_state
);
1501 VM_DEFINE_INSTRUCTION (92, unwind_fluids
, "unwind-fluids", 0, 0, 0)
1503 /* This function must not allocate. */
1504 scm_dynstack_unwind_fluids (¤t_thread
->dynstack
,
1505 current_thread
->dynamic_state
);
1509 VM_DEFINE_INSTRUCTION (93, fluid_ref
, "fluid-ref", 0, 1, 1)
1515 fluids
= SCM_I_DYNAMIC_STATE_FLUIDS (current_thread
->dynamic_state
);
1516 if (SCM_UNLIKELY (!SCM_FLUID_P (*sp
))
1517 || ((num
= SCM_I_FLUID_NUM (*sp
)) >= SCM_SIMPLE_VECTOR_LENGTH (fluids
)))
1519 /* Punt dynstate expansion and error handling to the C proc. */
1521 *sp
= scm_fluid_ref (*sp
);
1525 SCM val
= SCM_SIMPLE_VECTOR_REF (fluids
, num
);
1526 if (scm_is_eq (val
, SCM_UNDEFINED
))
1527 val
= SCM_I_FLUID_DEFAULT (*sp
);
1528 VM_ASSERT (!scm_is_eq (val
, SCM_UNDEFINED
),
1529 vm_error_unbound_fluid (program
, *sp
));
1536 VM_DEFINE_INSTRUCTION (94, fluid_set
, "fluid-set", 0, 2, 0)
1539 SCM val
, fluid
, fluids
;
1542 fluids
= SCM_I_DYNAMIC_STATE_FLUIDS (current_thread
->dynamic_state
);
1543 if (SCM_UNLIKELY (!SCM_FLUID_P (fluid
))
1544 || ((num
= SCM_I_FLUID_NUM (fluid
)) >= SCM_SIMPLE_VECTOR_LENGTH (fluids
)))
1546 /* Punt dynstate expansion and error handling to the C proc. */
1548 scm_fluid_set_x (fluid
, val
);
1551 SCM_SIMPLE_VECTOR_SET (fluids
, num
, val
);
1556 VM_DEFINE_INSTRUCTION (95, assert_nargs_ee_locals
, "assert-nargs-ee/locals", 1, 0, 0)
1561 /* nargs = n & 0x7, nlocs = nargs + (n >> 3) */
1564 VM_ASSERT (sp
- (fp
- 1) == (n
& 0x7),
1565 vm_error_wrong_num_args (program
));
1571 *++old_sp
= SCM_UNDEFINED
;
1576 /* Like bind-optionals/shuffle, but if there are too many positional
1577 arguments, jumps to the next case-lambda clause. */
1578 VM_DEFINE_INSTRUCTION (96, bind_optionals_shuffle_or_br
, "bind-optionals/shuffle-or-br", 9, -1, -1)
1581 scm_t_ptrdiff nreq
, nreq_and_opt
, ntotal
;
1583 nreq
= FETCH () << 8;
1585 nreq_and_opt
= FETCH () << 8;
1586 nreq_and_opt
+= FETCH ();
1587 ntotal
= FETCH () << 8;
1589 FETCH_OFFSET (offset
);
1591 /* look in optionals for first keyword or last positional */
1592 /* starting after the last required positional arg */
1594 while (/* while we have args */
1596 /* and we still have positionals to fill */
1597 && walk
- fp
< nreq_and_opt
1598 /* and we haven't reached a keyword yet */
1599 && !scm_is_keyword (*walk
))
1600 /* bind this optional arg (by leaving it in place) */
1602 if (/* If we have filled all the positionals */
1603 walk
- fp
== nreq_and_opt
1604 /* and there are still more arguments */
1606 /* and the next argument is not a keyword, */
1607 && !scm_is_keyword (*walk
))
1609 /* Jump to the next case-lambda* clause. */
1614 /* Otherwise, finish as in bind-optionals/shuffle: shuffle up,
1615 from walk to ntotal */
1616 scm_t_ptrdiff nshuf
= sp
- walk
+ 1, i
;
1617 sp
= (fp
- 1) + ntotal
+ nshuf
;
1619 for (i
= 0; i
< nshuf
; i
++)
1620 sp
[-i
] = walk
[nshuf
-i
-1];
1622 /* and fill optionals & keyword args with SCM_UNDEFINED */
1623 while (walk
<= (fp
- 1) + ntotal
)
1624 *walk
++ = SCM_UNDEFINED
;
1632 (defun renumber-ops ()
1633 "start from top of buffer and renumber 'VM_DEFINE_FOO (\n' sequences"
1636 (let ((counter -1)) (goto-char (point-min))
1637 (while (re-search-forward "^VM_DEFINE_[^ ]+ (\\([^,]+\\)," (point-max) t)
1639 (number-to-string (setq counter (1+ counter)))