aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/callint.c6
-rw-r--r--src/data.c46
-rw-r--r--src/eval.c148
-rw-r--r--src/lread.c35
-rw-r--r--src/profiler.c8
5 files changed, 149 insertions, 94 deletions
diff --git a/src/callint.c b/src/callint.c
index b31faba8704..9d6f2ab2888 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -319,10 +319,10 @@ invoke it (via an `interactive' spec that contains, for instance, an
319 { 319 {
320 Lisp_Object funval = Findirect_function (function, Qt); 320 Lisp_Object funval = Findirect_function (function, Qt);
321 uintmax_t events = num_input_events; 321 uintmax_t events = num_input_events;
322 Lisp_Object env = CLOSUREP (funval) && CONSP (AREF (funval, CLOSURE_CODE))
323 ? AREF (funval, CLOSURE_CONSTANTS) : Qnil;
322 /* Compute the arg values using the user's expression. */ 324 /* Compute the arg values using the user's expression. */
323 specs = Feval (specs, 325 specs = Feval (specs, env);
324 CONSP (funval) && EQ (Qclosure, XCAR (funval))
325 ? CAR_SAFE (XCDR (funval)) : Qnil);
326 if (events != num_input_events || !NILP (record_flag)) 326 if (events != num_input_events || !NILP (record_flag))
327 { 327 {
328 /* We should record this command on the command history. 328 /* We should record this command on the command history.
diff --git a/src/data.c b/src/data.c
index 681054ff8cb..ea611ad1abf 100644
--- a/src/data.c
+++ b/src/data.c
@@ -248,7 +248,9 @@ a fixed set of types. */)
248 return XSUBR (object)->max_args == UNEVALLED ? Qspecial_form 248 return XSUBR (object)->max_args == UNEVALLED ? Qspecial_form
249 : SUBR_NATIVE_COMPILEDP (object) ? Qsubr_native_elisp 249 : SUBR_NATIVE_COMPILEDP (object) ? Qsubr_native_elisp
250 : Qprimitive_function; 250 : Qprimitive_function;
251 case PVEC_CLOSURE: return Qcompiled_function; 251 case PVEC_CLOSURE:
252 return CONSP (AREF (object, CLOSURE_CODE))
253 ? Qinterpreted_function : Qbyte_code_function;
252 case PVEC_BUFFER: return Qbuffer; 254 case PVEC_BUFFER: return Qbuffer;
253 case PVEC_CHAR_TABLE: return Qchar_table; 255 case PVEC_CHAR_TABLE: return Qchar_table;
254 case PVEC_BOOL_VECTOR: return Qbool_vector; 256 case PVEC_BOOL_VECTOR: return Qbool_vector;
@@ -518,12 +520,32 @@ DEFUN ("subrp", Fsubrp, Ssubrp, 1, 1, 0,
518 return Qnil; 520 return Qnil;
519} 521}
520 522
523DEFUN ("closurep", Fclosurep, Sclosurep,
524 1, 1, 0,
525 doc: /* Return t if OBJECT is a function of type `closure'. */)
526 (Lisp_Object object)
527{
528 if (CLOSUREP (object))
529 return Qt;
530 return Qnil;
531}
532
521DEFUN ("byte-code-function-p", Fbyte_code_function_p, Sbyte_code_function_p, 533DEFUN ("byte-code-function-p", Fbyte_code_function_p, Sbyte_code_function_p,
522 1, 1, 0, 534 1, 1, 0,
523 doc: /* Return t if OBJECT is a byte-compiled function object. */) 535 doc: /* Return t if OBJECT is a byte-compiled function object. */)
524 (Lisp_Object object) 536 (Lisp_Object object)
525{ 537{
526 if (CLOSUREP (object)) 538 if (CLOSUREP (object) && STRINGP (AREF (object, CLOSURE_CODE)))
539 return Qt;
540 return Qnil;
541}
542
543DEFUN ("interpreted-function-p", Finterpreted_function_p,
544 Sinterpreted_function_p, 1, 1, 0,
545 doc: /* Return t if OBJECT is a function of type `interpreted-function'. */)
546 (Lisp_Object object)
547{
548 if (CLOSUREP (object) && CONSP (AREF (object, CLOSURE_CODE)))
527 return Qt; 549 return Qt;
528 return Qnil; 550 return Qnil;
529} 551}
@@ -1174,17 +1196,11 @@ Value, if non-nil, is a list (interactive SPEC). */)
1174 else if (CONSP (fun)) 1196 else if (CONSP (fun))
1175 { 1197 {
1176 Lisp_Object funcar = XCAR (fun); 1198 Lisp_Object funcar = XCAR (fun);
1177 if (EQ (funcar, Qclosure) 1199 if (EQ (funcar, Qlambda))
1178 || EQ (funcar, Qlambda))
1179 { 1200 {
1180 Lisp_Object form = Fcdr (XCDR (fun)); 1201 Lisp_Object form = Fcdr (XCDR (fun));
1181 if (EQ (funcar, Qclosure))
1182 form = Fcdr (form);
1183 Lisp_Object spec = Fassq (Qinteractive, form); 1202 Lisp_Object spec = Fassq (Qinteractive, form);
1184 if (NILP (spec) && VALID_DOCSTRING_P (CAR_SAFE (form))) 1203 if (NILP (Fcdr (Fcdr (spec))))
1185 /* A "docstring" is a sign that we may have an OClosure. */
1186 genfun = true;
1187 else if (NILP (Fcdr (Fcdr (spec))))
1188 return spec; 1204 return spec;
1189 else 1205 else
1190 return list2 (Qinteractive, Fcar (Fcdr (spec))); 1206 return list2 (Qinteractive, Fcar (Fcdr (spec)));
@@ -1257,12 +1273,9 @@ The value, if non-nil, is a list of mode name symbols. */)
1257 else if (CONSP (fun)) 1273 else if (CONSP (fun))
1258 { 1274 {
1259 Lisp_Object funcar = XCAR (fun); 1275 Lisp_Object funcar = XCAR (fun);
1260 if (EQ (funcar, Qclosure) 1276 if (EQ (funcar, Qlambda))
1261 || EQ (funcar, Qlambda))
1262 { 1277 {
1263 Lisp_Object form = Fcdr (XCDR (fun)); 1278 Lisp_Object form = Fcdr (XCDR (fun));
1264 if (EQ (funcar, Qclosure))
1265 form = Fcdr (form);
1266 return Fcdr (Fcdr (Fassq (Qinteractive, form))); 1279 return Fcdr (Fcdr (Fassq (Qinteractive, form)));
1267 } 1280 }
1268 } 1281 }
@@ -4224,7 +4237,8 @@ syms_of_data (void)
4224 DEFSYM (Qspecial_form, "special-form"); 4237 DEFSYM (Qspecial_form, "special-form");
4225 DEFSYM (Qprimitive_function, "primitive-function"); 4238 DEFSYM (Qprimitive_function, "primitive-function");
4226 DEFSYM (Qsubr_native_elisp, "subr-native-elisp"); 4239 DEFSYM (Qsubr_native_elisp, "subr-native-elisp");
4227 DEFSYM (Qcompiled_function, "compiled-function"); 4240 DEFSYM (Qbyte_code_function, "byte-code-function");
4241 DEFSYM (Qinterpreted_function, "interpreted-function");
4228 DEFSYM (Qbuffer, "buffer"); 4242 DEFSYM (Qbuffer, "buffer");
4229 DEFSYM (Qframe, "frame"); 4243 DEFSYM (Qframe, "frame");
4230 DEFSYM (Qvector, "vector"); 4244 DEFSYM (Qvector, "vector");
@@ -4289,6 +4303,8 @@ syms_of_data (void)
4289 defsubr (&Smarkerp); 4303 defsubr (&Smarkerp);
4290 defsubr (&Ssubrp); 4304 defsubr (&Ssubrp);
4291 defsubr (&Sbyte_code_function_p); 4305 defsubr (&Sbyte_code_function_p);
4306 defsubr (&Sinterpreted_function_p);
4307 defsubr (&Sclosurep);
4292 defsubr (&Smodule_function_p); 4308 defsubr (&Smodule_function_p);
4293 defsubr (&Schar_or_string_p); 4309 defsubr (&Schar_or_string_p);
4294 defsubr (&Sthreadp); 4310 defsubr (&Sthreadp);
diff --git a/src/eval.c b/src/eval.c
index a7d860114cf..fd388706108 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -510,6 +510,33 @@ usage: (quote ARG) */)
510 return XCAR (args); 510 return XCAR (args);
511} 511}
512 512
513DEFUN ("make-interpreted-closure", Fmake_interpreted_closure,
514 Smake_interpreted_closure, 3, 5, 0,
515 doc: /* Make an interpreted closure.
516ARGS should be the list of formal arguments.
517BODY should be a non-empty list of forms.
518ENV should be a lexical environment, like the second argument of `eval'.
519IFORM if non-nil should be of the form (interactive ...). */)
520 (Lisp_Object args, Lisp_Object body, Lisp_Object env,
521 Lisp_Object docstring, Lisp_Object iform)
522{
523 CHECK_CONS (body); /* Make sure it's not confused with byte-code! */
524 CHECK_LIST (args);
525 CHECK_LIST (iform);
526 Lisp_Object ifcdr = Fcdr (iform);
527 Lisp_Object slots[] = { args, body, env, Qnil, docstring,
528 NILP (Fcdr (ifcdr))
529 ? Fcar (ifcdr)
530 : CALLN (Fvector, XCAR (ifcdr), XCDR (ifcdr)) };
531 /* Adjusting the size is indispensable since, as for byte-code objects,
532 we distinguish interactive functions by the presence or absence of the
533 iform slot. */
534 Lisp_Object val
535 = Fvector (!NILP (iform) ? 6 : !NILP (docstring) ? 5 : 3, slots);
536 XSETPVECTYPE (XVECTOR (val), PVEC_CLOSURE);
537 return val;
538}
539
513DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0, 540DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0,
514 doc: /* Like `quote', but preferred for objects which are functions. 541 doc: /* Like `quote', but preferred for objects which are functions.
515In byte compilation, `function' causes its argument to be handled by 542In byte compilation, `function' causes its argument to be handled by
@@ -525,33 +552,55 @@ usage: (function ARG) */)
525 if (!NILP (XCDR (args))) 552 if (!NILP (XCDR (args)))
526 xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args)); 553 xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args));
527 554
528 if (!NILP (Vinternal_interpreter_environment) 555 if (CONSP (quoted)
529 && CONSP (quoted)
530 && EQ (XCAR (quoted), Qlambda)) 556 && EQ (XCAR (quoted), Qlambda))
531 { /* This is a lambda expression within a lexical environment; 557 { /* This is a lambda expression within a lexical environment;
532 return an interpreted closure instead of a simple lambda. */ 558 return an interpreted closure instead of a simple lambda. */
533 Lisp_Object cdr = XCDR (quoted); 559 Lisp_Object cdr = XCDR (quoted);
534 Lisp_Object tmp = cdr; 560 Lisp_Object args = Fcar (cdr);
535 if (CONSP (tmp) 561 cdr = Fcdr (cdr);
536 && (tmp = XCDR (tmp), CONSP (tmp)) 562 Lisp_Object docstring = Qnil, iform = Qnil;
537 && (tmp = XCAR (tmp), CONSP (tmp)) 563 if (CONSP (cdr))
538 && (EQ (QCdocumentation, XCAR (tmp)))) 564 {
539 { /* Handle the special (:documentation <form>) to build the docstring 565 docstring = XCAR (cdr);
566 if (STRINGP (docstring))
567 {
568 Lisp_Object tmp = XCDR (cdr);
569 if (!NILP (tmp))
570 cdr = tmp;
571 else /* It's not a docstring, it's a return value. */
572 docstring = Qnil;
573 }
574 /* Handle the special (:documentation <form>) to build the docstring
540 dynamically. */ 575 dynamically. */
541 Lisp_Object docstring = eval_sub (Fcar (XCDR (tmp))); 576 else if (CONSP (docstring)
542 if (SYMBOLP (docstring) && !NILP (docstring)) 577 && EQ (QCdocumentation, XCAR (docstring))
543 /* Hack for OClosures: Allow the docstring to be a symbol 578 && (docstring = eval_sub (Fcar (XCDR (docstring))),
544 * (the OClosure's type). */ 579 true))
545 docstring = Fsymbol_name (docstring); 580 cdr = XCDR (cdr);
546 CHECK_STRING (docstring); 581 else
547 cdr = Fcons (XCAR (cdr), Fcons (docstring, XCDR (XCDR (cdr)))); 582 docstring = Qnil; /* Not a docstring after all. */
548 } 583 }
549 if (NILP (Vinternal_make_interpreted_closure_function)) 584 if (CONSP (cdr))
550 return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, cdr)); 585 {
586 iform = XCAR (cdr);
587 if (CONSP (iform)
588 && EQ (Qinteractive, XCAR (iform)))
589 cdr = XCDR (cdr);
590 else
591 iform = Qnil; /* Not an interactive-form after all. */
592 }
593 if (NILP (cdr))
594 cdr = Fcons (Qnil, Qnil); /* Make sure the body is never empty! */
595
596 if (NILP (Vinternal_interpreter_environment)
597 || NILP (Vinternal_make_interpreted_closure_function))
598 return Fmake_interpreted_closure
599 (args, cdr, Vinternal_interpreter_environment, docstring, iform);
551 else 600 else
552 return call2 (Vinternal_make_interpreted_closure_function, 601 return call5 (Vinternal_make_interpreted_closure_function,
553 Fcons (Qlambda, cdr), 602 args, cdr, Vinternal_interpreter_environment,
554 Vinternal_interpreter_environment); 603 docstring, iform);
555 } 604 }
556 else 605 else
557 /* Simply quote the argument. */ 606 /* Simply quote the argument. */
@@ -2193,15 +2242,12 @@ then strings and vectors are not accepted. */)
2193 else 2242 else
2194 { 2243 {
2195 Lisp_Object body = CDR_SAFE (XCDR (fun)); 2244 Lisp_Object body = CDR_SAFE (XCDR (fun));
2196 if (EQ (funcar, Qclosure)) 2245 if (!EQ (funcar, Qlambda))
2197 body = CDR_SAFE (body);
2198 else if (!EQ (funcar, Qlambda))
2199 return Qnil; 2246 return Qnil;
2200 if (!NILP (Fassq (Qinteractive, body))) 2247 if (!NILP (Fassq (Qinteractive, body)))
2201 return Qt; 2248 return Qt;
2202 else if (VALID_DOCSTRING_P (CAR_SAFE (body))) 2249 else
2203 /* A "docstring" is a sign that we may have an OClosure. */ 2250 return Qnil;
2204 genfun = true;
2205 } 2251 }
2206 } 2252 }
2207 2253
@@ -2611,8 +2657,7 @@ eval_sub (Lisp_Object form)
2611 exp = unbind_to (count1, exp); 2657 exp = unbind_to (count1, exp);
2612 val = eval_sub (exp); 2658 val = eval_sub (exp);
2613 } 2659 }
2614 else if (EQ (funcar, Qlambda) 2660 else if (EQ (funcar, Qlambda))
2615 || EQ (funcar, Qclosure))
2616 return apply_lambda (fun, original_args, count); 2661 return apply_lambda (fun, original_args, count);
2617 else 2662 else
2618 xsignal1 (Qinvalid_function, original_fun); 2663 xsignal1 (Qinvalid_function, original_fun);
@@ -2950,7 +2995,7 @@ FUNCTIONP (Lisp_Object object)
2950 else if (CONSP (object)) 2995 else if (CONSP (object))
2951 { 2996 {
2952 Lisp_Object car = XCAR (object); 2997 Lisp_Object car = XCAR (object);
2953 return EQ (car, Qlambda) || EQ (car, Qclosure); 2998 return EQ (car, Qlambda);
2954 } 2999 }
2955 else 3000 else
2956 return false; 3001 return false;
@@ -2980,8 +3025,7 @@ funcall_general (Lisp_Object fun, ptrdiff_t numargs, Lisp_Object *args)
2980 Lisp_Object funcar = XCAR (fun); 3025 Lisp_Object funcar = XCAR (fun);
2981 if (!SYMBOLP (funcar)) 3026 if (!SYMBOLP (funcar))
2982 xsignal1 (Qinvalid_function, original_fun); 3027 xsignal1 (Qinvalid_function, original_fun);
2983 if (EQ (funcar, Qlambda) 3028 if (EQ (funcar, Qlambda))
2984 || EQ (funcar, Qclosure))
2985 return funcall_lambda (fun, numargs, args); 3029 return funcall_lambda (fun, numargs, args);
2986 else if (EQ (funcar, Qautoload)) 3030 else if (EQ (funcar, Qautoload))
2987 { 3031 {
@@ -3165,16 +3209,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, Lisp_Object *arg_vector)
3165 3209
3166 if (CONSP (fun)) 3210 if (CONSP (fun))
3167 { 3211 {
3168 if (EQ (XCAR (fun), Qclosure)) 3212 lexenv = Qnil;
3169 {
3170 Lisp_Object cdr = XCDR (fun); /* Drop `closure'. */
3171 if (! CONSP (cdr))
3172 xsignal1 (Qinvalid_function, fun);
3173 fun = cdr;
3174 lexenv = XCAR (fun);
3175 }
3176 else
3177 lexenv = Qnil;
3178 syms_left = XCDR (fun); 3213 syms_left = XCDR (fun);
3179 if (CONSP (syms_left)) 3214 if (CONSP (syms_left))
3180 syms_left = XCAR (syms_left); 3215 syms_left = XCAR (syms_left);
@@ -3189,10 +3224,12 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, Lisp_Object *arg_vector)
3189 engine directly. */ 3224 engine directly. */
3190 if (FIXNUMP (syms_left)) 3225 if (FIXNUMP (syms_left))
3191 return exec_byte_code (fun, XFIXNUM (syms_left), nargs, arg_vector); 3226 return exec_byte_code (fun, XFIXNUM (syms_left), nargs, arg_vector);
3192 /* Otherwise the bytecode object uses dynamic binding and the 3227 /* Otherwise the closure either is interpreted
3193 ARGLIST slot contains a standard formal argument list whose 3228 or uses dynamic binding and the ARGLIST slot contains a standard
3194 variables are bound dynamically below. */ 3229 formal argument list whose variables are bound dynamically below. */
3195 lexenv = Qnil; 3230 lexenv = CONSP (AREF (fun, CLOSURE_CODE))
3231 ? AREF (fun, CLOSURE_CONSTANTS)
3232 : Qnil;
3196 } 3233 }
3197#ifdef HAVE_MODULES 3234#ifdef HAVE_MODULES
3198 else if (MODULE_FUNCTIONP (fun)) 3235 else if (MODULE_FUNCTIONP (fun))
@@ -3280,7 +3317,14 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, Lisp_Object *arg_vector)
3280 val = XSUBR (fun)->function.a0 (); 3317 val = XSUBR (fun)->function.a0 ();
3281 } 3318 }
3282 else 3319 else
3283 val = exec_byte_code (fun, 0, 0, NULL); 3320 {
3321 eassert (CLOSUREP (fun));
3322 val = CONSP (AREF (fun, CLOSURE_CODE))
3323 /* Interpreted function. */
3324 ? Fprogn (AREF (fun, CLOSURE_CODE))
3325 /* Dynbound bytecode. */
3326 : exec_byte_code (fun, 0, 0, NULL);
3327 }
3284 3328
3285 return unbind_to (count, val); 3329 return unbind_to (count, val);
3286} 3330}
@@ -3330,8 +3374,7 @@ function with `&rest' args, or `unevalled' for a special form. */)
3330 funcar = XCAR (function); 3374 funcar = XCAR (function);
3331 if (!SYMBOLP (funcar)) 3375 if (!SYMBOLP (funcar))
3332 xsignal1 (Qinvalid_function, original); 3376 xsignal1 (Qinvalid_function, original);
3333 if (EQ (funcar, Qlambda) 3377 if (EQ (funcar, Qlambda))
3334 || EQ (funcar, Qclosure))
3335 result = lambda_arity (function); 3378 result = lambda_arity (function);
3336 else if (EQ (funcar, Qautoload)) 3379 else if (EQ (funcar, Qautoload))
3337 { 3380 {
@@ -3352,11 +3395,6 @@ lambda_arity (Lisp_Object fun)
3352 3395
3353 if (CONSP (fun)) 3396 if (CONSP (fun))
3354 { 3397 {
3355 if (EQ (XCAR (fun), Qclosure))
3356 {
3357 fun = XCDR (fun); /* Drop `closure'. */
3358 CHECK_CONS (fun);
3359 }
3360 syms_left = XCDR (fun); 3398 syms_left = XCDR (fun);
3361 if (CONSP (syms_left)) 3399 if (CONSP (syms_left))
3362 syms_left = XCAR (syms_left); 3400 syms_left = XCAR (syms_left);
@@ -4265,7 +4303,6 @@ before making `inhibit-quit' nil. */);
4265 DEFSYM (Qcommandp, "commandp"); 4303 DEFSYM (Qcommandp, "commandp");
4266 DEFSYM (Qand_rest, "&rest"); 4304 DEFSYM (Qand_rest, "&rest");
4267 DEFSYM (Qand_optional, "&optional"); 4305 DEFSYM (Qand_optional, "&optional");
4268 DEFSYM (Qclosure, "closure");
4269 DEFSYM (QCdocumentation, ":documentation"); 4306 DEFSYM (QCdocumentation, ":documentation");
4270 DEFSYM (Qdebug, "debug"); 4307 DEFSYM (Qdebug, "debug");
4271 DEFSYM (Qdebug_early, "debug-early"); 4308 DEFSYM (Qdebug_early, "debug-early");
@@ -4423,6 +4460,7 @@ alist of active lexical bindings. */);
4423 defsubr (&Ssetq); 4460 defsubr (&Ssetq);
4424 defsubr (&Squote); 4461 defsubr (&Squote);
4425 defsubr (&Sfunction); 4462 defsubr (&Sfunction);
4463 defsubr (&Smake_interpreted_closure);
4426 defsubr (&Sdefault_toplevel_value); 4464 defsubr (&Sdefault_toplevel_value);
4427 defsubr (&Sset_default_toplevel_value); 4465 defsubr (&Sset_default_toplevel_value);
4428 defsubr (&Sdefvar); 4466 defsubr (&Sdefvar);
diff --git a/src/lread.c b/src/lread.c
index 8b614e6220e..983fdb883ff 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -3523,25 +3523,32 @@ bytecode_from_rev_list (Lisp_Object elems, Lisp_Object readcharfun)
3523 } 3523 }
3524 } 3524 }
3525 3525
3526 if (!(size >= CLOSURE_STACK_DEPTH + 1 && size <= CLOSURE_INTERACTIVE + 1 3526 if (!(size >= CLOSURE_STACK_DEPTH && size <= CLOSURE_INTERACTIVE + 1
3527 && (FIXNUMP (vec[CLOSURE_ARGLIST]) 3527 && (FIXNUMP (vec[CLOSURE_ARGLIST])
3528 || CONSP (vec[CLOSURE_ARGLIST]) 3528 || CONSP (vec[CLOSURE_ARGLIST])
3529 || NILP (vec[CLOSURE_ARGLIST])) 3529 || NILP (vec[CLOSURE_ARGLIST]))
3530 && STRINGP (vec[CLOSURE_CODE]) 3530 && ((STRINGP (vec[CLOSURE_CODE]) /* Byte-code function. */
3531 && VECTORP (vec[CLOSURE_CONSTANTS]) 3531 && VECTORP (vec[CLOSURE_CONSTANTS])
3532 && FIXNATP (vec[CLOSURE_STACK_DEPTH]))) 3532 && size > CLOSURE_STACK_DEPTH
3533 && (FIXNATP (vec[CLOSURE_STACK_DEPTH])))
3534 || (CONSP (vec[CLOSURE_CODE]) /* Interpreted function. */
3535 && (CONSP (vec[CLOSURE_CONSTANTS])
3536 || NILP (vec[CLOSURE_CONSTANTS]))))))
3533 invalid_syntax ("Invalid byte-code object", readcharfun); 3537 invalid_syntax ("Invalid byte-code object", readcharfun);
3534 3538
3535 if (STRING_MULTIBYTE (vec[CLOSURE_CODE])) 3539 if (STRINGP (vec[CLOSURE_CODE]))
3536 /* BYTESTR must have been produced by Emacs 20.2 or earlier 3540 {
3537 because it produced a raw 8-bit string for byte-code and 3541 if (STRING_MULTIBYTE (vec[CLOSURE_CODE]))
3538 now such a byte-code string is loaded as multibyte with 3542 /* BYTESTR must have been produced by Emacs 20.2 or earlier
3539 raw 8-bit characters converted to multibyte form. 3543 because it produced a raw 8-bit string for byte-code and
3540 Convert them back to the original unibyte form. */ 3544 now such a byte-code string is loaded as multibyte with
3541 vec[CLOSURE_CODE] = Fstring_as_unibyte (vec[CLOSURE_CODE]); 3545 raw 8-bit characters converted to multibyte form.
3542 3546 Convert them back to the original unibyte form. */
3543 /* Bytecode must be immovable. */ 3547 vec[CLOSURE_CODE] = Fstring_as_unibyte (vec[CLOSURE_CODE]);
3544 pin_string (vec[CLOSURE_CODE]); 3548
3549 /* Bytecode must be immovable. */
3550 pin_string (vec[CLOSURE_CODE]);
3551 }
3545 3552
3546 XSETPVECTYPE (XVECTOR (obj), PVEC_CLOSURE); 3553 XSETPVECTYPE (XVECTOR (obj), PVEC_CLOSURE);
3547 return obj; 3554 return obj;
diff --git a/src/profiler.c b/src/profiler.c
index ac23a97b672..6e1dc46abd3 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -170,9 +170,7 @@ trace_hash (Lisp_Object *trace, int depth)
170 { 170 {
171 Lisp_Object f = trace[i]; 171 Lisp_Object f = trace[i];
172 EMACS_UINT hash1 172 EMACS_UINT hash1
173 = (CLOSUREP (f) ? XHASH (AREF (f, CLOSURE_CODE)) 173 = (CLOSUREP (f) ? XHASH (AREF (f, CLOSURE_CODE)) : XHASH (f));
174 : (CONSP (f) && CONSP (XCDR (f)) && BASE_EQ (Qclosure, XCAR (f)))
175 ? XHASH (XCDR (XCDR (f))) : XHASH (f));
176 hash = sxhash_combine (hash, hash1); 174 hash = sxhash_combine (hash, hash1);
177 } 175 }
178 return hash; 176 return hash;
@@ -677,10 +675,6 @@ the same lambda expression, or are really unrelated function. */)
677 res = true; 675 res = true;
678 else if (CLOSUREP (f1) && CLOSUREP (f2)) 676 else if (CLOSUREP (f1) && CLOSUREP (f2))
679 res = EQ (AREF (f1, CLOSURE_CODE), AREF (f2, CLOSURE_CODE)); 677 res = EQ (AREF (f1, CLOSURE_CODE), AREF (f2, CLOSURE_CODE));
680 else if (CONSP (f1) && CONSP (f2) && CONSP (XCDR (f1)) && CONSP (XCDR (f2))
681 && EQ (Qclosure, XCAR (f1))
682 && EQ (Qclosure, XCAR (f2)))
683 res = EQ (XCDR (XCDR (f1)), XCDR (XCDR (f2)));
684 else 678 else
685 res = false; 679 res = false;
686 return res ? Qt : Qnil; 680 return res ? Qt : Qnil;