Obey lexical-binding in interactive evaluation commands.
[bpt/emacs.git] / src / bytecode.c
index e2e3a79..eb12b9c 100644 (file)
@@ -1,13 +1,13 @@
 /* Execution of byte code produced by bytecomp.el.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+                 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,10 +15,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
+/*
 hacked on by jwz@lucid.com 17-jun-91
   o  added a compile-time switch to turn on simple sanity checking;
   o  put back the obsolete byte-codes for error-detection;
@@ -35,6 +34,7 @@ by Hallvard:
  */
 
 #include <config.h>
+#include <setjmp.h>
 #include "lisp.h"
 #include "buffer.h"
 #include "character.h"
@@ -87,9 +87,11 @@ int byte_metering_on;
 \f
 
 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
 
@@ -272,7 +281,7 @@ struct byte_stack *byte_stack_list;
 /* Mark objects on byte_stack_list.  Called during GC.  */
 
 void
-mark_byte_stack ()
+mark_byte_stack (void)
 {
   struct byte_stack *stack;
   Lisp_Object *obj;
@@ -301,7 +310,7 @@ mark_byte_stack ()
    counters.  Called when GC has completed.  */
 
 void
-unmark_byte_stack ()
+unmark_byte_stack (void)
 {
   struct byte_stack *stack;
 
@@ -393,17 +402,41 @@ unmark_byte_stack ()
        Fsignal (Qquit, Qnil);                          \
        AFTER_POTENTIAL_GC ();                          \
       }                                                        \
+    ELSE_PENDING_SIGNALS                               \
   } 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) */)
+     (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 (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
+               Lisp_Object args_template, int nargs, Lisp_Object *args)
 {
   int count = SPECPDL_INDEX ();
 #ifdef BYTE_CODE_METER
@@ -422,7 +455,7 @@ If the third argument is incorrect, Emacs may crash.  */)
   Lisp_Object *top;
   Lisp_Object result;
 
-#ifdef CHECK_FRAME_FONT
+#if 0 /* CHECK_FRAME_FONT */
  {
    struct frame *f = SELECTED_FRAME ();
    if (FRAME_X_P (f)
@@ -461,6 +494,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
@@ -504,8 +568,9 @@ If the third argument is incorrect, Emacs may crash.  */)
            v1 = vectorp[op];
            if (SYMBOLP (v1))
              {
-               v2 = SYMBOL_VALUE (v1);
-               if (MISCP (v2) || EQ (v2, Qunbound))
+               if (XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL
+                   || (v2 = SYMBOL_VAL (XSYMBOL (v1)),
+                       EQ (v2, Qunbound)))
                  {
                    BEFORE_POTENTIAL_GC ();
                    v2 = Fsymbol_value (v1);
@@ -596,14 +661,13 @@ If the third argument is incorrect, Emacs may crash.  */)
            /* Inline the most common case.  */
            if (SYMBOLP (sym)
                && !EQ (val, Qunbound)
-               && !XSYMBOL (sym)->indirect_variable
-               && !SYMBOL_CONSTANT_P (sym)
-               && !MISCP (XSYMBOL (sym)->value))
-             XSYMBOL (sym)->value = val;
+               && !XSYMBOL (sym)->redirect
+               && !SYMBOL_CONSTANT_P (sym))
+             XSYMBOL (sym)->val.value = val;
            else
              {
                BEFORE_POTENTIAL_GC ();
-               set_internal (sym, val, current_buffer, 0);
+               set_internal (sym, val, Qnil, 0);
                AFTER_POTENTIAL_GC ();
              }
          }
@@ -837,7 +901,7 @@ If the third argument is incorrect, Emacs may crash.  */)
 
        case Bsave_window_excursion:
          BEFORE_POTENTIAL_GC ();
-         TOP = Fsave_window_excursion (TOP);
+         TOP = Fsave_window_excursion (TOP); /* FIXME: lexbind */
          AFTER_POTENTIAL_GC ();
          break;
 
@@ -851,13 +915,13 @@ If the third argument is incorrect, Emacs may crash.  */)
            Lisp_Object v1;
            BEFORE_POTENTIAL_GC ();
            v1 = POP;
-           TOP = internal_catch (TOP, Feval, v1);
+           TOP = internal_catch (TOP, eval_sub, 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:
@@ -866,7 +930,7 @@ If the third argument is incorrect, Emacs may crash.  */)
            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;
          }
@@ -1640,8 +1704,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, 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)
+           {
+             op &= 0x7F;
+             top[-op] = TOP;
+           }
+         DISCARD (op);
+         break;
 
        case 255:
        default:
@@ -1677,9 +1790,9 @@ If the third argument is incorrect, Emacs may crash.  */)
 }
 
 void
-syms_of_bytecode ()
+syms_of_bytecode (void)
 {
-  Qbytecode = intern ("byte-code");
+  Qbytecode = intern_c_string ("byte-code");
   staticpro (&Qbytecode);
 
   defsubr (&Sbyte_code);
@@ -1702,7 +1815,7 @@ integer, it is incremented each time that symbol's function is called.  */);
 
   byte_metering_on = 0;
   Vbyte_code_meter = Fmake_vector (make_number (256), make_number (0));
-  Qbyte_code_meter = intern ("byte-code-meter");
+  Qbyte_code_meter = intern_c_string ("byte-code-meter");
   staticpro (&Qbyte_code_meter);
   {
     int i = 256;