Mercurial > hg > xemacs-beta
comparison src/eval.c @ 4677:8f1ee2d15784
Support full Common Lisp multiple values in C.
lisp/ChangeLog
2009-08-11 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp.el :
Update this file to support full C-level multiple values. This
involves:
-- Four new bytecodes, and special compiler functions to compile
multiple-value-call, multiple-value-list-internal, values,
values-list, and, since it now needs to pass back multiple values
and is a special form, throw.
-- There's a new compiler variable, byte-compile-checks-on-load,
which is a list of forms that are evaluated at the very start of a
file, with an error thrown if any of them give nil.
-- The header is now inserted *after* compilation, giving a chance
for the compilation process to influence what those checks
are. There is still a check done before compilation for non-ASCII
characters, to try to turn off dynamic docstrings if appopriate,
in `byte-compile-maybe-reset-coding'.
Space is reserved for checks; comments describing the version of
the byte compiler generating the file are inserted if space
remains for them.
* bytecomp.el (byte-compile-version):
Update this, we're a newer version of the byte compiler.
* byte-optimize.el (byte-optimize-funcall):
Correct a comment.
* bytecomp.el (byte-compile-lapcode):
Discard the arg with byte-multiple-value-call.
* bytecomp.el (byte-compile-checks-and-comments-space):
New variable, describe how many octets to reserve for checks at
the start of byte-compiled files.
* cl-compat.el:
Remove the fake multiple-value implementation. Have the functions
that use it use the real multiple-value implementation instead.
* cl-macs.el (cl-block-wrapper, cl-block-throw):
Revise the byte-compile properties of these symbols to work now
we've made throw into a special form; keep the byte-compile
properties as anonymous lambdas, since we don't have docstrings
for them.
* cl-macs.el (multiple-value-bind, multiple-value-setq)
(multiple-value-list, nth-value):
Update these functions to work with the C support for multiple
values.
* cl-macs.el (values):
Modify the setf handler for this to call
#'multiple-value-list-internal appropriately.
* cl-macs.el (cl-setf-do-store):
If the store form is a cons, treat it specially as wrapping the
store value.
* cl.el (cl-block-wrapper):
Make this an alias of #'and, not #'identity, since it needs to
pass back multiple values.
* cl.el (multiple-value-apply):
We no longer support this, mark it obsolete.
* lisp-mode.el (eval-interactive-verbose):
Remove a useless space in the docstring.
* lisp-mode.el (eval-interactive):
Update this function and its docstring. It now passes back a list,
basically wrapping any eval calls with multiple-value-list. This
allows multiple values to be printed by default in *scratch*.
* lisp-mode.el (prin1-list-as-multiple-values):
New function, printing a list as multiple values in the manner of
Bruno Haible's clisp, separating each entry with " ;\n".
* lisp-mode.el (eval-last-sexp):
Call #'prin1-list-as-multiple-values on the return value of
#'eval-interactive.
* lisp-mode.el (eval-defun):
Call #'prin1-list-as-multiple-values on the return value of
#'eval-interactive.
* mouse.el (mouse-eval-sexp):
Deal with lists corresponding to multiple values from
#'eval-interactive. Call #'cl-prettyprint, which is always
available, instead of sometimes calling #'pprint and sometimes
falling back to prin1.
* obsolete.el (obsolete-throw):
New function, called from eval.c when #'funcall encounters an
attempt to call #'throw (now a special form) as a function. Only
needed for compatibility with 21.4 byte-code.
man/ChangeLog addition:
2009-08-11 Aidan Kehoe <kehoea@parhasard.net>
* cl.texi (Organization):
Remove references to the obsolete multiple-value emulating code.
src/ChangeLog addition:
2009-08-11 Aidan Kehoe <kehoea@parhasard.net>
* bytecode.c (enum Opcode /* Byte codes */):
Add four new bytecodes, to deal with multiple values.
(POP_WITH_MULTIPLE_VALUES): New macro.
(POP): Modify this macro to ignore multiple values.
(DISCARD_PRESERVING_MULTIPLE_VALUES): New macro.
(DISCARD): Modify this macro to ignore multiple values.
(TOP_WITH_MULTIPLE_VALUES): New macro.
(TOP_ADDRESS): New macro.
(TOP): Modify this macro to ignore multiple values.
(TOP_LVALUE): New macro.
(Bcall): Ignore multiple values where appropriate.
(Breturn): Pass back multiple values.
(Bdup): Preserve multiple values.
Use TOP_LVALUE with most bytecodes that assign anything to
anything.
(Bbind_multiple_value_limits, Bmultiple_value_call,
Bmultiple_value_list_internal, Bthrow): Implement the new
bytecodes.
(Bgotoifnilelsepop, Bgotoifnonnilelsepop, BRgotoifnilelsepop,
BRgotoifnonnilelsepop):
Discard any multiple values.
* callint.c (Fcall_interactively):
Ignore multiple values when calling #'eval, in two places.
* device-x.c (x_IO_error_handler):
* macros.c (pop_kbd_macro_event):
* eval.c (Fsignal):
* eval.c (flagged_a_squirmer):
Call throw_or_bomb_out, not Fthrow, now that the latter is a
special form.
* eval.c:
Make Qthrow, Qobsolete_throw available as symbols.
Provide multiple_value_current_limit, multiple-values-limit (the
latter as specified by Common Lisp.
* eval.c (For):
Ignore multiple values when comparing with Qnil, but pass any
multiple values back for the last arg.
* eval.c (Fand):
Ditto.
* eval.c (Fif):
Ignore multiple values when examining the result of the
condition.
* eval.c (Fcond):
Ignore multiple values when comparing what the clauses give, but
pass them back if a clause gave non-nil.
* eval.c (Fprog2):
Never pass back multiple values.
* eval.c (FletX, Flet):
Ignore multiple when evaluating what exactly symbols should be
bound to.
* eval.c (Fwhile):
Ignore multiple values when evaluating the test.
* eval.c (Fsetq, Fdefvar, Fdefconst):
Ignore multiple values.
* eval.c (Fthrow):
Declare this as a special form; ignore multiple values for TAG,
preserve them for VALUE.
* eval.c (throw_or_bomb_out):
Make this available to other files, now Fthrow is a special form.
* eval.c (Feval):
Ignore multiple values when calling a compiled function, a
non-special-form subr, or a lambda expression.
* eval.c (Ffuncall):
If we attempt to call #'throw (now a special form) as a function,
don't error, call #'obsolete-throw instead.
* eval.c (make_multiple_value, multiple_value_aset)
(multiple_value_aref, print_multiple_value, mark_multiple_value)
(size_multiple_value):
Implement the multiple_value type. Add a long comment describing
our implementation.
* eval.c (bind_multiple_value_limits):
New function, used by the bytecode and by #'multiple-value-call,
#'multiple-value-list-internal.
* eval.c (multiple_value_call):
New function, used by the bytecode and #'multiple-value-call.
* eval.c (Fmultiple_value_call):
New special form.
* eval.c (multiple_value_list_internal):
New function, used by the byte code and
#'multiple-value-list-internal.
* eval.c (Fmultiple_value_list_internal, Fmultiple_value_prog1):
New special forms.
* eval.c (Fvalues, Fvalues_list):
New Lisp functions.
* eval.c (values2):
New function, for C code returning multiple values.
* eval.c (syms_of_eval):
Make our new Lisp functions and symbols available.
* eval.c (multiple-values-limit):
Make this available to Lisp.
* event-msw.c (dde_eval_string):
* event-stream.c (execute_help_form):
* glade.c (connector):
* glyphs-widget.c (glyph_instantiator_to_glyph):
* glyphs.c (evaluate_xpm_color_symbols):
* gui-x.c (wv_set_evalable_slot, button_item_to_widget_value):
* gui.c (gui_item_value, gui_item_display_flush_left):
* lread.c (check_if_suppressed):
* menubar-gtk.c (menu_convert, menu_descriptor_to_widget_1):
* menubar-msw.c (populate_menu_add_item):
* print.c (Fwith_output_to_temp_buffer):
* symbols.c (Fsetq_default):
Ignore multiple values when calling Feval.
* symeval.h:
Add the header declarations necessary for the multiple-values
implementation.
* inline.c:
#include symeval.h, now that it has some inline functions.
* lisp.h:
Update Fthrow's declaration. Make throw_or_bomb_out available to
all files.
* lrecord.h (enum lrecord_type):
Add the multiple_value type here.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sun, 16 Aug 2009 20:55:49 +0100 |
parents | f8d7d8202635 |
children | cdabd56ce1b5 |
comparison
equal
deleted
inserted
replaced
4676:e3feb329bda9 | 4677:8f1ee2d15784 |
---|---|
239 Lisp_Object Qsetq; | 239 Lisp_Object Qsetq; |
240 Lisp_Object Qdisplay_warning; | 240 Lisp_Object Qdisplay_warning; |
241 Lisp_Object Vpending_warnings, Vpending_warnings_tail; | 241 Lisp_Object Vpending_warnings, Vpending_warnings_tail; |
242 Lisp_Object Qif; | 242 Lisp_Object Qif; |
243 | 243 |
244 Lisp_Object Qthrow; | |
245 Lisp_Object Qobsolete_throw; | |
246 | |
247 static int first_desired_multiple_value; | |
248 /* Used outside this file, somewhat uncleanly, in the IGNORE_MULTIPLE_VALUES | |
249 macro: */ | |
250 int multiple_value_current_limit; | |
251 | |
252 Fixnum Vmultiple_values_limit; | |
253 | |
244 /* Flags specifying which operations are currently inhibited. */ | 254 /* Flags specifying which operations are currently inhibited. */ |
245 int inhibit_flags; | 255 int inhibit_flags; |
246 | 256 |
247 /* Buffers, frames, windows, devices, and consoles created since most | 257 /* Buffers, frames, windows, devices, and consoles created since most |
248 recent active | 258 recent active |
818 DEFUN ("or", For, 0, UNEVALLED, 0, /* | 828 DEFUN ("or", For, 0, UNEVALLED, 0, /* |
819 Eval ARGS until one of them yields non-nil, then return that value. | 829 Eval ARGS until one of them yields non-nil, then return that value. |
820 The remaining ARGS are not evalled at all. | 830 The remaining ARGS are not evalled at all. |
821 If all args return nil, return nil. | 831 If all args return nil, return nil. |
822 | 832 |
833 Any multiple values from the last form, and only from the last form, are | |
834 passed back. See `values' and `multiple-value-bind'. | |
835 | |
823 arguments: (&rest ARGS) | 836 arguments: (&rest ARGS) |
824 */ | 837 */ |
825 (args)) | 838 (args)) |
826 { | 839 { |
827 /* This function can GC */ | 840 /* This function can GC */ |
828 REGISTER Lisp_Object val; | 841 REGISTER Lisp_Object val; |
829 | 842 |
830 LIST_LOOP_2 (arg, args) | 843 LIST_LOOP_3 (arg, args, tail) |
831 { | 844 { |
832 if (!NILP (val = Feval (arg))) | 845 if (!NILP (IGNORE_MULTIPLE_VALUES (val = Feval (arg)))) |
833 return val; | 846 { |
834 } | 847 if (NILP (XCDR (tail))) |
835 | 848 { |
836 return Qnil; | 849 /* Pass back multiple values if this is the last one: */ |
850 return val; | |
851 } | |
852 | |
853 return IGNORE_MULTIPLE_VALUES (val); | |
854 } | |
855 } | |
856 | |
857 return val; | |
837 } | 858 } |
838 | 859 |
839 DEFUN ("and", Fand, 0, UNEVALLED, 0, /* | 860 DEFUN ("and", Fand, 0, UNEVALLED, 0, /* |
840 Eval ARGS until one of them yields nil, then return nil. | 861 Eval ARGS until one of them yields nil, then return nil. |
841 The remaining ARGS are not evalled at all. | 862 The remaining ARGS are not evalled at all. |
842 If no arg yields nil, return the last arg's value. | 863 If no arg yields nil, return the last arg's value. |
843 | 864 |
865 Any multiple values from the last form, and only from the last form, are | |
866 passed back. See `values' and `multiple-value-bind'. | |
867 | |
844 arguments: (&rest ARGS) | 868 arguments: (&rest ARGS) |
845 */ | 869 */ |
846 (args)) | 870 (args)) |
847 { | 871 { |
848 /* This function can GC */ | 872 /* This function can GC */ |
849 REGISTER Lisp_Object val = Qt; | 873 REGISTER Lisp_Object val = Qt; |
850 | 874 |
851 LIST_LOOP_2 (arg, args) | 875 LIST_LOOP_3 (arg, args, tail) |
852 { | 876 { |
853 if (NILP (val = Feval (arg))) | 877 if (NILP (IGNORE_MULTIPLE_VALUES (val = Feval (arg)))) |
854 return val; | 878 { |
879 if (NILP (XCDR (tail))) | |
880 { | |
881 /* Pass back any multiple values for the last form: */ | |
882 return val; | |
883 } | |
884 | |
885 return Qnil; | |
886 } | |
855 } | 887 } |
856 | 888 |
857 return val; | 889 return val; |
858 } | 890 } |
859 | 891 |
870 /* This function can GC */ | 902 /* This function can GC */ |
871 Lisp_Object condition = XCAR (args); | 903 Lisp_Object condition = XCAR (args); |
872 Lisp_Object then_form = XCAR (XCDR (args)); | 904 Lisp_Object then_form = XCAR (XCDR (args)); |
873 Lisp_Object else_forms = XCDR (XCDR (args)); | 905 Lisp_Object else_forms = XCDR (XCDR (args)); |
874 | 906 |
875 if (!NILP (Feval (condition))) | 907 if (!NILP (IGNORE_MULTIPLE_VALUES (Feval (condition)))) |
876 return Feval (then_form); | 908 return Feval (then_form); |
877 else | 909 else |
878 return Fprogn (else_forms); | 910 return Fprogn (else_forms); |
879 } | 911 } |
880 | 912 |
933 REGISTER Lisp_Object val; | 965 REGISTER Lisp_Object val; |
934 | 966 |
935 LIST_LOOP_2 (clause, args) | 967 LIST_LOOP_2 (clause, args) |
936 { | 968 { |
937 CHECK_CONS (clause); | 969 CHECK_CONS (clause); |
938 if (!NILP (val = Feval (XCAR (clause)))) | 970 if (!NILP (val = IGNORE_MULTIPLE_VALUES (Feval (XCAR (clause))))) |
939 { | 971 { |
940 if (!NILP (clause = XCDR (clause))) | 972 if (!NILP (clause = XCDR (clause))) |
941 { | 973 { |
942 CHECK_TRUE_LIST (clause); | 974 CHECK_TRUE_LIST (clause); |
975 /* Pass back any multiple values here: */ | |
943 val = Fprogn (clause); | 976 val = Fprogn (clause); |
944 } | 977 } |
945 return val; | 978 return val; |
946 } | 979 } |
947 } | 980 } |
986 (args)) | 1019 (args)) |
987 { | 1020 { |
988 Lisp_Object val; | 1021 Lisp_Object val; |
989 struct gcpro gcpro1; | 1022 struct gcpro gcpro1; |
990 | 1023 |
991 val = Feval (XCAR (args)); | 1024 val = IGNORE_MULTIPLE_VALUES (Feval (Fcar (args))); |
992 | 1025 |
993 GCPRO1 (val); | 1026 GCPRO1 (val); |
994 | 1027 |
995 { | 1028 { |
996 LIST_LOOP_2 (form, XCDR (args)) | 1029 LIST_LOOP_2 (form, XCDR (args)) |
1015 Lisp_Object val; | 1048 Lisp_Object val; |
1016 struct gcpro gcpro1; | 1049 struct gcpro gcpro1; |
1017 | 1050 |
1018 Feval (XCAR (args)); | 1051 Feval (XCAR (args)); |
1019 args = XCDR (args); | 1052 args = XCDR (args); |
1020 val = Feval (XCAR (args)); | 1053 |
1054 val = IGNORE_MULTIPLE_VALUES (Feval (XCAR (args))); | |
1055 | |
1021 args = XCDR (args); | 1056 args = XCDR (args); |
1022 | 1057 |
1023 GCPRO1 (val); | 1058 GCPRO1 (val); |
1024 | 1059 |
1025 { | 1060 { |
1060 if (NILP (tem)) | 1095 if (NILP (tem)) |
1061 value = Qnil; | 1096 value = Qnil; |
1062 else | 1097 else |
1063 { | 1098 { |
1064 CHECK_CONS (tem); | 1099 CHECK_CONS (tem); |
1065 value = Feval (XCAR (tem)); | 1100 value = IGNORE_MULTIPLE_VALUES (Feval (XCAR (tem))); |
1066 if (!NILP (XCDR (tem))) | 1101 if (!NILP (XCDR (tem))) |
1067 sferror | 1102 sferror |
1068 ("`let' bindings can have only one value-form", var); | 1103 ("`let' bindings can have only one value-form", var); |
1069 } | 1104 } |
1070 } | 1105 } |
1118 if (NILP (tem)) | 1153 if (NILP (tem)) |
1119 *value = Qnil; | 1154 *value = Qnil; |
1120 else | 1155 else |
1121 { | 1156 { |
1122 CHECK_CONS (tem); | 1157 CHECK_CONS (tem); |
1123 *value = Feval (XCAR (tem)); | 1158 *value = IGNORE_MULTIPLE_VALUES (Feval (XCAR (tem))); |
1124 gcpro1.nvars = idx; | 1159 gcpro1.nvars = idx; |
1125 | 1160 |
1126 if (!NILP (XCDR (tem))) | 1161 if (!NILP (XCDR (tem))) |
1127 sferror | 1162 sferror |
1128 ("`let' bindings can have only one value-form", var); | 1163 ("`let' bindings can have only one value-form", var); |
1155 { | 1190 { |
1156 /* This function can GC */ | 1191 /* This function can GC */ |
1157 Lisp_Object test = XCAR (args); | 1192 Lisp_Object test = XCAR (args); |
1158 Lisp_Object body = XCDR (args); | 1193 Lisp_Object body = XCDR (args); |
1159 | 1194 |
1160 while (!NILP (Feval (test))) | 1195 while (!NILP (IGNORE_MULTIPLE_VALUES (Feval (test)))) |
1161 { | 1196 { |
1162 QUIT; | 1197 QUIT; |
1163 Fprogn (body); | 1198 Fprogn (body); |
1164 } | 1199 } |
1165 | 1200 |
1187 Fsignal (Qwrong_number_of_arguments, list2 (Qsetq, make_int (nargs))); | 1222 Fsignal (Qwrong_number_of_arguments, list2 (Qsetq, make_int (nargs))); |
1188 | 1223 |
1189 GC_PROPERTY_LIST_LOOP_3 (symbol, val, args) | 1224 GC_PROPERTY_LIST_LOOP_3 (symbol, val, args) |
1190 { | 1225 { |
1191 val = Feval (val); | 1226 val = Feval (val); |
1227 val = IGNORE_MULTIPLE_VALUES (val); | |
1192 Fset (symbol, val); | 1228 Fset (symbol, val); |
1193 retval = val; | 1229 retval = val; |
1194 } | 1230 } |
1195 | 1231 |
1196 END_GC_PROPERTY_LIST_LOOP (symbol); | 1232 END_GC_PROPERTY_LIST_LOOP (symbol); |
1309 | 1345 |
1310 if (NILP (Fdefault_boundp (sym))) | 1346 if (NILP (Fdefault_boundp (sym))) |
1311 { | 1347 { |
1312 struct gcpro gcpro1; | 1348 struct gcpro gcpro1; |
1313 GCPRO1 (val); | 1349 GCPRO1 (val); |
1314 val = Feval (val); | 1350 val = IGNORE_MULTIPLE_VALUES (Feval (val)); |
1315 Fset_default (sym, val); | 1351 Fset_default (sym, val); |
1316 UNGCPRO; | 1352 UNGCPRO; |
1317 } | 1353 } |
1318 | 1354 |
1319 if (!NILP (args = XCDR (args))) | 1355 if (!NILP (args = XCDR (args))) |
1358 Lisp_Object sym = XCAR (args); | 1394 Lisp_Object sym = XCAR (args); |
1359 Lisp_Object val = Feval (XCAR (args = XCDR (args))); | 1395 Lisp_Object val = Feval (XCAR (args = XCDR (args))); |
1360 struct gcpro gcpro1; | 1396 struct gcpro gcpro1; |
1361 | 1397 |
1362 GCPRO1 (val); | 1398 GCPRO1 (val); |
1399 | |
1400 val = IGNORE_MULTIPLE_VALUES (val); | |
1363 | 1401 |
1364 Fset_default (sym, val); | 1402 Fset_default (sym, val); |
1365 | 1403 |
1366 UNGCPRO; | 1404 UNGCPRO; |
1367 | 1405 |
1661 throw_level = 0; | 1699 throw_level = 0; |
1662 #endif | 1700 #endif |
1663 LONGJMP (c->jmp, 1); | 1701 LONGJMP (c->jmp, 1); |
1664 } | 1702 } |
1665 | 1703 |
1666 static DECLARE_DOESNT_RETURN (throw_or_bomb_out (Lisp_Object, Lisp_Object, int, | 1704 DECLARE_DOESNT_RETURN (throw_or_bomb_out (Lisp_Object, Lisp_Object, int, |
1667 Lisp_Object, Lisp_Object)); | 1705 Lisp_Object, Lisp_Object)); |
1668 | 1706 |
1669 static DOESNT_RETURN | 1707 DOESNT_RETURN |
1670 throw_or_bomb_out (Lisp_Object tag, Lisp_Object val, int bomb_out_p, | 1708 throw_or_bomb_out (Lisp_Object tag, Lisp_Object val, int bomb_out_p, |
1671 Lisp_Object sig, Lisp_Object data) | 1709 Lisp_Object sig, Lisp_Object data) |
1672 { | 1710 { |
1673 #ifdef DEFEND_AGAINST_THROW_RECURSION | 1711 #ifdef DEFEND_AGAINST_THROW_RECURSION |
1674 /* die if we recurse more than is reasonable */ | 1712 /* die if we recurse more than is reasonable */ |
1737 that is EQ() to TAG. When it finds it, it will longjmp() | 1775 that is EQ() to TAG. When it finds it, it will longjmp() |
1738 back to the place that established the catch (in this case, | 1776 back to the place that established the catch (in this case, |
1739 condition_case_1). See below for more info. | 1777 condition_case_1). See below for more info. |
1740 */ | 1778 */ |
1741 | 1779 |
1742 DEFUN_NORETURN ("throw", Fthrow, 2, 2, 0, /* | 1780 DEFUN_NORETURN ("throw", Fthrow, 2, UNEVALLED, 0, /* |
1743 Throw to the catch for TAG and return VALUE from it. | 1781 Throw to the catch for TAG and return VALUE from it. |
1744 Both TAG and VALUE are evalled. Tags are the same iff they are `eq'. | 1782 |
1783 Both TAG and VALUE are evalled, and multiple values in VALUE will be passed | |
1784 back. Tags are the same if and only if they are `eq'. | |
1785 | |
1786 arguments: (TAG VALUE) | |
1745 */ | 1787 */ |
1746 (tag, value)) | 1788 (args)) |
1747 { | 1789 { |
1790 int nargs; | |
1791 Lisp_Object tag, value; | |
1792 | |
1793 GET_LIST_LENGTH (args, nargs); | |
1794 if (nargs != 2) | |
1795 { | |
1796 Fsignal (Qwrong_number_of_arguments, list2 (Qthrow, make_int (nargs))); | |
1797 } | |
1798 | |
1799 tag = IGNORE_MULTIPLE_VALUES (Feval (XCAR(args))); | |
1800 | |
1801 value = Feval (XCAR (XCDR (args))); | |
1802 | |
1748 throw_or_bomb_out (tag, value, 0, Qnil, Qnil); /* Doesn't return */ | 1803 throw_or_bomb_out (tag, value, 0, Qnil, Qnil); /* Doesn't return */ |
1749 RETURN_NOT_REACHED (Qnil); | 1804 RETURN_NOT_REACHED (Qnil); |
1750 } | 1805 } |
1751 | 1806 |
1752 DEFUN ("unwind-protect", Funwind_protect, 1, UNEVALLED, 0, /* | 1807 DEFUN ("unwind-protect", Funwind_protect, 1, UNEVALLED, 0, /* |
2358 /* t is used by handlers for all conditions, set up by C code. | 2413 /* t is used by handlers for all conditions, set up by C code. |
2359 * debugger is not called even if debug_on_error */ | 2414 * debugger is not called even if debug_on_error */ |
2360 else if (EQ (handler_data, Qt)) | 2415 else if (EQ (handler_data, Qt)) |
2361 { | 2416 { |
2362 UNGCPRO; | 2417 UNGCPRO; |
2363 return Fthrow (handlers, Fcons (error_symbol, data)); | 2418 throw_or_bomb_out (handlers, Fcons (error_symbol, data), |
2419 0, Qnil, Qnil); | |
2364 } | 2420 } |
2365 /* `error' is used similarly to the way `t' is used, but in | 2421 /* `error' is used similarly to the way `t' is used, but in |
2366 addition it invokes the debugger if debug_on_error. | 2422 addition it invokes the debugger if debug_on_error. |
2367 This is normally used for the outer command-loop error | 2423 This is normally used for the outer command-loop error |
2368 handler. */ | 2424 handler. */ |
2377 UNGCPRO; | 2433 UNGCPRO; |
2378 if (!UNBOUNDP (tem)) | 2434 if (!UNBOUNDP (tem)) |
2379 return return_from_signal (tem); | 2435 return return_from_signal (tem); |
2380 | 2436 |
2381 tem = Fcons (error_symbol, data); | 2437 tem = Fcons (error_symbol, data); |
2382 return Fthrow (handlers, tem); | 2438 throw_or_bomb_out (handlers, tem, 0, Qnil, Qnil); |
2383 } | 2439 } |
2384 else | 2440 else |
2385 { | 2441 { |
2386 /* handler established by real (Lisp) condition-case */ | 2442 /* handler established by real (Lisp) condition-case */ |
2387 Lisp_Object h; | 2443 Lisp_Object h; |
2401 if (!UNBOUNDP (tem)) | 2457 if (!UNBOUNDP (tem)) |
2402 return return_from_signal (tem); | 2458 return return_from_signal (tem); |
2403 | 2459 |
2404 /* Doesn't return */ | 2460 /* Doesn't return */ |
2405 tem = Fcons (Fcons (error_symbol, data), Fcdr (clause)); | 2461 tem = Fcons (Fcons (error_symbol, data), Fcdr (clause)); |
2406 return Fthrow (handlers, tem); | 2462 throw_or_bomb_out (handlers, tem, 0, Qnil, Qnil); |
2407 } | 2463 } |
2408 } | 2464 } |
2409 } | 2465 } |
2410 } | 2466 } |
2411 | 2467 |
3663 gcpro1.nvars = 0; | 3719 gcpro1.nvars = 0; |
3664 | 3720 |
3665 { | 3721 { |
3666 LIST_LOOP_2 (arg, original_args) | 3722 LIST_LOOP_2 (arg, original_args) |
3667 { | 3723 { |
3668 *p++ = Feval (arg); | 3724 *p++ = IGNORE_MULTIPLE_VALUES (Feval (arg)); |
3669 gcpro1.nvars++; | 3725 gcpro1.nvars++; |
3670 } | 3726 } |
3671 } | 3727 } |
3672 | 3728 |
3673 /* &optional args default to nil. */ | 3729 /* &optional args default to nil. */ |
3694 gcpro1.nvars = 0; | 3750 gcpro1.nvars = 0; |
3695 | 3751 |
3696 { | 3752 { |
3697 LIST_LOOP_2 (arg, original_args) | 3753 LIST_LOOP_2 (arg, original_args) |
3698 { | 3754 { |
3699 *p++ = Feval (arg); | 3755 *p++ = IGNORE_MULTIPLE_VALUES (Feval (arg)); |
3700 gcpro1.nvars++; | 3756 gcpro1.nvars++; |
3701 } | 3757 } |
3702 } | 3758 } |
3703 | 3759 |
3704 backtrace.args = args; | 3760 backtrace.args = args; |
3727 gcpro1.nvars = 0; | 3783 gcpro1.nvars = 0; |
3728 | 3784 |
3729 { | 3785 { |
3730 LIST_LOOP_2 (arg, original_args) | 3786 LIST_LOOP_2 (arg, original_args) |
3731 { | 3787 { |
3732 *p++ = Feval (arg); | 3788 *p++ = IGNORE_MULTIPLE_VALUES (Feval (arg)); |
3733 gcpro1.nvars++; | 3789 gcpro1.nvars++; |
3734 } | 3790 } |
3735 } | 3791 } |
3736 | 3792 |
3737 backtrace.args = args; | 3793 backtrace.args = args; |
3776 gcpro1.nvars = 0; | 3832 gcpro1.nvars = 0; |
3777 | 3833 |
3778 { | 3834 { |
3779 LIST_LOOP_2 (arg, original_args) | 3835 LIST_LOOP_2 (arg, original_args) |
3780 { | 3836 { |
3781 *p++ = Feval (arg); | 3837 *p++ = IGNORE_MULTIPLE_VALUES (Feval (arg)); |
3782 gcpro1.nvars++; | 3838 gcpro1.nvars++; |
3783 } | 3839 } |
3784 } | 3840 } |
3785 | 3841 |
3786 UNGCPRO; | 3842 UNGCPRO; |
3956 val = SUBR_FUNCTION (subr, MANY) (fun_nargs, fun_args); | 4012 val = SUBR_FUNCTION (subr, MANY) (fun_nargs, fun_args); |
3957 PROFILE_EXIT_FUNCTION (); | 4013 PROFILE_EXIT_FUNCTION (); |
3958 } | 4014 } |
3959 else if (max_args == UNEVALLED) /* Can't funcall a special form */ | 4015 else if (max_args == UNEVALLED) /* Can't funcall a special form */ |
3960 { | 4016 { |
4017 /* Ugh, ugh, ugh. */ | |
4018 if (EQ (fun, XSYMBOL_FUNCTION (Qthrow))) | |
4019 { | |
4020 args[0] = Qobsolete_throw; | |
4021 goto retry; | |
4022 } | |
3961 goto invalid_function; | 4023 goto invalid_function; |
3962 } | 4024 } |
3963 else | 4025 else |
3964 { | 4026 { |
3965 wrong_number_of_arguments: | 4027 wrong_number_of_arguments: |
4236 | 4298 |
4237 RETURN_UNGCPRO (Ffuncall (funcall_nargs, funcall_args)); | 4299 RETURN_UNGCPRO (Ffuncall (funcall_nargs, funcall_args)); |
4238 } | 4300 } |
4239 } | 4301 } |
4240 | 4302 |
4241 | |
4242 /* Apply lambda list FUN to the NARGS evaluated arguments in ARGS and | 4303 /* Apply lambda list FUN to the NARGS evaluated arguments in ARGS and |
4243 return the result of evaluation. */ | 4304 return the result of evaluation. */ |
4244 | 4305 |
4245 static Lisp_Object | 4306 static Lisp_Object |
4246 funcall_lambda (Lisp_Object fun, int nargs, Lisp_Object args[]) | 4307 funcall_lambda (Lisp_Object fun, int nargs, Lisp_Object args[]) |
4291 wrong_number_of_arguments: | 4352 wrong_number_of_arguments: |
4292 return signal_wrong_number_of_arguments_error (fun, nargs); | 4353 return signal_wrong_number_of_arguments_error (fun, nargs); |
4293 | 4354 |
4294 invalid_function: | 4355 invalid_function: |
4295 return signal_invalid_function_error (fun); | 4356 return signal_invalid_function_error (fun); |
4357 } | |
4358 | |
4359 | |
4360 /* Multiple values. | |
4361 | |
4362 A multiple value object is returned by #'values if: | |
4363 | |
4364 -- The number of arguments to #'values is not one, and: | |
4365 -- Some special form in the call stack is prepared to handle more than | |
4366 one multiple value. | |
4367 | |
4368 The return value of #'values-list is analogous to that of #'values. | |
4369 | |
4370 Henry Baker, in https://eprints.kfupm.edu.sa/31898/1/31898.pdf ("CONS | |
4371 Should not CONS its Arguments, or, a Lazy Alloc is a Smart Alloc", ACM | |
4372 Sigplan Notices 27,3 (March 1992),24-34.) says it should be possible to | |
4373 allocate Common Lisp multiple-value objects on the stack, but this | |
4374 assumes that variable-length records can be allocated on the stack, | |
4375 something not true for us. As far as I can tell, it also ignores the | |
4376 contexts where multiple-values need to be thrown, or maybe it thinks such | |
4377 objects should be converted to heap allocation at that point. | |
4378 | |
4379 The specific multiple values saved and returned depend on how many | |
4380 multiple-values special forms in the stack are interested in; for | |
4381 example, if #'multiple-value-call is somewhere in the call stack, all | |
4382 values passed to #'values will be saved and returned. If an expansion of | |
4383 #'multiple-value-setq with 10 SYMS is the only part of the call stack | |
4384 interested in multiple values, then a maximum of ten multiple values will | |
4385 be saved and returned. | |
4386 | |
4387 (#'throw passes back multiple values in its VALUE argument; this is why | |
4388 we can't just take the details of the most immediate | |
4389 #'multiple-value-{whatever} call to work out which values to save, we | |
4390 need to look at the whole stack, or, equivalently, the dynamic variables | |
4391 we set to reflect the whole stack.) | |
4392 | |
4393 The first value passed to #'values will always be saved, since that is | |
4394 needed to convert a multiple value object into a single value object, | |
4395 something that is normally necessary independent of how many functions in | |
4396 the call stack are interested in multiple values. | |
4397 | |
4398 However many values (for values of "however many" that are not one) are | |
4399 saved and restored, the multiple value object knows how many arguments it | |
4400 would contain were none to have been discarded, and will indicate this | |
4401 on being printed from within GDB. | |
4402 | |
4403 In lisp-interaction-mode, no multiple values should be discarded (unless | |
4404 they need to be for the sake of the correctness of the program); | |
4405 #'eval-interactive-with-multiple-value-list in lisp-mode.el wraps its | |
4406 #'eval calls with #'multiple-value-list calls to avoid this. This means | |
4407 that there is a small performance and memory penalty for code evaluated | |
4408 in *scratch*; use M-: EXPRESSION RET if you really need to avoid | |
4409 this. Lisp code execution that is not ultimately from hitting C-j in | |
4410 *scratch*--that is, the vast vast majority of Lisp code execution--does | |
4411 not have this penalty. | |
4412 | |
4413 Probably the most important aspect of multiple values is stated with | |
4414 admirable clarity by CLTL2: | |
4415 | |
4416 "No matter how many values a form produces, if the form is an argument | |
4417 form in a function call, then exactly one value (the first one) is | |
4418 used." | |
4419 | |
4420 This means that most contexts, most of the time, will never see multiple | |
4421 values. There are important exceptions; search the web for that text in | |
4422 quotation marks and read the related chapter. This code handles all of | |
4423 them, to my knowledge. Aidan Kehoe, Mon Mar 16 00:17:39 GMT 2009. */ | |
4424 | |
4425 static Lisp_Object | |
4426 make_multiple_value (Lisp_Object first_value, Elemcount count, | |
4427 Elemcount first_desired, Elemcount upper_limit) | |
4428 { | |
4429 Bytecount sizem; | |
4430 struct multiple_value *mv; | |
4431 Elemcount i, allocated_count; | |
4432 | |
4433 assert (count != 1); | |
4434 | |
4435 if (1 != upper_limit && (0 == first_desired)) | |
4436 { | |
4437 /* We always allocate element zero, and that's taken into account when | |
4438 working out allocated_count: */ | |
4439 first_desired = 1; | |
4440 } | |
4441 | |
4442 if (first_desired >= count) | |
4443 { | |
4444 /* We can't pass anything back that our caller is interested in. Only | |
4445 allocate for the first argument. */ | |
4446 allocated_count = 1; | |
4447 } | |
4448 else | |
4449 { | |
4450 allocated_count = 1 + ((upper_limit > count ? count : upper_limit) | |
4451 - first_desired); | |
4452 } | |
4453 | |
4454 sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (multiple_value, | |
4455 Lisp_Object, | |
4456 contents, allocated_count); | |
4457 mv = (multiple_value *) BASIC_ALLOC_LCRECORD (sizem, | |
4458 &lrecord_multiple_value); | |
4459 | |
4460 mv->count = count; | |
4461 mv->first_desired = first_desired; | |
4462 mv->allocated_count = allocated_count; | |
4463 mv->contents[0] = first_value; | |
4464 | |
4465 for (i = first_desired; i < upper_limit && i < count; ++i) | |
4466 { | |
4467 mv->contents[1 + (i - first_desired)] = Qunbound; | |
4468 } | |
4469 | |
4470 return wrap_multiple_value (mv); | |
4471 } | |
4472 | |
4473 void | |
4474 multiple_value_aset (Lisp_Object obj, Elemcount index, Lisp_Object value) | |
4475 { | |
4476 struct multiple_value *mv = XMULTIPLE_VALUE (obj); | |
4477 Elemcount first_desired = mv->first_desired; | |
4478 Elemcount allocated_count = mv->allocated_count; | |
4479 | |
4480 if (index != 0 && | |
4481 (index < first_desired || index >= (first_desired + allocated_count))) | |
4482 { | |
4483 args_out_of_range (make_int (first_desired), | |
4484 make_int (first_desired + allocated_count)); | |
4485 } | |
4486 | |
4487 mv->contents[index == 0 ? 0 : 1 + (index - first_desired)] = value; | |
4488 } | |
4489 | |
4490 Lisp_Object | |
4491 multiple_value_aref (Lisp_Object obj, Elemcount index) | |
4492 { | |
4493 struct multiple_value *mv = XMULTIPLE_VALUE (obj); | |
4494 Elemcount first_desired = mv->first_desired; | |
4495 Elemcount allocated_count = mv->allocated_count; | |
4496 | |
4497 if (index != 0 && | |
4498 (index < first_desired || index >= (first_desired + allocated_count))) | |
4499 { | |
4500 args_out_of_range (make_int (first_desired), | |
4501 make_int (first_desired + allocated_count)); | |
4502 } | |
4503 | |
4504 return mv->contents[index == 0 ? 0 : 1 + (index - first_desired)]; | |
4505 } | |
4506 | |
4507 static void | |
4508 print_multiple_value (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
4509 { | |
4510 struct multiple_value *mv = XMULTIPLE_VALUE (obj); | |
4511 Elemcount first_desired = mv->first_desired; | |
4512 Elemcount allocated_count = mv->allocated_count; | |
4513 Elemcount count = mv->count, index; | |
4514 | |
4515 if (print_readably) | |
4516 { | |
4517 printing_unreadable_object ("multiple values"); | |
4518 } | |
4519 | |
4520 if (0 == count) | |
4521 { | |
4522 write_c_string (printcharfun, "#<zero-length multiple value>"); | |
4523 } | |
4524 | |
4525 for (index = 0; index < count;) | |
4526 { | |
4527 if (index != 0 && | |
4528 (index < first_desired || | |
4529 index >= (first_desired + (allocated_count - 1)))) | |
4530 { | |
4531 write_fmt_string (printcharfun, "#<discarded-multiple-value %d>", | |
4532 index); | |
4533 } | |
4534 else | |
4535 { | |
4536 print_internal (multiple_value_aref (obj, index), | |
4537 printcharfun, escapeflag); | |
4538 } | |
4539 | |
4540 ++index; | |
4541 | |
4542 if (count > 1 && index < count) | |
4543 { | |
4544 write_c_string (printcharfun, " ;\n"); | |
4545 } | |
4546 } | |
4547 } | |
4548 | |
4549 static Lisp_Object | |
4550 mark_multiple_value (Lisp_Object obj) | |
4551 { | |
4552 struct multiple_value *mv = XMULTIPLE_VALUE (obj); | |
4553 Elemcount index, allocated_count = mv->allocated_count; | |
4554 | |
4555 for (index = 0; index < allocated_count; ++index) | |
4556 { | |
4557 mark_object (mv->contents[index]); | |
4558 } | |
4559 | |
4560 return Qnil; | |
4561 } | |
4562 | |
4563 static Bytecount | |
4564 size_multiple_value (const void *lheader) | |
4565 { | |
4566 return FLEXIBLE_ARRAY_STRUCT_SIZEOF (struct multiple_value, | |
4567 Lisp_Object, contents, | |
4568 ((struct multiple_value *) lheader)-> | |
4569 allocated_count); | |
4570 } | |
4571 | |
4572 static const struct memory_description multiple_value_description[] = { | |
4573 { XD_LONG, offsetof (struct multiple_value, count) }, | |
4574 { XD_ELEMCOUNT, offsetof (struct multiple_value, allocated_count) }, | |
4575 { XD_LONG, offsetof (struct multiple_value, first_desired) }, | |
4576 { XD_LISP_OBJECT_ARRAY, offsetof (struct multiple_value, contents), | |
4577 XD_INDIRECT (1, 0) }, | |
4578 { XD_END } | |
4579 }; | |
4580 | |
4581 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("multiple-value", multiple_value, | |
4582 1, /*dumpable-flag*/ | |
4583 mark_multiple_value, | |
4584 print_multiple_value, 0, | |
4585 0, /* No equal method. */ | |
4586 0, /* No hash method. */ | |
4587 multiple_value_description, | |
4588 size_multiple_value, | |
4589 struct multiple_value); | |
4590 | |
4591 /* Given that FIRST and UPPER are the inclusive lower and exclusive upper | |
4592 bounds for the multiple values we're interested in, modify (or don't) the | |
4593 special variables used to indicate this to #'values and #'values-list. | |
4594 Returns the specpdl_depth() value before any modification. */ | |
4595 int | |
4596 bind_multiple_value_limits (int first, int upper) | |
4597 { | |
4598 int result = specpdl_depth(); | |
4599 | |
4600 if (!(upper > first)) | |
4601 { | |
4602 invalid_argument ("MULTIPLE-VALUE-UPPER-LIMIT must be greater than " | |
4603 " FIRST-DESIRED-MULTIPLE-VALUE", Qunbound); | |
4604 } | |
4605 | |
4606 if (upper > Vmultiple_values_limit) | |
4607 { | |
4608 args_out_of_range (make_int (upper), make_int (Vmultiple_values_limit)); | |
4609 } | |
4610 | |
4611 /* In the event that something back up the stack wants more multiple | |
4612 values than we do, we need to keep its figures for | |
4613 first_desired_multiple_value or multiple_value_current_limit both. It | |
4614 may be that the form will throw past us. | |
4615 | |
4616 If first_desired_multiple_value is zero, this means it hasn't ever been | |
4617 bound, and any value we have for first is appropriate to use. | |
4618 | |
4619 Zeroth element is always saved, no need to note that: */ | |
4620 if (0 == first) | |
4621 { | |
4622 first = 1; | |
4623 } | |
4624 | |
4625 if (0 == first_desired_multiple_value | |
4626 || first < first_desired_multiple_value) | |
4627 { | |
4628 internal_bind_int (&first_desired_multiple_value, first); | |
4629 } | |
4630 | |
4631 if (upper > multiple_value_current_limit) | |
4632 { | |
4633 internal_bind_int (&multiple_value_current_limit, upper); | |
4634 } | |
4635 | |
4636 return result; | |
4637 } | |
4638 | |
4639 Lisp_Object | |
4640 multiple_value_call (int nargs, Lisp_Object *args) | |
4641 { | |
4642 /* The argument order here is horrible: */ | |
4643 int i, speccount = XINT (args[3]); | |
4644 Lisp_Object result = Qnil, head = Fcons (args[0], Qnil), list_offset; | |
4645 struct gcpro gcpro1, gcpro2; | |
4646 Lisp_Object apply_args[2]; | |
4647 | |
4648 GCPRO2 (head, result); | |
4649 list_offset = head; | |
4650 | |
4651 assert (!(MULTIPLE_VALUEP (args[0]))); | |
4652 CHECK_FUNCTION (args[0]); | |
4653 | |
4654 /* Start at 4, to ignore the function, the speccount, and the arguments to | |
4655 multiple-values-limit (which we don't discard because | |
4656 #'multiple-value-list-internal needs them): */ | |
4657 for (i = 4; i < nargs; ++i) | |
4658 { | |
4659 result = args[i]; | |
4660 if (MULTIPLE_VALUEP (result)) | |
4661 { | |
4662 Lisp_Object val; | |
4663 Elemcount i, count = XMULTIPLE_VALUE_COUNT (result); | |
4664 | |
4665 for (i = 0; i < count; i++) | |
4666 { | |
4667 val = multiple_value_aref (result, i); | |
4668 assert (!UNBOUNDP (val)); | |
4669 | |
4670 XSETCDR (list_offset, Fcons (val, Qnil)); | |
4671 list_offset = XCDR (list_offset); | |
4672 } | |
4673 } | |
4674 else | |
4675 { | |
4676 XSETCDR (list_offset, Fcons (result, Qnil)); | |
4677 list_offset = XCDR (list_offset); | |
4678 } | |
4679 } | |
4680 | |
4681 apply_args [0] = XCAR (head); | |
4682 apply_args [1] = XCDR (head); | |
4683 | |
4684 unbind_to (speccount); | |
4685 | |
4686 RETURN_UNGCPRO (Fapply (countof(apply_args), apply_args)); | |
4687 } | |
4688 | |
4689 DEFUN ("multiple-value-call", Fmultiple_value_call, 1, UNEVALLED, 0, /* | |
4690 Call FUNCTION with arguments FORMS, using multiple values when returned. | |
4691 | |
4692 All of the (possibly multiple) values returned by each form in FORMS are | |
4693 gathered together, and given as arguments to FUNCTION; conceptually, this | |
4694 function is a version of `apply' that by-passes the multiple values | |
4695 infrastructure, treating multiple values as intercalated lists. | |
4696 | |
4697 arguments: (FUNCTION &rest FORMS) | |
4698 */ | |
4699 (args)) | |
4700 { | |
4701 int listcount, i = 0, speccount; | |
4702 Lisp_Object *constructed_args; | |
4703 struct gcpro gcpro1; | |
4704 | |
4705 GET_EXTERNAL_LIST_LENGTH (args, listcount); | |
4706 | |
4707 constructed_args = alloca_array (Lisp_Object, listcount + 3); | |
4708 | |
4709 /* Fcar so we error on non-cons: */ | |
4710 constructed_args[i] = IGNORE_MULTIPLE_VALUES (Feval (Fcar (args))); | |
4711 | |
4712 GCPRO1 (*constructed_args); | |
4713 gcpro1.nvars = ++i; | |
4714 | |
4715 /* The argument order is horrible here. */ | |
4716 constructed_args[i] = make_int (0); | |
4717 gcpro1.nvars = ++i; | |
4718 constructed_args[i] = make_int (Vmultiple_values_limit); | |
4719 gcpro1.nvars = ++i; | |
4720 | |
4721 speccount = bind_multiple_value_limits (0, Vmultiple_values_limit); | |
4722 constructed_args[i] = make_int (speccount); | |
4723 gcpro1.nvars = ++i; | |
4724 | |
4725 { | |
4726 LIST_LOOP_2 (elt, XCDR (args)) | |
4727 { | |
4728 constructed_args[i] = Feval (elt); | |
4729 gcpro1.nvars = ++i; | |
4730 } | |
4731 } | |
4732 | |
4733 RETURN_UNGCPRO (multiple_value_call (listcount + 3, constructed_args)); | |
4734 } | |
4735 | |
4736 Lisp_Object | |
4737 multiple_value_list_internal (int nargs, Lisp_Object *args) | |
4738 { | |
4739 int first = XINT (args[0]), upper = XINT (args[1]), | |
4740 speccount = XINT(args[2]); | |
4741 Lisp_Object result = Qnil; | |
4742 | |
4743 assert (nargs == 4); | |
4744 | |
4745 result = args[3]; | |
4746 | |
4747 unbind_to (speccount); | |
4748 | |
4749 if (MULTIPLE_VALUEP (result)) | |
4750 { | |
4751 Lisp_Object head = Fcons (Qnil, Qnil); | |
4752 Lisp_Object list_offset = head, val; | |
4753 Elemcount count = XMULTIPLE_VALUE_COUNT(result); | |
4754 | |
4755 for (; first < upper && first < count; ++first) | |
4756 { | |
4757 val = multiple_value_aref (result, first); | |
4758 assert (!UNBOUNDP (val)); | |
4759 | |
4760 XSETCDR (list_offset, Fcons (val, Qnil)); | |
4761 list_offset = XCDR (list_offset); | |
4762 } | |
4763 | |
4764 return XCDR (head); | |
4765 } | |
4766 else | |
4767 { | |
4768 if (first == 0) | |
4769 { | |
4770 return Fcons (result, Qnil); | |
4771 } | |
4772 else | |
4773 { | |
4774 return Qnil; | |
4775 } | |
4776 } | |
4777 } | |
4778 | |
4779 DEFUN ("multiple-value-list-internal", Fmultiple_value_list_internal, 3, | |
4780 UNEVALLED, 0, /* | |
4781 Evaluate FORM. Return a list of multiple vals reflecting the other two args. | |
4782 | |
4783 Don't use this. Use `multiple-value-list', the macro specified by Common | |
4784 Lisp, instead. | |
4785 | |
4786 FIRST-DESIRED-MULTIPLE-VALUE is the first element in list of multiple values | |
4787 to pass back. MULTIPLE-VALUE-UPPER-LIMIT is the exclusive upper limit on | |
4788 the indexes within the values that may be passed back; this function will | |
4789 never return a list longer than MULTIPLE-VALUE-UPPER-LIMIT - | |
4790 FIRST-DESIRED-MULTIPLE-VALUE. It may return a list shorter than that, if | |
4791 `values' or `values-list' do not supply enough elements. | |
4792 | |
4793 arguments: (FIRST-DESIRED-MULTIPLE-VALUE MULTIPLE-VALUE-UPPER-LIMIT FORM) | |
4794 */ | |
4795 (args)) | |
4796 { | |
4797 Lisp_Object argv[4]; | |
4798 int first, upper; | |
4799 struct gcpro gcpro1; | |
4800 | |
4801 argv[0] = IGNORE_MULTIPLE_VALUES (Feval (XCAR (args))); | |
4802 CHECK_NATNUM (argv[0]); | |
4803 first = XINT (argv[0]); | |
4804 | |
4805 GCPRO1 (argv[0]); | |
4806 gcpro1.nvars = 1; | |
4807 | |
4808 args = XCDR (args); | |
4809 | |
4810 argv[1] = IGNORE_MULTIPLE_VALUES (Feval (XCAR (args))); | |
4811 CHECK_NATNUM (argv[1]); | |
4812 upper = XINT (argv[1]); | |
4813 gcpro1.nvars = 2; | |
4814 | |
4815 /* The unintuitive order of things here is for the sake of the bytecode; | |
4816 the alternative would be to encode the number of arguments in the | |
4817 bytecode stream, which complicates things if we have more than 255 | |
4818 arguments. */ | |
4819 argv[2] = make_int (bind_multiple_value_limits (first, upper)); | |
4820 gcpro1.nvars = 3; | |
4821 args = XCDR (args); | |
4822 | |
4823 /* GCPROing in this function is not strictly necessary, this Feval is the | |
4824 only point that may cons up data that is not immediately discarded, and | |
4825 within it is the only point (in Fmultiple_value_list_internal and | |
4826 multiple_value_list) that we can garbage collect. But I'm conservative, | |
4827 and this function is called so rarely (only from interpreted code) that | |
4828 it doesn't matter for performance. */ | |
4829 argv[3] = Feval (XCAR (args)); | |
4830 gcpro1.nvars = 4; | |
4831 | |
4832 RETURN_UNGCPRO (multiple_value_list_internal (countof (argv), argv)); | |
4833 } | |
4834 | |
4835 DEFUN ("multiple-value-prog1", Fmultiple_value_prog1, 1, UNEVALLED, 0, /* | |
4836 Similar to `prog1', but return any multiple values from the first form. | |
4837 `prog1' itself will never return multiple values. | |
4838 | |
4839 arguments: (FIRST &rest BODY) | |
4840 */ | |
4841 (args)) | |
4842 { | |
4843 /* This function can GC */ | |
4844 Lisp_Object val; | |
4845 struct gcpro gcpro1; | |
4846 | |
4847 val = Feval (XCAR (args)); | |
4848 | |
4849 GCPRO1 (val); | |
4850 | |
4851 { | |
4852 LIST_LOOP_2 (form, XCDR (args)) | |
4853 Feval (form); | |
4854 } | |
4855 | |
4856 RETURN_UNGCPRO (val); | |
4857 } | |
4858 | |
4859 DEFUN ("values", Fvalues, 0, MANY, 0, /* | |
4860 Return all ARGS as multiple values. | |
4861 | |
4862 arguments: (&rest ARGS) | |
4863 */ | |
4864 (int nargs, Lisp_Object *args)) | |
4865 { | |
4866 Lisp_Object result = Qnil; | |
4867 int counting = 1; | |
4868 | |
4869 /* Pathological cases, no need to cons up an object: */ | |
4870 if (1 == nargs || 1 == multiple_value_current_limit) | |
4871 { | |
4872 return nargs ? args[0] : Qnil; | |
4873 } | |
4874 | |
4875 /* If nargs is zero, this code is correct and desirable. With | |
4876 #'multiple-value-call, we want zero-length multiple values in the | |
4877 argument list to be discarded entirely, and we can't do this if we | |
4878 transform them to nil. */ | |
4879 result = make_multiple_value (nargs ? args[0] : Qnil, nargs, | |
4880 first_desired_multiple_value, | |
4881 multiple_value_current_limit); | |
4882 | |
4883 for (; counting < nargs; ++counting) | |
4884 { | |
4885 if (counting >= first_desired_multiple_value && | |
4886 counting < multiple_value_current_limit) | |
4887 { | |
4888 multiple_value_aset (result, counting, args[counting]); | |
4889 } | |
4890 } | |
4891 | |
4892 return result; | |
4893 } | |
4894 | |
4895 DEFUN ("values-list", Fvalues_list, 1, 1, 0, /* | |
4896 Return all the elements of LIST as multiple values. | |
4897 */ | |
4898 (list)) | |
4899 { | |
4900 Lisp_Object result = Qnil; | |
4901 int counting = 1, listcount; | |
4902 | |
4903 GET_EXTERNAL_LIST_LENGTH (list, listcount); | |
4904 | |
4905 /* Pathological cases, no need to cons up an object: */ | |
4906 if (1 == listcount || 1 == multiple_value_current_limit) | |
4907 { | |
4908 return Fcar_safe (list); | |
4909 } | |
4910 | |
4911 result = make_multiple_value (Fcar_safe (list), listcount, | |
4912 first_desired_multiple_value, | |
4913 multiple_value_current_limit); | |
4914 | |
4915 list = Fcdr_safe (list); | |
4916 | |
4917 { | |
4918 EXTERNAL_LIST_LOOP_2 (elt, list) | |
4919 { | |
4920 if (counting >= first_desired_multiple_value && | |
4921 counting < multiple_value_current_limit) | |
4922 { | |
4923 multiple_value_aset (result, counting, elt); | |
4924 } | |
4925 ++counting; | |
4926 } | |
4927 } | |
4928 | |
4929 return result; | |
4930 } | |
4931 | |
4932 Lisp_Object | |
4933 values2 (Lisp_Object first, Lisp_Object second) | |
4934 { | |
4935 Lisp_Object argv[2]; | |
4936 | |
4937 argv[0] = first; | |
4938 argv[1] = second; | |
4939 | |
4940 return Fvalues (countof (argv), argv); | |
4296 } | 4941 } |
4297 | 4942 |
4298 | 4943 |
4299 /************************************************************************/ | 4944 /************************************************************************/ |
4300 /* Run hook variables in various ways. */ | 4945 /* Run hook variables in various ways. */ |
4966 else | 5611 else |
4967 p->backtrace = Qnil; | 5612 p->backtrace = Qnil; |
4968 p->error_conditions = error_conditions; | 5613 p->error_conditions = error_conditions; |
4969 p->data = data; | 5614 p->data = data; |
4970 | 5615 |
4971 Fthrow (p->catchtag, Qnil); | 5616 throw_or_bomb_out (p->catchtag, Qnil, 0, Qnil, Qnil); |
4972 RETURN_NOT_REACHED (Qnil); | 5617 RETURN_NOT_REACHED (Qnil); |
4973 } | 5618 } |
4974 | 5619 |
4975 static Lisp_Object | 5620 static Lisp_Object |
4976 call_trapping_problems_2 (Lisp_Object opaque) | 5621 call_trapping_problems_2 (Lisp_Object opaque) |
6553 | 7198 |
6554 void | 7199 void |
6555 syms_of_eval (void) | 7200 syms_of_eval (void) |
6556 { | 7201 { |
6557 INIT_LRECORD_IMPLEMENTATION (subr); | 7202 INIT_LRECORD_IMPLEMENTATION (subr); |
7203 INIT_LRECORD_IMPLEMENTATION (multiple_value); | |
6558 | 7204 |
6559 DEFSYMBOL (Qinhibit_quit); | 7205 DEFSYMBOL (Qinhibit_quit); |
6560 DEFSYMBOL (Qautoload); | 7206 DEFSYMBOL (Qautoload); |
6561 DEFSYMBOL (Qdebug_on_error); | 7207 DEFSYMBOL (Qdebug_on_error); |
6562 DEFSYMBOL (Qstack_trace_on_error); | 7208 DEFSYMBOL (Qstack_trace_on_error); |
6576 DEFSYMBOL (Qvalues); | 7222 DEFSYMBOL (Qvalues); |
6577 DEFSYMBOL (Qdisplay_warning); | 7223 DEFSYMBOL (Qdisplay_warning); |
6578 DEFSYMBOL (Qrun_hooks); | 7224 DEFSYMBOL (Qrun_hooks); |
6579 DEFSYMBOL (Qfinalize_list); | 7225 DEFSYMBOL (Qfinalize_list); |
6580 DEFSYMBOL (Qif); | 7226 DEFSYMBOL (Qif); |
7227 DEFSYMBOL (Qthrow); | |
7228 DEFSYMBOL (Qobsolete_throw); | |
6581 | 7229 |
6582 DEFSUBR (For); | 7230 DEFSUBR (For); |
6583 DEFSUBR (Fand); | 7231 DEFSUBR (Fand); |
6584 DEFSUBR (Fif); | 7232 DEFSUBR (Fif); |
6585 DEFSUBR_MACRO (Fwhen); | 7233 DEFSUBR_MACRO (Fwhen); |
6609 DEFSUBR (Fcommandp); | 7257 DEFSUBR (Fcommandp); |
6610 DEFSUBR (Fcommand_execute); | 7258 DEFSUBR (Fcommand_execute); |
6611 DEFSUBR (Fautoload); | 7259 DEFSUBR (Fautoload); |
6612 DEFSUBR (Feval); | 7260 DEFSUBR (Feval); |
6613 DEFSUBR (Fapply); | 7261 DEFSUBR (Fapply); |
7262 DEFSUBR (Fmultiple_value_call); | |
7263 DEFSUBR (Fmultiple_value_list_internal); | |
7264 DEFSUBR (Fmultiple_value_prog1); | |
7265 DEFSUBR (Fvalues); | |
7266 DEFSUBR (Fvalues_list); | |
6614 DEFSUBR (Ffuncall); | 7267 DEFSUBR (Ffuncall); |
6615 DEFSUBR (Ffunctionp); | 7268 DEFSUBR (Ffunctionp); |
6616 DEFSUBR (Ffunction_min_args); | 7269 DEFSUBR (Ffunction_min_args); |
6617 DEFSUBR (Ffunction_max_args); | 7270 DEFSUBR (Ffunction_max_args); |
6618 DEFSUBR (Frun_hooks); | 7271 DEFSUBR (Frun_hooks); |
6634 backtrace_list = 0; | 7287 backtrace_list = 0; |
6635 Vquit_flag = Qnil; | 7288 Vquit_flag = Qnil; |
6636 debug_on_next_call = 0; | 7289 debug_on_next_call = 0; |
6637 lisp_eval_depth = 0; | 7290 lisp_eval_depth = 0; |
6638 entering_debugger = 0; | 7291 entering_debugger = 0; |
7292 | |
7293 first_desired_multiple_value = 0; | |
7294 multiple_value_current_limit = 1; | |
6639 } | 7295 } |
6640 | 7296 |
6641 void | 7297 void |
6642 reinit_vars_of_eval (void) | 7298 reinit_vars_of_eval (void) |
6643 { | 7299 { |
6803 If due to `apply' or `funcall' entry, one arg, `lambda'. | 7459 If due to `apply' or `funcall' entry, one arg, `lambda'. |
6804 If due to `eval' entry, one arg, t. | 7460 If due to `eval' entry, one arg, t. |
6805 */ ); | 7461 */ ); |
6806 Vdebugger = Qnil; | 7462 Vdebugger = Qnil; |
6807 | 7463 |
7464 DEFVAR_CONST_INT ("multiple-values-limit", &Vmultiple_values_limit /* | |
7465 The exclusive upper bound on the number of multiple values. | |
7466 | |
7467 This applies to `values', `values-list', `multiple-value-bind' and related | |
7468 macros and special forms. | |
7469 */); | |
7470 Vmultiple_values_limit = EMACS_INT_MAX > INT_MAX ? INT_MAX : EMACS_INT_MAX; | |
7471 | |
6808 staticpro (&Vcatch_everything_tag); | 7472 staticpro (&Vcatch_everything_tag); |
6809 Vcatch_everything_tag = make_opaque (OPAQUE_CLEAR, 0); | 7473 Vcatch_everything_tag = make_opaque (OPAQUE_CLEAR, 0); |
6810 | 7474 |
6811 staticpro (&Vpending_warnings); | 7475 staticpro (&Vpending_warnings); |
6812 Vpending_warnings = Qnil; | 7476 Vpending_warnings = Qnil; |