From b9598260f96ddc652cd82ab64bbe922ccfc48a29 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sun, 13 Jun 2010 16:36:17 -0400 Subject: New branch for lexbind, losing all history. This initial patch is based on 2002-06-27T22:39:10Z!storm@cua.dk of the original lexbind branch. --- src/bytecode.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 122 insertions(+), 6 deletions(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index c53c5acdbb3..fec855c0b83 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -87,9 +87,11 @@ int byte_metering_on; Lisp_Object Qbytecode; +extern Lisp_Object Qand_optional, Qand_rest; /* Byte codes: */ +#define Bstack_ref 0 #define Bvarref 010 #define Bvarset 020 #define Bvarbind 030 @@ -229,6 +231,13 @@ Lisp_Object Qbytecode; #define BconcatN 0260 #define BinsertN 0261 +/* Bstack_ref is code 0. */ +#define Bstack_set 0262 +#define Bstack_set2 0263 +#define Bvec_ref 0264 +#define Bvec_set 0265 +#define BdiscardN 0266 + #define Bconstant 0300 #define CONSTANTLIM 0100 @@ -397,14 +406,41 @@ unmark_byte_stack () } while (0) -DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, +DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, MANY, 0, doc: /* Function used internally in byte-compiled code. The first argument, BYTESTR, is a string of byte code; the second, VECTOR, a vector of constants; the third, MAXDEPTH, the maximum stack depth used in this function. -If the third argument is incorrect, Emacs may crash. */) - (bytestr, vector, maxdepth) - Lisp_Object bytestr, vector, maxdepth; +If the third argument is incorrect, Emacs may crash. + +If ARGS-TEMPLATE is specified, it is an argument list specification, +according to which any remaining arguments are pushed on the stack +before executing BYTESTR. + +usage: (byte-code BYTESTR VECTOR MAXDEP &optional ARGS-TEMPLATE &rest ARGS) */) + (nargs, args) + int nargs; + Lisp_Object *args; +{ + Lisp_Object args_tmpl = nargs >= 4 ? args[3] : Qnil; + int pnargs = nargs >= 4 ? nargs - 4 : 0; + Lisp_Object *pargs = nargs >= 4 ? args + 4 : 0; + return exec_byte_code (args[0], args[1], args[2], args_tmpl, pnargs, pargs); +} + +/* Execute the byte-code in BYTESTR. VECTOR is the constant vector, and + MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect, + emacs may crash!). If ARGS_TEMPLATE is non-nil, it should be a lisp + argument list (including &rest, &optional, etc.), and ARGS, of size + NARGS, should be a vector of the actual arguments. The arguments in + ARGS are pushed on the stack according to ARGS_TEMPLATE before + executing BYTESTR. */ + +Lisp_Object +exec_byte_code (bytestr, vector, maxdepth, args_template, nargs, args) + Lisp_Object bytestr, vector, maxdepth, args_template; + int nargs; + Lisp_Object *args; { int count = SPECPDL_INDEX (); #ifdef BYTE_CODE_METER @@ -462,6 +498,37 @@ If the third argument is incorrect, Emacs may crash. */) stacke = stack.bottom - 1 + XFASTINT (maxdepth); #endif + if (! NILP (args_template)) + /* We should push some arguments on the stack. */ + { + Lisp_Object at; + int pushed = 0, optional = 0; + + for (at = args_template; CONSP (at); at = XCDR (at)) + if (EQ (XCAR (at), Qand_optional)) + optional = 1; + else if (EQ (XCAR (at), Qand_rest)) + { + PUSH (Flist (nargs, args)); + pushed = nargs; + at = Qnil; + break; + } + else if (pushed < nargs) + { + PUSH (*args++); + pushed++; + } + else if (optional) + PUSH (Qnil); + else + break; + + if (pushed != nargs || !NILP (at)) + Fsignal (Qwrong_number_of_arguments, + Fcons (args_template, Fcons (make_number (nargs), Qnil))); + } + while (1) { #ifdef BYTE_CODE_SAFE @@ -1641,8 +1708,57 @@ If the third argument is incorrect, Emacs may crash. */) break; #endif - case 0: - abort (); + /* Handy byte-codes for lexical binding. */ + case Bstack_ref: + case Bstack_ref+1: + case Bstack_ref+2: + case Bstack_ref+3: + case Bstack_ref+4: + case Bstack_ref+5: + PUSH (stack.bottom[op - Bstack_ref]); + break; + case Bstack_ref+6: + PUSH (stack.bottom[FETCH]); + break; + case Bstack_ref+7: + PUSH (stack.bottom[FETCH2]); + break; + case Bstack_set: + stack.bottom[FETCH] = POP; + break; + case Bstack_set2: + stack.bottom[FETCH2] = POP; + break; + case Bvec_ref: + case Bvec_set: + /* These byte-codes used mostly for variable references to + lexically bound variables that are in an environment vector + instead of on the byte-interpreter stack (generally those + variables which might be shared with a closure). */ + { + int index = FETCH; + Lisp_Object vec = POP; + + if (! VECTORP (vec)) + wrong_type_argument (Qvectorp, vec); + else if (index < 0 || index >= XVECTOR (vec)->size) + args_out_of_range (vec, index); + + if (op == Bvec_ref) + PUSH (XVECTOR (vec)->contents[index]); + else + XVECTOR (vec)->contents[index] = POP; + } + break; + case BdiscardN: + op = FETCH; + if (op & 0x80) + { + op &= 0x7F; + top[-op] = TOP; + } + DISCARD (op); + break; case 255: default: -- cgit v1.2.1 From 3c3ddb9833996729545bb4909bea359e5dbaa02e Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Mon, 14 Jun 2010 22:51:25 -0400 Subject: * lisp/emacs-lisp/bytecomp.el (byte-compile-initial-macro-environment): Don't macroexpand before evaluating in eval-and-compile, in case `body's macro expansion uses macros and functions defined in itself. * src/bytecode.c (exec_byte_code): * src/eval.c (Ffunctionp): Fix up int/Lisp_Object confusions. --- src/bytecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index fec855c0b83..192d397c45f 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1742,7 +1742,7 @@ exec_byte_code (bytestr, vector, maxdepth, args_template, nargs, args) if (! VECTORP (vec)) wrong_type_argument (Qvectorp, vec); else if (index < 0 || index >= XVECTOR (vec)->size) - args_out_of_range (vec, index); + args_out_of_range (vec, make_number (index)); if (op == Bvec_ref) PUSH (XVECTOR (vec)->contents[index]); -- cgit v1.2.1 From defb141157dfa37c33cdcbfa4b29c702a8fc9edf Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Mon, 13 Dec 2010 22:37:44 -0500 Subject: Try and be more careful about propagation of lexical environment. * src/eval.c (apply_lambda, funcall_lambda): Remove lexenv arg. (Feval): Always eval in the empty environment. (eval_sub): New function. Use it for all calls to Feval that should evaluate in the lexical environment of the caller. Pass `closure's as is to apply_lambda. (Ffuncall): Pass `closure's as is to funcall_lambda. (funcall_lambda): Extract lexenv for `closure's, when applicable. Also use lexical scoping for the &rest argument, if applicable. * src/lisp.h (eval_sub): Declare. * src/lread.c (readevalloop): Remove `evalfun' argument. * src/print.c (Fwith_output_to_temp_buffer): * src/data.c (Fsetq_default): Use eval_sub. * lisp/emacs-lisp/bytecomp.el (byte-compile-condition-case): Use push. --- src/bytecode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index d94b19b2d07..01fce0577b0 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -901,7 +901,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, case Bsave_window_excursion: BEFORE_POTENTIAL_GC (); - TOP = Fsave_window_excursion (TOP); + TOP = Fsave_window_excursion (TOP); /* FIXME: lexbind */ AFTER_POTENTIAL_GC (); break; @@ -915,13 +915,13 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, Lisp_Object v1; BEFORE_POTENTIAL_GC (); v1 = POP; - TOP = internal_catch (TOP, Feval, v1); + TOP = internal_catch (TOP, Feval, v1); /* FIXME: lexbind */ AFTER_POTENTIAL_GC (); break; } case Bunwind_protect: - record_unwind_protect (Fprogn, POP); + record_unwind_protect (Fprogn, POP); /* FIXME: lexbind */ break; case Bcondition_case: @@ -930,7 +930,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, handlers = POP; body = POP; BEFORE_POTENTIAL_GC (); - TOP = internal_lisp_condition_case (TOP, body, handlers); + TOP = internal_lisp_condition_case (TOP, body, handlers); /* FIXME: lexbind */ AFTER_POTENTIAL_GC (); break; } -- cgit v1.2.1 From a0ee6f2751acba71df443d4d795bb350eb6421dd Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Wed, 15 Dec 2010 12:46:59 -0500 Subject: Obey lexical-binding in interactive evaluation commands. * lisp/emacs-lisp/edebug.el (edebug-eval-defun, edebug-eval): * lisp/emacs-lisp/lisp-mode.el (eval-last-sexp-1, eval-defun-1): * lisp/ielm.el (ielm-eval-input): * lisp/simple.el (eval-expression): Use new eval arg to obey lexical-binding. * src/eval.c (Feval): Add `lexical' argument. Adjust callers. (Ffuncall, eval_sub): Avoid goto. --- src/bytecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index 01fce0577b0..eb12b9c4963 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -915,7 +915,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, Lisp_Object v1; BEFORE_POTENTIAL_GC (); v1 = POP; - TOP = internal_catch (TOP, Feval, v1); /* FIXME: lexbind */ + TOP = internal_catch (TOP, eval_sub, v1); /* FIXME: lexbind */ AFTER_POTENTIAL_GC (); break; } -- cgit v1.2.1 From ce5b520a3758e22c6516e0d864d8c1a3512bf457 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sat, 12 Feb 2011 00:53:30 -0500 Subject: * lisp/emacs-lisp/byte-lexbind.el: Delete. * lisp/emacs-lisp/bytecomp.el (byte-compile-current-heap-environment) (byte-compile-current-num-closures): Remove vars. (byte-vec-ref, byte-vec-set): Remove byte codes. (byte-compile-arglist-vars, byte-compile-make-lambda-lexenv): Move from byte-lexbind.el. (byte-compile-lambda): Never build a closure. (byte-compile-closure-code-p, byte-compile-make-closure): Remove. (byte-compile-closure): Simplify. (byte-compile-top-level): Don't mess with heap environments. (byte-compile-dynamic-variable-bind): Always maintain byte-compile-bound-variables. (byte-compile-variable-ref, byte-compile-variable-set): Always just use the stack for lexical vars. (byte-compile-push-binding-init): Simplify. (byte-compile-not-lexical-var-p): New function, moved from cconv.el. (byte-compile-bind, byte-compile-unbind): New functions, moved and simplified from byte-lexbind.el. (byte-compile-let, byte-compile-let*): Simplify. (byte-compile-condition-case): Don't add :fun-body to the bound vars. (byte-compile-defmacro): Simplify. * lisp/emacs-lisp/byte-opt.el (byte-compile-side-effect-free-ops) (byte-optimize-lapcode): Remove byte-vec-ref and byte-vec-set. * lisp/emacs-lisp/cconv.el (cconv-not-lexical-var-p): Remove. (cconv-freevars, cconv-analyse-function, cconv-analyse-form): Use byte-compile-not-lexical-var-p instead. * src/bytecode.c (Bvec_ref, Bvec_set): Remove. (exec_byte_code): Don't handle them. * lisp/help-fns.el (describe-function-1): Fix paren typo. --- src/bytecode.c | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index 96d2aa273f2..9bf6ae45ce9 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -231,8 +231,6 @@ extern Lisp_Object Qand_optional, Qand_rest; /* Bstack_ref is code 0. */ #define Bstack_set 0262 #define Bstack_set2 0263 -#define Bvec_ref 0264 -#define Bvec_set 0265 #define BdiscardN 0266 #define Bconstant 0300 @@ -1722,27 +1720,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, case Bstack_set2: stack.bottom[FETCH2] = POP; break; - case Bvec_ref: - case Bvec_set: - /* These byte-codes used mostly for variable references to - lexically bound variables that are in an environment vector - instead of on the byte-interpreter stack (generally those - variables which might be shared with a closure). */ - { - int index = FETCH; - Lisp_Object vec = POP; - - if (! VECTORP (vec)) - wrong_type_argument (Qvectorp, vec); - else if (index < 0 || index >= XVECTOR (vec)->size) - args_out_of_range (vec, make_number (index)); - - if (op == Bvec_ref) - PUSH (XVECTOR (vec)->contents[index]); - else - XVECTOR (vec)->contents[index] = POP; - } - break; case BdiscardN: op = FETCH; if (op & 0x80) -- cgit v1.2.1 From b38b1ec071ee9752da53f2485902165fe728e8fa Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Thu, 17 Feb 2011 16:19:13 -0500 Subject: Various compiler bug-fixes. MPC seems to run correctly now. * lisp/files.el (lexical-binding): Add a safe-local-variable property. * lisp/emacs-lisp/byte-opt.el (byte-inline-lapcode): Check how many elements are added to the stack. (byte-compile-splice-in-already-compiled-code): Don't touch lexical nor byte-compile-depth now that byte-inline-lapcode does it for us. (byte-compile-inline-expand): Don't inline dynbind byte code into lexbind code, since it has to be done differently. * lisp/emacs-lisp/bytecomp.el (byte-compile-arglist-warn): Correctly extract arglist from `closure's. (byte-compile-cl-warn): Compiler-macros are run earlier now. (byte-compile-top-level): Bind byte-compile-lexical-environment to nil, except for lambdas. (byte-compile-form): Don't run the compiler-macro expander here. (byte-compile-let): Merge with byte-compile-let*. Don't preserve-body-value if the body's value was discarded. * lisp/emacs-lisp/cconv.el (cconv--set-diff, cconv--set-diff-map) (cconv--map-diff, cconv--map-diff-elem, cconv--map-diff-set): New funs. (cconv--env-var): New constant. (cconv-closure-convert-rec): Use it and use them. Fix a typo that ended up forgetting to remove entries from lmenvs in `let'. For `lambda' use the outer `fvrs' when building the closure and don't forget to remove `vars' from the `emvrs' and `lmenvs' of the body. * lisp/emacs-lisp/cl-macs.el (cl-byte-compile-block): Disable optimization in lexbind, because it needs a different implementation. * src/bytecode.c (exec_byte_code): Fix handling of &rest. * src/eval.c (Vinternal_interpreter_environment): Remove. (syms_of_eval): Do declare Vinternal_interpreter_environment as a global lisp var, but unintern it to hide it. (Fcommandp): * src/data.c (Finteractive_form): Understand `closure's. --- src/bytecode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index 9bf6ae45ce9..1ad01aaf8f7 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -500,7 +500,9 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, optional = 1; else if (EQ (XCAR (at), Qand_rest)) { - PUSH (Flist (nargs, args)); + PUSH (pushed < nargs + ? Flist (nargs - pushed, args) + : Qnil); pushed = nargs; at = Qnil; break; -- cgit v1.2.1 From e0f57e65692ed73a86926f737388b60faec92767 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sat, 19 Feb 2011 00:10:33 -0500 Subject: * lisp/subr.el (save-window-excursion): New macro, moved from C. * lisp/emacs-lisp/lisp-mode.el (save-window-excursion): Don't touch. * lisp/emacs-lisp/cconv.el (cconv-closure-convert-rec, cconv-analyse-form): Don't handle save-window-excursion any more. * lisp/emacs-lisp/bytecomp.el (interactive-p, save-window-excursion): Don't use the byte-code any more. (byte-compile-form): Check macro expansion was done. (byte-compile-save-window-excursion): Remove. * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Ignore save-window-excursion. Don't macroepand any more. * src/window.c (Fsave_window_excursion): Remove. Moved to Lisp. (syms_of_window): Don't defsubr it. * src/window.h (Fsave_window_excursion): Don't declare it. * src/bytecode.c (exec_byte_code): Inline Fsave_window_excursion. --- src/bytecode.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index 1ad01aaf8f7..ad2f7d18ade 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -138,7 +138,7 @@ extern Lisp_Object Qand_optional, Qand_rest; #define Bpoint 0140 /* Was Bmark in v17. */ -#define Bsave_current_buffer 0141 +#define Bsave_current_buffer 0141 /* Obsolete. */ #define Bgoto_char 0142 #define Binsert 0143 #define Bpoint_max 0144 @@ -158,7 +158,7 @@ extern Lisp_Object Qand_optional, Qand_rest; #define Bsave_current_buffer_1 0162 /* Replacing Bsave_current_buffer. */ #define Bread_char 0162 /* No longer generated as of v19 */ #define Bset_mark 0163 /* this loser is no longer generated as of v18 */ -#define Binteractive_p 0164 /* Needed since interactive-p takes unevalled args */ +#define Binteractive_p 0164 /* Obsolete. */ #define Bforward_char 0165 #define Bforward_word 0166 @@ -183,7 +183,7 @@ extern Lisp_Object Qand_optional, Qand_rest; #define Bdup 0211 #define Bsave_excursion 0212 -#define Bsave_window_excursion 0213 +#define Bsave_window_excursion 0213 /* Obsolete. */ #define Bsave_restriction 0214 #define Bcatch 0215 @@ -192,7 +192,7 @@ extern Lisp_Object Qand_optional, Qand_rest; #define Btemp_output_buffer_setup 0220 #define Btemp_output_buffer_show 0221 -#define Bunbind_all 0222 +#define Bunbind_all 0222 /* Obsolete. */ #define Bset_marker 0223 #define Bmatch_beginning 0224 @@ -763,7 +763,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, AFTER_POTENTIAL_GC (); break; - case Bunbind_all: + case Bunbind_all: /* Obsolete. */ /* To unbind back to the beginning of this frame. Not used yet, but will be needed for tail-recursion elimination. */ BEFORE_POTENTIAL_GC (); @@ -891,16 +891,24 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, save_excursion_save ()); break; - case Bsave_current_buffer: + case Bsave_current_buffer: /* Obsolete. */ case Bsave_current_buffer_1: record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ()); break; - case Bsave_window_excursion: - BEFORE_POTENTIAL_GC (); - TOP = Fsave_window_excursion (TOP); /* FIXME: lexbind */ - AFTER_POTENTIAL_GC (); - break; + case Bsave_window_excursion: /* Obsolete. */ + { + register Lisp_Object val; + register int count = SPECPDL_INDEX (); + + record_unwind_protect (Fset_window_configuration, + Fcurrent_window_configuration (Qnil)); + BEFORE_POTENTIAL_GC (); + TOP = Fprogn (TOP); + unbind_to (count, TOP); + AFTER_POTENTIAL_GC (); + break; + } case Bsave_restriction: record_unwind_protect (save_restriction_restore, @@ -1412,7 +1420,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, AFTER_POTENTIAL_GC (); break; - case Binteractive_p: + case Binteractive_p: /* Obsolete. */ PUSH (Finteractive_p ()); break; -- cgit v1.2.1 From 3e21b6a72b87787e2327513a44623b250054f77d Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Mon, 21 Feb 2011 15:12:44 -0500 Subject: Use offsets relative to top rather than bottom for stack refs * lisp/emacs-lisp/byte-opt.el (byte-compile-side-effect-and-error-free-ops): Remove interactive-p. (byte-optimize-lapcode): Update optimizations now that stack-refs are relative to the top rather than to the bottom. * lisp/emacs-lisp/bytecomp.el (byte-compile-lapcode): Turn stack-ref-0 into dup. (byte-compile-form): Don't indirect-function since it can signal errors. (byte-compile-stack-ref, byte-compile-stack-set): Adjust to stack-refs being relative to top rather than to bottom in the byte-code. (with-output-to-temp-buffer): Remove. (byte-compile-with-output-to-temp-buffer): Remove. * lisp/emacs-lisp/cconv.el: Use lexical-binding. (cconv--lookup-let): Rename from cconv-lookup-let. (cconv-closure-convert-rec): Fix handling of captured+mutated arguments in defun/defmacro. * lisp/emacs-lisp/eieio-comp.el (eieio-byte-compile-file-form-defmethod): Rename from byte-compile-file-form-defmethod. Don't byte-compile-lambda. (eieio-byte-compile-defmethod-param-convert): Rename from byte-compile-defmethod-param-convert. * lisp/emacs-lisp/eieio.el (eieio-defgeneric-form-primary-only-one): Call byte-compile rather than byte-compile-lambda. * src/alloc.c (Fgarbage_collect): Don't mark the byte-stack redundantly. * src/bytecode.c (exec_byte_code): Change stack_ref and stack_set to use offsets relative to top rather than to bottom. * lisp/subr.el (with-output-to-temp-buffer): New macro. * lisp/simple.el (count-words-region): Don't use interactive-p. --- src/bytecode.c | 52 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 19 deletions(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index ad2f7d18ade..b2e9e3c5b56 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -51,7 +51,7 @@ by Hallvard: * * define BYTE_CODE_METER to enable generation of a byte-op usage histogram. */ -/* #define BYTE_CODE_SAFE */ +#define BYTE_CODE_SAFE /* #define BYTE_CODE_METER */ @@ -88,7 +88,7 @@ extern Lisp_Object Qand_optional, Qand_rest; /* Byte codes: */ -#define Bstack_ref 0 +#define Bstack_ref 0 /* Actually, Bstack_ref+0 is not implemented: use dup. */ #define Bvarref 010 #define Bvarset 020 #define Bvarbind 030 @@ -189,8 +189,8 @@ extern Lisp_Object Qand_optional, Qand_rest; #define Bunwind_protect 0216 #define Bcondition_case 0217 -#define Btemp_output_buffer_setup 0220 -#define Btemp_output_buffer_show 0221 +#define Btemp_output_buffer_setup 0220 /* Obsolete. */ +#define Btemp_output_buffer_show 0221 /* Obsolete. */ #define Bunbind_all 0222 /* Obsolete. */ @@ -898,9 +898,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, case Bsave_window_excursion: /* Obsolete. */ { - register Lisp_Object val; register int count = SPECPDL_INDEX (); - record_unwind_protect (Fset_window_configuration, Fcurrent_window_configuration (Qnil)); BEFORE_POTENTIAL_GC (); @@ -940,7 +938,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, break; } - case Btemp_output_buffer_setup: + case Btemp_output_buffer_setup: /* Obsolete. */ BEFORE_POTENTIAL_GC (); CHECK_STRING (TOP); temp_output_buffer_setup (SSDATA (TOP)); @@ -948,7 +946,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, TOP = Vstandard_output; break; - case Btemp_output_buffer_show: + case Btemp_output_buffer_show: /* Obsolete. */ { Lisp_Object v1; BEFORE_POTENTIAL_GC (); @@ -1710,26 +1708,42 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, #endif /* Handy byte-codes for lexical binding. */ - case Bstack_ref: + /* case Bstack_ref: */ /* Use `dup' instead. */ case Bstack_ref+1: case Bstack_ref+2: case Bstack_ref+3: case Bstack_ref+4: case Bstack_ref+5: - PUSH (stack.bottom[op - Bstack_ref]); - break; + { + Lisp_Object *ptr = top - (op - Bstack_ref); + PUSH (*ptr); + break; + } case Bstack_ref+6: - PUSH (stack.bottom[FETCH]); - break; + { + Lisp_Object *ptr = top - (FETCH); + PUSH (*ptr); + break; + } case Bstack_ref+7: - PUSH (stack.bottom[FETCH2]); - break; + { + Lisp_Object *ptr = top - (FETCH2); + PUSH (*ptr); + break; + } + /* stack-set-0 = discard; stack-set-1 = discard-1-preserve-tos. */ case Bstack_set: - stack.bottom[FETCH] = POP; - break; + { + Lisp_Object *ptr = top - (FETCH); + *ptr = POP; + break; + } case Bstack_set2: - stack.bottom[FETCH2] = POP; - break; + { + Lisp_Object *ptr = top - (FETCH2); + *ptr = POP; + break; + } case BdiscardN: op = FETCH; if (op & 0x80) -- cgit v1.2.1 From 876c194cbac17a6220dbf406b0a602325978011c Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Thu, 24 Feb 2011 22:27:45 -0500 Subject: Get rid of funvec. * lisp/emacs-lisp/bytecomp.el (byte-compile-lapcode): Handle new form of `byte-constant'. (byte-compile-close-variables, displaying-byte-compile-warnings): Add edebug spec. (byte-compile-toplevel-file-form): New fun, split out of byte-compile-file-form. (byte-compile-from-buffer): Use it to avoid applying cconv multiple times. (byte-compile): Only strip `function' if it's present. (byte-compile-lambda): Add `reserved-csts' argument. Use new lexenv arg of byte-compile-top-level. (byte-compile-reserved-constants): New var. (byte-compile-constants-vector): Obey it. (byte-compile-constants-vector): Handle new `byte-constant' form. (byte-compile-top-level): Add args `lexenv' and `reserved-csts'. (byte-compile-form): Don't check callargs here. (byte-compile-normal-call): Do it here instead. (byte-compile-push-unknown-constant) (byte-compile-resolve-unknown-constant): Remove, unused. (byte-compile-make-closure): Use `make-byte-code' rather than `curry', putting the environment into the "constant" pool. (byte-compile-get-closed-var): Use special byte-constant. * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Handle new intermediate special form `internal-make-vector'. (byte-optimize-lapcode): Handle new form of `byte-constant'. * lisp/help-fns.el (describe-function-1): Don't handle funvecs. * lisp/emacs-lisp/macroexp.el (macroexpand-all-1): Only convert quote to function if the content is a lambda expression, not if it's a closure. * emacs-lisp/eieio-come.el: Remove. * lisp/emacs-lisp/eieio.el: Don't require eieio-comp. (defmethod): Do a bit more work to find the body and wrap it into a function before passing it to eieio-defmethod. (eieio-defmethod): New arg `code' for it. * lisp/emacs-lisp/debug.el (debugger-setup-buffer): Don't hide things in debugger backtrace. * lisp/emacs-lisp/cl-extra.el (cl-macroexpand-all): Use backquotes, and be more careful when quoting a function value. * lisp/emacs-lisp/cconv.el (cconv-freevars): Accept defvar/defconst. (cconv-closure-convert-rec): Catch stray `internal-make-closure'. * lisp/Makefile.in (COMPILE_FIRST): Compile pcase and cconv early. * src/eval.c (Qcurry): Remove. (funcall_funvec): Remove. (funcall_lambda): Move new byte-code handling to reduce impact. Treat all args as lexical in the case of lexbind. (Fcurry): Remove. * src/data.c (Qfunction_vector): Remove. (Ffunvecp): Remove. * src/lread.c (read1): Revert to calling make_byte_code here. (read_vector): Don't call make_byte_code any more. * src/lisp.h (enum pvec_type): Rename back to PVEC_COMPILED. (XSETCOMPILED): Rename back from XSETFUNVEC. (FUNVEC_SIZE): Remove. (FUNVEC_COMPILED_TAG_P, FUNVEC_COMPILED_P): Remove. (COMPILEDP): Rename back from FUNVECP. * src/fns.c (Felt): Remove unexplained FUNVEC check. * src/doc.c (Fdocumentation): Don't handle funvec. * src/alloc.c (make_funvec, Ffunvec): Remove. * doc/lispref/vol2.texi (Top): * doc/lispref/vol1.texi (Top): * doc/lispref/objects.texi (Programming Types, Funvec Type, Type Predicates): * doc/lispref/functions.texi (Functions, What Is a Function, FunctionCurrying): * doc/lispref/elisp.texi (Top): Remove mentions of funvec and curry. --- src/bytecode.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index 639c543dbf9..464bc3d12de 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -51,7 +51,7 @@ by Hallvard: * * define BYTE_CODE_METER to enable generation of a byte-op usage histogram. */ -/* #define BYTE_CODE_SAFE 1 */ +/* #define BYTE_CODE_SAFE */ /* #define BYTE_CODE_METER */ @@ -1720,8 +1720,13 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, break; #endif + case 0: + /* Actually this is Bstack_ref with offset 0, but we use Bdup + for that instead. */ + /* case Bstack_ref: */ + abort (); + /* Handy byte-codes for lexical binding. */ - /* case Bstack_ref: */ /* Use `dup' instead. */ case Bstack_ref+1: case Bstack_ref+2: case Bstack_ref+3: -- cgit v1.2.1 From a9de04fa62f123413d82b7b7b1e7a77705eb82dd Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sat, 26 Feb 2011 10:19:08 -0500 Subject: Compute freevars in cconv-analyse. * lisp/emacs-lisp/cconv.el: Compute freevars in cconv-analyse. (cconv-mutated, cconv-captured): Remove. (cconv-captured+mutated, cconv-lambda-candidates): Don't give them a global value. (cconv-freevars-alist): New var. (cconv-freevars): Remove. (cconv--lookup-let): Remove. (cconv-closure-convert-function): Extract from cconv-closure-convert-rec. (cconv-closure-convert-rec): Adjust to above changes. (fboundp): New function. (cconv-analyse-function, form): Rewrite. * lisp/emacs-lisp/bytecomp.el (byte-compile-initial-macro-environment): Handle declare-function here. (byte-compile-obsolete): Remove. (byte-compile-arglist-warn): Check late defsubst here. (byte-compile-file-form): Simplify. (byte-compile-file-form-defsubst): Remove. (byte-compile-macroexpand-declare-function): Rename from byte-compile-declare-function, turn it into a macro-expander. (byte-compile-normal-call): Check obsolescence. (byte-compile-quote-form): Remove. (byte-compile-defmacro): Revert to trunk's definition which seems to work just as well and handles `declare'. * lisp/emacs-lisp/byte-run.el (make-obsolete): Don't modify byte-compile. * lisp/Makefile.in (BIG_STACK_DEPTH): Increase to 1200. (compile-onefile): Pass $(BIG_STACK_OPTS) before "-l bytecomp". * lisp/emacs-lisp/macroexp.el: Use lexbind. (macroexpand-all-1): Check macro obsolescence. * lisp/vc/diff-mode.el: Use lexbind. * lisp/follow.el (follow-calc-win-end): Simplify. --- src/bytecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index 464bc3d12de..9693a5a9196 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -51,7 +51,7 @@ by Hallvard: * * define BYTE_CODE_METER to enable generation of a byte-op usage histogram. */ -/* #define BYTE_CODE_SAFE */ +#define BYTE_CODE_SAFE 1 /* #define BYTE_CODE_METER */ -- cgit v1.2.1 From e2abe5a13dffb08d6371b6a611bc39c3a9ac2bc6 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sat, 5 Mar 2011 23:48:17 -0500 Subject: Fix pcase memoizing; change lexbound byte-code marker. * src/bytecode.c (exec_byte_code): Remove old lexical binding slot handling and replace it with the a integer args-desc handling. * eval.c (funcall_lambda): Adjust arglist test accordingly. * lisp/emacs-lisp/bytecomp.el (byte-compile-arglist-signature): Handle integer arglist descriptor. (byte-compile-make-args-desc): Make integer arglist descriptor. (byte-compile-lambda): Use integer arglist descriptor to mark lexical byte-coded functions instead of an extra slot. * lisp/help-fns.el (help-add-fundoc-usage): Don't add a dummy doc. (help-split-fundoc): Return a nil doc if there was no actual doc. (help-function-arglist): Generate an arglist from an integer arg-desc. * lisp/emacs-lisp/pcase.el (pcase--memoize): Rename from pcase-memoize; Make only the key weak. (pcase): Change the key used in the memoization table, so it does not always get GC'd away. * lisp/emacs-lisp/macroexp.el (macroexpand-all-1): Slight change to the pcase pattern to generate slightly better code. --- src/bytecode.c | 71 ++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 29 deletions(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index 9693a5a9196..dbab02886e2 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -502,37 +502,50 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, stacke = stack.bottom - 1 + XFASTINT (maxdepth); #endif - if (! NILP (args_template)) - /* We should push some arguments on the stack. */ + if (INTEGERP (args_template)) { - Lisp_Object at; - int pushed = 0, optional = 0; - - for (at = args_template; CONSP (at); at = XCDR (at)) - if (EQ (XCAR (at), Qand_optional)) - optional = 1; - else if (EQ (XCAR (at), Qand_rest)) - { - PUSH (pushed < nargs - ? Flist (nargs - pushed, args) - : Qnil); - pushed = nargs; - at = Qnil; - break; - } - else if (pushed < nargs) - { - PUSH (*args++); - pushed++; - } - else if (optional) - PUSH (Qnil); - else - break; - - if (pushed != nargs || !NILP (at)) + int at = XINT (args_template); + int rest = at & 128; + int mandatory = at & 127; + int nonrest = at >> 8; + eassert (mandatory <= nonrest); + if (nargs <= nonrest) + { + int i; + for (i = 0 ; i < nargs; i++, args++) + PUSH (*args); + if (nargs < mandatory) + /* Too few arguments. */ + Fsignal (Qwrong_number_of_arguments, + Fcons (Fcons (make_number (mandatory), + rest ? Qand_rest : make_number (nonrest)), + Fcons (make_number (nargs), Qnil))); + else + { + for (; i < nonrest; i++) + PUSH (Qnil); + if (rest) + PUSH (Qnil); + } + } + else if (rest) + { + int i; + for (i = 0 ; i < nonrest; i++, args++) + PUSH (*args); + PUSH (Flist (nargs - nonrest, args)); + } + else + /* Too many arguments. */ Fsignal (Qwrong_number_of_arguments, - Fcons (args_template, Fcons (make_number (nargs), Qnil))); + Fcons (Fcons (make_number (mandatory), + make_number (nonrest)), + Fcons (make_number (nargs), Qnil))); + } + else if (! NILP (args_template)) + /* We should push some arguments on the stack. */ + { + error ("Unknown args template!"); } while (1) -- cgit v1.2.1 From ca1055060d5793e368c1a165c412944d6800c3a6 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Wed, 16 Mar 2011 16:08:39 -0400 Subject: Remove bytecomp- prefix, plus misc changes. * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Make it work to inline lexbind interpreted functions into lexbind code. (bytedecomp-bytes): Not a dynamic var any more. (disassemble-offset): Get the bytes via an argument instead. (byte-decompile-bytecode-1): Use push. * lisp/emacs-lisp/bytecomp.el: Remove the bytecomp- prefix now that we use lexical-binding. (byte-compile-outbuffer): Rename from bytecomp-outbuffer. * lisp/emacs-lisp/cl-macs.el (load-time-value): * lisp/emacs-lisp/cl.el (cl-compiling-file): Adjust to new name. * lisp/emacs-lisp/pcase.el (pcase-mutually-exclusive-predicates): Add byte-code-function-p. (pcase--u1): Remove left-over code from early development. Fix case of variable shadowing in guards and predicates. (pcase--u1): Add a new `let' pattern. * src/image.c (parse_image_spec): Use Ffunctionp. * src/lisp.h: Declare Ffunctionp. --- src/bytecode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index b19f9687cdc..ba3c012bd1a 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -939,27 +939,27 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, save_restriction_save ()); break; - case Bcatch: + case Bcatch: /* FIXME: ill-suited for lexbind */ { Lisp_Object v1; BEFORE_POTENTIAL_GC (); v1 = POP; - TOP = internal_catch (TOP, eval_sub, v1); /* FIXME: lexbind */ + TOP = internal_catch (TOP, eval_sub, v1); AFTER_POTENTIAL_GC (); break; } - case Bunwind_protect: - record_unwind_protect (Fprogn, POP); /* FIXME: lexbind */ + case Bunwind_protect: /* FIXME: avoid closure for lexbind */ + record_unwind_protect (Fprogn, POP); break; - case Bcondition_case: + case Bcondition_case: /* FIXME: ill-suited for lexbind */ { Lisp_Object handlers, body; handlers = POP; body = POP; BEFORE_POTENTIAL_GC (); - TOP = internal_lisp_condition_case (TOP, body, handlers); /* FIXME: lexbind */ + TOP = internal_lisp_condition_case (TOP, body, handlers); AFTER_POTENTIAL_GC (); break; } -- cgit v1.2.1 From 7200d79c65c65686495dd95e9f6dd436cf6db55e Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Fri, 1 Apr 2011 11:16:50 -0400 Subject: Miscellanous cleanups in preparation for the merge. * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Remove debug statement. * lisp/emacs-lisp/bytecomp.el (byte-compile-single-version) (byte-compile-version-cond, byte-compile-delay-out) (byte-compile-delayed-out): Remove, unused. * src/bytecode.c (Fbyte_code): Revert to old calling convention. * src/lisp.h (COMPILED_PUSH_ARGS): Remove, unused. --- src/bytecode.c | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index 01ae8055ebf..5d94cb0fb39 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -51,7 +51,7 @@ by Hallvard: * * define BYTE_CODE_METER to enable generation of a byte-op usage histogram. */ -#define BYTE_CODE_SAFE 1 +/* #define BYTE_CODE_SAFE */ /* #define BYTE_CODE_METER */ @@ -160,7 +160,7 @@ extern Lisp_Object Qand_optional, Qand_rest; #ifdef BYTE_CODE_SAFE #define Bset_mark 0163 /* this loser is no longer generated as of v18 */ #endif -#define Binteractive_p 0164 /* Obsolete. */ +#define Binteractive_p 0164 /* Obsolete since Emacs-24.1. */ #define Bforward_char 0165 #define Bforward_word 0166 @@ -185,16 +185,16 @@ extern Lisp_Object Qand_optional, Qand_rest; #define Bdup 0211 #define Bsave_excursion 0212 -#define Bsave_window_excursion 0213 /* Obsolete. */ +#define Bsave_window_excursion 0213 /* Obsolete since Emacs-24.1. */ #define Bsave_restriction 0214 #define Bcatch 0215 #define Bunwind_protect 0216 #define Bcondition_case 0217 -#define Btemp_output_buffer_setup 0220 /* Obsolete. */ -#define Btemp_output_buffer_show 0221 /* Obsolete. */ +#define Btemp_output_buffer_setup 0220 /* Obsolete since Emacs-24.1. */ +#define Btemp_output_buffer_show 0221 /* Obsolete since Emacs-24.1. */ -#define Bunbind_all 0222 /* Obsolete. */ +#define Bunbind_all 0222 /* Obsolete. Never used. */ #define Bset_marker 0223 #define Bmatch_beginning 0224 @@ -413,24 +413,15 @@ unmark_byte_stack (void) } while (0) -DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, MANY, 0, +DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, doc: /* Function used internally in byte-compiled code. The first argument, BYTESTR, is a string of byte code; the second, VECTOR, a vector of constants; the third, MAXDEPTH, the maximum stack depth used in this function. -If the third argument is incorrect, Emacs may crash. - -If ARGS-TEMPLATE is specified, it is an argument list specification, -according to which any remaining arguments are pushed on the stack -before executing BYTESTR. - -usage: (byte-code BYTESTR VECTOR MAXDEP &optional ARGS-TEMPLATE &rest ARGS) */) - (size_t nargs, Lisp_Object *args) +If the third argument is incorrect, Emacs may crash. */) + (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth) { - Lisp_Object args_tmpl = nargs >= 4 ? args[3] : Qnil; - int pnargs = nargs >= 4 ? nargs - 4 : 0; - Lisp_Object *pargs = nargs >= 4 ? args + 4 : 0; - return exec_byte_code (args[0], args[1], args[2], args_tmpl, pnargs, pargs); + return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL); } /* Execute the byte-code in BYTESTR. VECTOR is the constant vector, and @@ -810,7 +801,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, AFTER_POTENTIAL_GC (); break; - case Bunbind_all: /* Obsolete. */ + case Bunbind_all: /* Obsolete. Never used. */ /* To unbind back to the beginning of this frame. Not used yet, but will be needed for tail-recursion elimination. */ BEFORE_POTENTIAL_GC (); @@ -938,12 +929,12 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, save_excursion_save ()); break; - case Bsave_current_buffer: /* Obsolete. */ + case Bsave_current_buffer: /* Obsolete since ??. */ case Bsave_current_buffer_1: record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ()); break; - case Bsave_window_excursion: /* Obsolete. */ + case Bsave_window_excursion: /* Obsolete since 24.1. */ { register int count = SPECPDL_INDEX (); record_unwind_protect (Fset_window_configuration, @@ -985,7 +976,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, break; } - case Btemp_output_buffer_setup: /* Obsolete. */ + case Btemp_output_buffer_setup: /* Obsolete since 24.1. */ BEFORE_POTENTIAL_GC (); CHECK_STRING (TOP); temp_output_buffer_setup (SSDATA (TOP)); @@ -993,7 +984,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, TOP = Vstandard_output; break; - case Btemp_output_buffer_show: /* Obsolete. */ + case Btemp_output_buffer_show: /* Obsolete since 24.1. */ { Lisp_Object v1; BEFORE_POTENTIAL_GC (); @@ -1465,7 +1456,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, AFTER_POTENTIAL_GC (); break; - case Binteractive_p: /* Obsolete. */ + case Binteractive_p: /* Obsolete since 24.1. */ PUSH (Finteractive_p ()); break; -- cgit v1.2.1