summaryrefslogtreecommitdiff
path: root/src/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/src/eval.c b/src/eval.c
index 7e2fbca743a..2bf8dcb0f79 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -64,6 +64,7 @@ union specbinding *backtrace_next (union specbinding *) EXTERNALLY_VISIBLE;
union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE;
static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *);
+static Lisp_Object apply_lambda0 (Lisp_Object, Lisp_Object, ptrdiff_t);
static Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, ptrdiff_t);
static Lisp_Object lambda_arity (Lisp_Object);
@@ -2159,6 +2160,7 @@ record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
Lisp_Object
eval_sub (Lisp_Object form)
{
+ Lisp_Object lexspace = Qnil;
if (SYMBOLP (form))
{
/* Look up its binding in the lexical environment.
@@ -2208,7 +2210,10 @@ eval_sub (Lisp_Object form)
fun = original_fun;
if (!SYMBOLP (fun))
fun = Ffunction (list1 (fun));
- else if (!NILP (fun) && (fun = SYMBOL_FUNCTION (XSYMBOL (fun)), SYMBOLP (fun)))
+ else if (!NILP (fun)
+ && (lexspace = SYMBOL_FUNC_LEXSPACE (XSYMBOL (fun)),
+ SYMBOL_FUNCTION (XSYMBOL (fun)),
+ SYMBOLP (fun)))
fun = indirect_function (fun);
if (SUBRP (fun))
@@ -2345,7 +2350,19 @@ eval_sub (Lisp_Object form)
}
else if (EQ (funcar, Qlambda)
|| EQ (funcar, Qclosure))
- return apply_lambda (fun, original_args, count);
+ {
+ if (!NILP (lexspace)
+ && !EQ (lexspace, Vcurrent_lexspace_idx))
+ {
+ ptrdiff_t count1 = SPECPDL_INDEX ();
+ specbind (Qcurrent_lexspace_idx, lexspace);
+ return unbind_to (count1,
+ apply_lambda0 (fun, original_args,
+ SPECPDL_INDEX ()));
+ }
+ return apply_lambda (fun, original_args, count);
+ }
+
else
xsignal1 (Qinvalid_function, original_fun);
}
@@ -2905,6 +2922,28 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args)
}
static Lisp_Object
+apply_lambda0 (Lisp_Object fun, Lisp_Object args, ptrdiff_t count)
+{
+ Lisp_Object *arg_vector;
+ Lisp_Object tem;
+ USE_SAFE_ALLOCA;
+
+ ptrdiff_t numargs = list_length (args);
+ SAFE_ALLOCA_LISP (arg_vector, numargs);
+ Lisp_Object args_left = args;
+
+ for (ptrdiff_t i = 0; i < numargs; i++)
+ {
+ tem = Fcar (args_left), args_left = Fcdr (args_left);
+ tem = eval_sub (tem);
+ arg_vector[i] = tem;
+ }
+ tem = funcall_lambda (fun, numargs, arg_vector);
+ SAFE_FREE ();
+ return tem;
+}
+
+static Lisp_Object
apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count)
{
Lisp_Object *arg_vector;