aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bytecode.c91
-rw-r--r--src/eval.c37
-rw-r--r--src/lisp.h5
3 files changed, 116 insertions, 17 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index 29b76f88ef7..fe59cf6600b 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -311,8 +311,6 @@ enum byte_code_op
311 311
312#define TOP (*top) 312#define TOP (*top)
313 313
314#define UPDATE_OFFSET (backtrace_byte_offset = pc - bytestr_data);
315
316DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, 314DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0,
317 doc: /* Function used internally in byte-compiled code. 315 doc: /* Function used internally in byte-compiled code.
318The first argument, BYTESTR, is a string of byte code; 316The first argument, BYTESTR, is a string of byte code;
@@ -433,7 +431,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
433 /* NEXT is invoked at the end of an instruction to go to the 431 /* NEXT is invoked at the end of an instruction to go to the
434 next instruction. It is either a computed goto, or a 432 next instruction. It is either a computed goto, or a
435 plain break. */ 433 plain break. */
436#define NEXT UPDATE_OFFSET goto *(targets[op = FETCH]) 434#define NEXT goto *(targets[op = FETCH])
437 /* FIRST is like NEXT, but is only used at the start of the 435 /* FIRST is like NEXT, but is only used at the start of the
438 interpreter body. In the switch-based interpreter it is the 436 interpreter body. In the switch-based interpreter it is the
439 switch, so the threaded definition must include a semicolon. */ 437 switch, so the threaded definition must include a semicolon. */
@@ -635,7 +633,90 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
635 } 633 }
636 } 634 }
637#endif 635#endif
638 TOP = Ffuncall (op + 1, &TOP); 636 Lisp_Object fun, original_fun;
637 Lisp_Object funcar;
638 Lisp_Object *fun_args;
639 ptrdiff_t numargs = op;
640 Lisp_Object val;
641 ptrdiff_t count_c;
642
643 maybe_quit ();
644
645 if (++lisp_eval_depth > max_lisp_eval_depth)
646 {
647 if (max_lisp_eval_depth < 100)
648 max_lisp_eval_depth = 100;
649 if (lisp_eval_depth > max_lisp_eval_depth)
650 error ("Lisp nesting exceeds `max-lisp-eval-depth'");
651 }
652
653 fun_args = &TOP + 1;
654
655 count_c = record_in_backtrace_with_offset (TOP, fun_args, numargs, pc - bytestr_data - 1);
656
657 maybe_gc ();
658
659 if (debug_on_next_call)
660 do_debug_on_call (Qlambda, count);
661
662 original_fun = TOP;
663
664 retry:
665
666 /* Optimize for no indirection. */
667 fun = original_fun;
668 if (SYMBOLP (fun) && !NILP (fun)
669 && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun)))
670 fun = indirect_function (fun);
671
672 if (COMPILEDP (fun))
673 {
674 Lisp_Object syms_left = AREF (fun, COMPILED_ARGLIST);
675 if (FIXNUMP (syms_left))
676 {
677 if (CONSP (AREF (fun, COMPILED_BYTECODE)))
678 Ffetch_bytecode (fun);
679 val = exec_byte_code (AREF (fun, COMPILED_BYTECODE),
680 AREF (fun, COMPILED_CONSTANTS),
681 AREF (fun, COMPILED_STACK_DEPTH),
682 syms_left, numargs, fun_args);
683 }
684 else
685 {
686 /* The rest of funcall_lambda is very bulky */
687 val = funcall_lambda (fun, numargs, fun_args);
688 }
689 }
690 else if (SUBRP (fun))
691 val = funcall_subr (XSUBR (fun), numargs, fun_args);
692#ifdef HAVE_MODULES
693 else if (MODULE_FUNCTIONP (fun))
694 val = funcall_module (fun, numargs, fun_args);
695#endif
696 else
697 {
698 if (NILP (fun))
699 xsignal1 (Qvoid_function, original_fun);
700 if (!CONSP (fun)
701 || (funcar = XCAR (fun), !SYMBOLP(funcar)))
702 xsignal1 (Qinvalid_function, original_fun);
703 if (EQ (funcar, Qlambda)
704 || EQ (funcar, Qclosure))
705 val = funcall_lambda (fun, numargs, fun_args);
706 else if (EQ (funcar, Qautoload))
707 {
708 Fautoload_do_load (fun, original_fun, Qnil);
709 goto retry;
710 }
711 else
712 xsignal1 (Qinvalid_function, original_fun);
713 }
714 lisp_eval_depth--;
715 if (backtrace_debug_on_exit (specpdl + count_c))
716 val = call_debugger (list2 (Qexit, val));
717 specpdl_ptr--;
718
719 TOP = val;
639 NEXT; 720 NEXT;
640 } 721 }
641 722
@@ -1451,7 +1532,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1451 unbind_to (count, Qnil); 1532 unbind_to (count, Qnil);
1452 error ("binding stack not balanced (serious byte compiler bug)"); 1533 error ("binding stack not balanced (serious byte compiler bug)");
1453 } 1534 }
1454 backtrace_byte_offset = -1; 1535
1455 Lisp_Object result = TOP; 1536 Lisp_Object result = TOP;
1456 SAFE_FREE (); 1537 SAFE_FREE ();
1457 return result; 1538 return result;
diff --git a/src/eval.c b/src/eval.c
index 5b43b81a6ca..544dfc25af9 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -56,8 +56,6 @@ Lisp_Object Vrun_hooks;
56/* FIXME: We should probably get rid of this! */ 56/* FIXME: We should probably get rid of this! */
57Lisp_Object Vsignaling_function; 57Lisp_Object Vsignaling_function;
58 58
59int backtrace_byte_offset = -1;
60
61/* These would ordinarily be static, but they need to be visible to GDB. */ 59/* These would ordinarily be static, but they need to be visible to GDB. */
62bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE; 60bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE;
63Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE; 61Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE;
@@ -65,7 +63,6 @@ Lisp_Object backtrace_function (union specbinding *) EXTERNALLY_VISIBLE;
65union specbinding *backtrace_next (union specbinding *) EXTERNALLY_VISIBLE; 63union specbinding *backtrace_next (union specbinding *) EXTERNALLY_VISIBLE;
66union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE; 64union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE;
67 65
68static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *);
69static Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, ptrdiff_t); 66static Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, ptrdiff_t);
70static Lisp_Object lambda_arity (Lisp_Object); 67static Lisp_Object lambda_arity (Lisp_Object);
71 68
@@ -146,7 +143,7 @@ backtrace_bytecode_offset (union specbinding *pdl)
146 return pdl->bt.bytecode_offset; 143 return pdl->bt.bytecode_offset;
147} 144}
148 145
149static bool 146bool
150backtrace_debug_on_exit (union specbinding *pdl) 147backtrace_debug_on_exit (union specbinding *pdl)
151{ 148{
152 eassert (pdl->kind == SPECPDL_BACKTRACE); 149 eassert (pdl->kind == SPECPDL_BACKTRACE);
@@ -354,7 +351,7 @@ call_debugger (Lisp_Object arg)
354 return unbind_to (count, val); 351 return unbind_to (count, val);
355} 352}
356 353
357static void 354void
358do_debug_on_call (Lisp_Object code, ptrdiff_t count) 355do_debug_on_call (Lisp_Object code, ptrdiff_t count)
359{ 356{
360 debug_on_next_call = 0; 357 debug_on_next_call = 0;
@@ -2146,6 +2143,27 @@ grow_specpdl (void)
2146} 2143}
2147 2144
2148ptrdiff_t 2145ptrdiff_t
2146record_in_backtrace_with_offset (Lisp_Object function, Lisp_Object *args,
2147 ptrdiff_t nargs, int offset)
2148{
2149 ptrdiff_t count = SPECPDL_INDEX ();
2150
2151 eassert (nargs >= UNEVALLED);
2152 specpdl_ptr->bt.kind = SPECPDL_BACKTRACE;
2153 specpdl_ptr->bt.debug_on_exit = false;
2154 specpdl_ptr->bt.function = function;
2155 current_thread->stack_top = specpdl_ptr->bt.args = args;
2156 specpdl_ptr->bt.nargs = nargs;
2157 specpdl_ptr->bt.bytecode_offset = -1;
2158 union specbinding *nxt = backtrace_top ();
2159 if (backtrace_p (nxt) && nxt->kind == SPECPDL_BACKTRACE)
2160 nxt->bt.bytecode_offset = offset;
2161 grow_specpdl ();
2162
2163 return count;
2164}
2165
2166ptrdiff_t
2149record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) 2167record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
2150{ 2168{
2151 ptrdiff_t count = SPECPDL_INDEX (); 2169 ptrdiff_t count = SPECPDL_INDEX ();
@@ -2156,10 +2174,7 @@ record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
2156 specpdl_ptr->bt.function = function; 2174 specpdl_ptr->bt.function = function;
2157 current_thread->stack_top = specpdl_ptr->bt.args = args; 2175 current_thread->stack_top = specpdl_ptr->bt.args = args;
2158 specpdl_ptr->bt.nargs = nargs; 2176 specpdl_ptr->bt.nargs = nargs;
2159 union specbinding *nxt = specpdl_ptr; 2177 specpdl_ptr->bt.bytecode_offset = -1;
2160 nxt = backtrace_next(nxt);
2161 if (nxt->kind == SPECPDL_BACKTRACE)
2162 nxt->bt.bytecode_offset = backtrace_byte_offset;
2163 grow_specpdl (); 2178 grow_specpdl ();
2164 2179
2165 return count; 2180 return count;
@@ -2965,7 +2980,7 @@ apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count)
2965 FUN must be either a lambda-expression, a compiled-code object, 2980 FUN must be either a lambda-expression, a compiled-code object,
2966 or a module function. */ 2981 or a module function. */
2967 2982
2968static Lisp_Object 2983Lisp_Object
2969funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, 2984funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
2970 register Lisp_Object *arg_vector) 2985 register Lisp_Object *arg_vector)
2971{ 2986{
@@ -3053,7 +3068,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
3053 arg = Qnil; 3068 arg = Qnil;
3054 3069
3055 /* Bind the argument. */ 3070 /* Bind the argument. */
3056 if (!NILP (lexenv) && SYMBOLP (next)) 3071 if (!NILP (lexenv))
3057 /* Lexically bind NEXT by adding it to the lexenv alist. */ 3072 /* Lexically bind NEXT by adding it to the lexenv alist. */
3058 lexenv = Fcons (Fcons (next, arg), lexenv); 3073 lexenv = Fcons (Fcons (next, arg), lexenv);
3059 else 3074 else
diff --git a/src/lisp.h b/src/lisp.h
index ef6302a4670..e04e374ca97 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4113,7 +4113,6 @@ extern Lisp_Object Vautoload_queue;
4113extern Lisp_Object Vrun_hooks; 4113extern Lisp_Object Vrun_hooks;
4114extern Lisp_Object Vsignaling_function; 4114extern Lisp_Object Vsignaling_function;
4115extern Lisp_Object inhibit_lisp_code; 4115extern Lisp_Object inhibit_lisp_code;
4116extern int backtrace_byte_offset;
4117 4116
4118/* To run a normal hook, use the appropriate function from the list below. 4117/* To run a normal hook, use the appropriate function from the list below.
4119 The calling convention: 4118 The calling convention:
@@ -4141,6 +4140,7 @@ extern AVOID signal_error (const char *, Lisp_Object);
4141extern AVOID overflow_error (void); 4140extern AVOID overflow_error (void);
4142extern bool FUNCTIONP (Lisp_Object); 4141extern bool FUNCTIONP (Lisp_Object);
4143extern Lisp_Object funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *arg_vector); 4142extern Lisp_Object funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *arg_vector);
4143extern Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *);
4144extern Lisp_Object eval_sub (Lisp_Object form); 4144extern Lisp_Object eval_sub (Lisp_Object form);
4145extern Lisp_Object apply1 (Lisp_Object, Lisp_Object); 4145extern Lisp_Object apply1 (Lisp_Object, Lisp_Object);
4146extern Lisp_Object call0 (Lisp_Object); 4146extern Lisp_Object call0 (Lisp_Object);
@@ -4185,6 +4185,7 @@ extern Lisp_Object vformat_string (const char *, va_list)
4185 ATTRIBUTE_FORMAT_PRINTF (1, 0); 4185 ATTRIBUTE_FORMAT_PRINTF (1, 0);
4186extern void un_autoload (Lisp_Object); 4186extern void un_autoload (Lisp_Object);
4187extern Lisp_Object call_debugger (Lisp_Object arg); 4187extern Lisp_Object call_debugger (Lisp_Object arg);
4188extern void do_debug_on_call (Lisp_Object code, ptrdiff_t count);
4188extern void init_eval_once (void); 4189extern void init_eval_once (void);
4189extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...); 4190extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...);
4190extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object); 4191extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object);
@@ -4193,8 +4194,10 @@ extern void init_eval (void);
4193extern void syms_of_eval (void); 4194extern void syms_of_eval (void);
4194extern void prog_ignore (Lisp_Object); 4195extern void prog_ignore (Lisp_Object);
4195extern ptrdiff_t record_in_backtrace (Lisp_Object, Lisp_Object *, ptrdiff_t); 4196extern ptrdiff_t record_in_backtrace (Lisp_Object, Lisp_Object *, ptrdiff_t);
4197extern ptrdiff_t record_in_backtrace_with_offset (Lisp_Object, Lisp_Object *, ptrdiff_t, int);
4196extern void mark_specpdl (union specbinding *first, union specbinding *ptr); 4198extern void mark_specpdl (union specbinding *first, union specbinding *ptr);
4197extern void get_backtrace (Lisp_Object array); 4199extern void get_backtrace (Lisp_Object array);
4200extern bool backtrace_debug_on_exit (union specbinding *pdl);
4198Lisp_Object backtrace_top_function (void); 4201Lisp_Object backtrace_top_function (void);
4199extern bool let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol); 4202extern bool let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol);
4200 4203