diff options
| author | Paul Eggert | 2020-05-19 23:22:40 -0700 |
|---|---|---|
| committer | Paul Eggert | 2020-05-19 23:25:16 -0700 |
| commit | f0b0105d913a94c66f230874c9269b19dbbc83bd (patch) | |
| tree | 21180d9cd9266d18187e8dd4de487eed950efa14 /src | |
| parent | 5352bda4eeb7415ad2bda5d74e007b4f36021e68 (diff) | |
| download | emacs-f0b0105d913a94c66f230874c9269b19dbbc83bd.tar.gz emacs-f0b0105d913a94c66f230874c9269b19dbbc83bd.zip | |
Hoist some byte-code checking out of eval
Check Lisp_Compiled objects better as they’re created,
so that the byte-code interpreter needn’t do the checks
each time it executes them. This improved performance
of ‘make compile-always’ by 1.5% on my platform. Also,
improve the quality of the (still-incomplete) checks, as
this is more practical now that they’re done less often.
* src/alloc.c (make_byte_code): Remove. All uses removed.
(Fmake_byte_code): Put a better (though still incomplete)
check here instead. Simplify by using Fvector instead
of make_uninit_vector followed by memcpy, and by using
XSETPVECTYPE instead of make_byte_code followed by XSETCOMPILED.
* src/bytecode.c (Fbyte_code): Do sanity check and conditional
translation to unibyte here instead of each time the function is
executed.
(exec_byte_code): Omit no-longer-necessary sanity and
unibyte checking. Use SCHARS instead of SBYTES where
either will do, as SCHARS is faster.
* src/eval.c (fetch_and_exec_byte_code): New function.
(funcall_lambda): Use it.
(funcall_lambda, lambda_arity, Ffetch_bytecode):
Omit no-longer-necessary sanity checks.
(Ffetch_bytecode): Add sanity check if actually fetching.
* src/lisp.h (XSETCOMPILED): Remove. All uses removed.
* src/lread.c (read1): Check byte-code objects more thoroughly,
albeit still incompletely, and do translation to unibyte here
instead of each time the function is executed.
(read1): Use XSETPVECYPE instead of make_byte_code.
(read_vector): Omit no-longer-necessary sanity check.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 33 | ||||
| -rw-r--r-- | src/bytecode.c | 28 | ||||
| -rw-r--r-- | src/eval.c | 48 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/lread.c | 26 |
5 files changed, 65 insertions, 72 deletions
diff --git a/src/alloc.c b/src/alloc.c index ebc55857ea0..b7ebaa63a5b 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3421,23 +3421,6 @@ usage: (vector &rest OBJECTS) */) | |||
| 3421 | return val; | 3421 | return val; |
| 3422 | } | 3422 | } |
| 3423 | 3423 | ||
| 3424 | void | ||
| 3425 | make_byte_code (struct Lisp_Vector *v) | ||
| 3426 | { | ||
| 3427 | /* Don't allow the global zero_vector to become a byte code object. */ | ||
| 3428 | eassert (0 < v->header.size); | ||
| 3429 | |||
| 3430 | if (v->header.size > 1 && STRINGP (v->contents[1]) | ||
| 3431 | && STRING_MULTIBYTE (v->contents[1])) | ||
| 3432 | /* BYTECODE-STRING must have been produced by Emacs 20.2 or the | ||
| 3433 | earlier because they produced a raw 8-bit string for byte-code | ||
| 3434 | and now such a byte-code string is loaded as multibyte while | ||
| 3435 | raw 8-bit characters converted to multibyte form. Thus, now we | ||
| 3436 | must convert them back to the original unibyte form. */ | ||
| 3437 | v->contents[1] = Fstring_as_unibyte (v->contents[1]); | ||
| 3438 | XSETPVECTYPE (v, PVEC_COMPILED); | ||
| 3439 | } | ||
| 3440 | |||
| 3441 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, | 3424 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, |
| 3442 | doc: /* Create a byte-code object with specified arguments as elements. | 3425 | doc: /* Create a byte-code object with specified arguments as elements. |
| 3443 | The arguments should be the ARGLIST, bytecode-string BYTE-CODE, constant | 3426 | The arguments should be the ARGLIST, bytecode-string BYTE-CODE, constant |
| @@ -3456,8 +3439,14 @@ stack before executing the byte-code. | |||
| 3456 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) | 3439 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) |
| 3457 | (ptrdiff_t nargs, Lisp_Object *args) | 3440 | (ptrdiff_t nargs, Lisp_Object *args) |
| 3458 | { | 3441 | { |
| 3459 | Lisp_Object val = make_uninit_vector (nargs); | 3442 | if (! ((FIXNUMP (args[COMPILED_ARGLIST]) |
| 3460 | struct Lisp_Vector *p = XVECTOR (val); | 3443 | || CONSP (args[COMPILED_ARGLIST]) |
| 3444 | || NILP (args[COMPILED_ARGLIST])) | ||
| 3445 | && STRINGP (args[COMPILED_BYTECODE]) | ||
| 3446 | && !STRING_MULTIBYTE (args[COMPILED_BYTECODE]) | ||
| 3447 | && VECTORP (args[COMPILED_CONSTANTS]) | ||
| 3448 | && FIXNATP (args[COMPILED_STACK_DEPTH]))) | ||
| 3449 | error ("Invalid byte-code object"); | ||
| 3461 | 3450 | ||
| 3462 | /* We used to purecopy everything here, if purify-flag was set. This worked | 3451 | /* We used to purecopy everything here, if purify-flag was set. This worked |
| 3463 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be | 3452 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be |
| @@ -3466,10 +3455,8 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3466 | copied into pure space, including its free variables, which is sometimes | 3455 | copied into pure space, including its free variables, which is sometimes |
| 3467 | just wasteful and other times plainly wrong (e.g. those free vars may want | 3456 | just wasteful and other times plainly wrong (e.g. those free vars may want |
| 3468 | to be setcar'd). */ | 3457 | to be setcar'd). */ |
| 3469 | 3458 | Lisp_Object val = Fvector (nargs, args); | |
| 3470 | memcpy (p->contents, args, nargs * sizeof *args); | 3459 | XSETPVECTYPE (XVECTOR (val), PVEC_COMPILED); |
| 3471 | make_byte_code (p); | ||
| 3472 | XSETCOMPILED (val, p); | ||
| 3473 | return val; | 3460 | return val; |
| 3474 | } | 3461 | } |
| 3475 | 3462 | ||
diff --git a/src/bytecode.c b/src/bytecode.c index 3c90544f3f2..5ac30aa1010 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -319,6 +319,19 @@ the third, MAXDEPTH, the maximum stack depth used in this function. | |||
| 319 | If the third argument is incorrect, Emacs may crash. */) | 319 | If the third argument is incorrect, Emacs may crash. */) |
| 320 | (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth) | 320 | (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth) |
| 321 | { | 321 | { |
| 322 | if (! (STRINGP (bytestr) && VECTORP (vector) && FIXNATP (maxdepth))) | ||
| 323 | error ("Invalid byte-code"); | ||
| 324 | |||
| 325 | if (STRING_MULTIBYTE (bytestr)) | ||
| 326 | { | ||
| 327 | /* BYTESTR must have been produced by Emacs 20.2 or earlier | ||
| 328 | because it produced a raw 8-bit string for byte-code and now | ||
| 329 | such a byte-code string is loaded as multibyte with raw 8-bit | ||
| 330 | characters converted to multibyte form. Convert them back to | ||
| 331 | the original unibyte form. */ | ||
| 332 | bytestr = Fstring_as_unibyte (bytestr); | ||
| 333 | } | ||
| 334 | |||
| 322 | return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL); | 335 | return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL); |
| 323 | } | 336 | } |
| 324 | 337 | ||
| @@ -344,21 +357,10 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 344 | int volatile this_op = 0; | 357 | int volatile this_op = 0; |
| 345 | #endif | 358 | #endif |
| 346 | 359 | ||
| 347 | CHECK_STRING (bytestr); | 360 | eassert (!STRING_MULTIBYTE (bytestr)); |
| 348 | CHECK_VECTOR (vector); | ||
| 349 | CHECK_FIXNAT (maxdepth); | ||
| 350 | 361 | ||
| 351 | ptrdiff_t const_length = ASIZE (vector); | 362 | ptrdiff_t const_length = ASIZE (vector); |
| 352 | 363 | ptrdiff_t bytestr_length = SCHARS (bytestr); | |
| 353 | if (STRING_MULTIBYTE (bytestr)) | ||
| 354 | /* BYTESTR must have been produced by Emacs 20.2 or the earlier | ||
| 355 | because they produced a raw 8-bit string for byte-code and now | ||
| 356 | such a byte-code string is loaded as multibyte while raw 8-bit | ||
| 357 | characters converted to multibyte form. Thus, now we must | ||
| 358 | convert them back to the originally intended unibyte form. */ | ||
| 359 | bytestr = Fstring_as_unibyte (bytestr); | ||
| 360 | |||
| 361 | ptrdiff_t bytestr_length = SBYTES (bytestr); | ||
| 362 | Lisp_Object *vectorp = XVECTOR (vector)->contents; | 364 | Lisp_Object *vectorp = XVECTOR (vector)->contents; |
| 363 | 365 | ||
| 364 | unsigned char quitcounter = 1; | 366 | unsigned char quitcounter = 1; |
diff --git a/src/eval.c b/src/eval.c index 014905ce6df..be2af2d041b 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -2904,6 +2904,21 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args) | |||
| 2904 | } | 2904 | } |
| 2905 | } | 2905 | } |
| 2906 | 2906 | ||
| 2907 | /* Call the compiled Lisp function FUN. If we have not yet read FUN's | ||
| 2908 | bytecode string and constants vector, fetch them from the file first. */ | ||
| 2909 | |||
| 2910 | static Lisp_Object | ||
| 2911 | fetch_and_exec_byte_code (Lisp_Object fun, Lisp_Object syms_left, | ||
| 2912 | ptrdiff_t nargs, Lisp_Object *args) | ||
| 2913 | { | ||
| 2914 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | ||
| 2915 | Ffetch_bytecode (fun); | ||
| 2916 | return exec_byte_code (AREF (fun, COMPILED_BYTECODE), | ||
| 2917 | AREF (fun, COMPILED_CONSTANTS), | ||
| 2918 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 2919 | syms_left, nargs, args); | ||
| 2920 | } | ||
| 2921 | |||
| 2907 | static Lisp_Object | 2922 | static Lisp_Object |
| 2908 | apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) | 2923 | apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) |
| 2909 | { | 2924 | { |
| @@ -2968,9 +2983,6 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, | |||
| 2968 | } | 2983 | } |
| 2969 | else if (COMPILEDP (fun)) | 2984 | else if (COMPILEDP (fun)) |
| 2970 | { | 2985 | { |
| 2971 | ptrdiff_t size = PVSIZE (fun); | ||
| 2972 | if (size <= COMPILED_STACK_DEPTH) | ||
| 2973 | xsignal1 (Qinvalid_function, fun); | ||
| 2974 | syms_left = AREF (fun, COMPILED_ARGLIST); | 2986 | syms_left = AREF (fun, COMPILED_ARGLIST); |
| 2975 | if (FIXNUMP (syms_left)) | 2987 | if (FIXNUMP (syms_left)) |
| 2976 | /* A byte-code object with an integer args template means we | 2988 | /* A byte-code object with an integer args template means we |
| @@ -2982,15 +2994,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, | |||
| 2982 | argument-binding code below instead (as do all interpreted | 2994 | argument-binding code below instead (as do all interpreted |
| 2983 | functions, even lexically bound ones). */ | 2995 | functions, even lexically bound ones). */ |
| 2984 | { | 2996 | { |
| 2985 | /* If we have not actually read the bytecode string | 2997 | return fetch_and_exec_byte_code (fun, syms_left, nargs, arg_vector); |
| 2986 | and constants vector yet, fetch them from the file. */ | ||
| 2987 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | ||
| 2988 | Ffetch_bytecode (fun); | ||
| 2989 | return exec_byte_code (AREF (fun, COMPILED_BYTECODE), | ||
| 2990 | AREF (fun, COMPILED_CONSTANTS), | ||
| 2991 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 2992 | syms_left, | ||
| 2993 | nargs, arg_vector); | ||
| 2994 | } | 2998 | } |
| 2995 | lexenv = Qnil; | 2999 | lexenv = Qnil; |
| 2996 | } | 3000 | } |
| @@ -3059,16 +3063,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, | |||
| 3059 | if (CONSP (fun)) | 3063 | if (CONSP (fun)) |
| 3060 | val = Fprogn (XCDR (XCDR (fun))); | 3064 | val = Fprogn (XCDR (XCDR (fun))); |
| 3061 | else | 3065 | else |
| 3062 | { | 3066 | val = fetch_and_exec_byte_code (fun, Qnil, 0, NULL); |
| 3063 | /* If we have not actually read the bytecode string | ||
| 3064 | and constants vector yet, fetch them from the file. */ | ||
| 3065 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | ||
| 3066 | Ffetch_bytecode (fun); | ||
| 3067 | val = exec_byte_code (AREF (fun, COMPILED_BYTECODE), | ||
| 3068 | AREF (fun, COMPILED_CONSTANTS), | ||
| 3069 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 3070 | Qnil, 0, 0); | ||
| 3071 | } | ||
| 3072 | 3067 | ||
| 3073 | return unbind_to (count, val); | 3068 | return unbind_to (count, val); |
| 3074 | } | 3069 | } |
| @@ -3153,9 +3148,6 @@ lambda_arity (Lisp_Object fun) | |||
| 3153 | } | 3148 | } |
| 3154 | else if (COMPILEDP (fun)) | 3149 | else if (COMPILEDP (fun)) |
| 3155 | { | 3150 | { |
| 3156 | ptrdiff_t size = PVSIZE (fun); | ||
| 3157 | if (size <= COMPILED_STACK_DEPTH) | ||
| 3158 | xsignal1 (Qinvalid_function, fun); | ||
| 3159 | syms_left = AREF (fun, COMPILED_ARGLIST); | 3151 | syms_left = AREF (fun, COMPILED_ARGLIST); |
| 3160 | if (FIXNUMP (syms_left)) | 3152 | if (FIXNUMP (syms_left)) |
| 3161 | return get_byte_code_arity (syms_left); | 3153 | return get_byte_code_arity (syms_left); |
| @@ -3198,13 +3190,11 @@ DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode, | |||
| 3198 | 3190 | ||
| 3199 | if (COMPILEDP (object)) | 3191 | if (COMPILEDP (object)) |
| 3200 | { | 3192 | { |
| 3201 | ptrdiff_t size = PVSIZE (object); | ||
| 3202 | if (size <= COMPILED_STACK_DEPTH) | ||
| 3203 | xsignal1 (Qinvalid_function, object); | ||
| 3204 | if (CONSP (AREF (object, COMPILED_BYTECODE))) | 3193 | if (CONSP (AREF (object, COMPILED_BYTECODE))) |
| 3205 | { | 3194 | { |
| 3206 | tem = read_doc_string (AREF (object, COMPILED_BYTECODE)); | 3195 | tem = read_doc_string (AREF (object, COMPILED_BYTECODE)); |
| 3207 | if (!CONSP (tem)) | 3196 | if (! (CONSP (tem) && STRINGP (XCAR (tem)) |
| 3197 | && VECTORP (XCDR (tem)))) | ||
| 3208 | { | 3198 | { |
| 3209 | tem = AREF (object, COMPILED_BYTECODE); | 3199 | tem = AREF (object, COMPILED_BYTECODE); |
| 3210 | if (CONSP (tem) && STRINGP (XCAR (tem))) | 3200 | if (CONSP (tem) && STRINGP (XCAR (tem))) |
diff --git a/src/lisp.h b/src/lisp.h index ad7d67ae695..85bdc172b20 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -1341,7 +1341,6 @@ dead_object (void) | |||
| 1341 | #define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) | 1341 | #define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) |
| 1342 | #define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) | 1342 | #define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) |
| 1343 | #define XSETSUBR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUBR)) | 1343 | #define XSETSUBR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUBR)) |
| 1344 | #define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED)) | ||
| 1345 | #define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) | 1344 | #define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) |
| 1346 | #define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) | 1345 | #define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) |
| 1347 | #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)) | 1346 | #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)) |
| @@ -3934,7 +3933,6 @@ build_string (const char *str) | |||
| 3934 | 3933 | ||
| 3935 | extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object); | 3934 | extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object); |
| 3936 | extern Lisp_Object make_vector (ptrdiff_t, Lisp_Object); | 3935 | extern Lisp_Object make_vector (ptrdiff_t, Lisp_Object); |
| 3937 | extern void make_byte_code (struct Lisp_Vector *); | ||
| 3938 | extern struct Lisp_Vector *allocate_vector (ptrdiff_t); | 3936 | extern struct Lisp_Vector *allocate_vector (ptrdiff_t); |
| 3939 | extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t); | 3937 | extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t); |
| 3940 | 3938 | ||
diff --git a/src/lread.c b/src/lread.c index 59bf529f45c..53b4e1be2df 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -2966,8 +2966,26 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2966 | struct Lisp_Vector *vec; | 2966 | struct Lisp_Vector *vec; |
| 2967 | tmp = read_vector (readcharfun, 1); | 2967 | tmp = read_vector (readcharfun, 1); |
| 2968 | vec = XVECTOR (tmp); | 2968 | vec = XVECTOR (tmp); |
| 2969 | if (vec->header.size == 0) | 2969 | if (! (COMPILED_STACK_DEPTH < vec->header.size |
| 2970 | invalid_syntax ("Empty byte-code object"); | 2970 | && (FIXNUMP (vec->contents[COMPILED_ARGLIST]) |
| 2971 | || CONSP (vec->contents[COMPILED_ARGLIST]) | ||
| 2972 | || NILP (vec->contents[COMPILED_ARGLIST])) | ||
| 2973 | && ((STRINGP (vec->contents[COMPILED_BYTECODE]) | ||
| 2974 | && VECTORP (vec->contents[COMPILED_CONSTANTS])) | ||
| 2975 | || CONSP (vec->contents[COMPILED_BYTECODE])) | ||
| 2976 | && FIXNATP (vec->contents[COMPILED_STACK_DEPTH]))) | ||
| 2977 | invalid_syntax ("Invalid byte-code object"); | ||
| 2978 | |||
| 2979 | if (STRING_MULTIBYTE (AREF (tmp, COMPILED_BYTECODE))) | ||
| 2980 | { | ||
| 2981 | /* BYTESTR must have been produced by Emacs 20.2 or earlier | ||
| 2982 | because it produced a raw 8-bit string for byte-code and | ||
| 2983 | now such a byte-code string is loaded as multibyte with | ||
| 2984 | raw 8-bit characters converted to multibyte form. | ||
| 2985 | Convert them back to the original unibyte form. */ | ||
| 2986 | ASET (tmp, COMPILED_BYTECODE, | ||
| 2987 | Fstring_as_unibyte (AREF (tmp, COMPILED_BYTECODE))); | ||
| 2988 | } | ||
| 2971 | 2989 | ||
| 2972 | if (COMPILED_DOC_STRING < vec->header.size | 2990 | if (COMPILED_DOC_STRING < vec->header.size |
| 2973 | && EQ (AREF (tmp, COMPILED_DOC_STRING), make_fixnum (0))) | 2991 | && EQ (AREF (tmp, COMPILED_DOC_STRING), make_fixnum (0))) |
| @@ -2986,7 +3004,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2986 | ASET (tmp, COMPILED_DOC_STRING, make_ufixnum (hash)); | 3004 | ASET (tmp, COMPILED_DOC_STRING, make_ufixnum (hash)); |
| 2987 | } | 3005 | } |
| 2988 | 3006 | ||
| 2989 | make_byte_code (vec); | 3007 | XSETPVECTYPE (vec, PVEC_COMPILED); |
| 2990 | return tmp; | 3008 | return tmp; |
| 2991 | } | 3009 | } |
| 2992 | if (c == '(') | 3010 | if (c == '(') |
| @@ -3824,8 +3842,6 @@ read_vector (Lisp_Object readcharfun, bool bytecodeflag) | |||
| 3824 | { | 3842 | { |
| 3825 | Lisp_Object tem = read_list (1, readcharfun); | 3843 | Lisp_Object tem = read_list (1, readcharfun); |
| 3826 | ptrdiff_t size = list_length (tem); | 3844 | ptrdiff_t size = list_length (tem); |
| 3827 | if (bytecodeflag && size <= COMPILED_STACK_DEPTH) | ||
| 3828 | error ("Invalid byte code"); | ||
| 3829 | Lisp_Object vector = make_nil_vector (size); | 3845 | Lisp_Object vector = make_nil_vector (size); |
| 3830 | 3846 | ||
| 3831 | Lisp_Object *ptr = XVECTOR (vector)->contents; | 3847 | Lisp_Object *ptr = XVECTOR (vector)->contents; |