diff options
| author | Andrea Corallo | 2020-05-24 10:20:23 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2020-05-24 10:20:23 +0100 |
| commit | 9daffe9cfe82d3b1e1e9fa8929dbb40cfed60f0f (patch) | |
| tree | c9e78cbb4e151dc3c3996a65cf1eedab19248fb4 /src | |
| parent | f5dceed09a8234548d5b3acb76d443569533cab9 (diff) | |
| parent | e021c2dc2279e0fd3a5331f9ea661e4d39c2e840 (diff) | |
| download | emacs-9daffe9cfe82d3b1e1e9fa8929dbb40cfed60f0f.tar.gz emacs-9daffe9cfe82d3b1e1e9fa8929dbb40cfed60f0f.zip | |
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 53 | ||||
| -rw-r--r-- | src/buffer.c | 40 | ||||
| -rw-r--r-- | src/bytecode.c | 28 | ||||
| -rw-r--r-- | src/emacs.c | 5 | ||||
| -rw-r--r-- | src/eval.c | 62 | ||||
| -rw-r--r-- | src/fns.c | 51 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/lread.c | 26 | ||||
| -rw-r--r-- | src/w32.c | 12 |
9 files changed, 173 insertions, 106 deletions
diff --git a/src/alloc.c b/src/alloc.c index d6ba4d97905..76d49d2efd6 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3429,23 +3429,6 @@ usage: (vector &rest OBJECTS) */) | |||
| 3429 | return val; | 3429 | return val; |
| 3430 | } | 3430 | } |
| 3431 | 3431 | ||
| 3432 | void | ||
| 3433 | make_byte_code (struct Lisp_Vector *v) | ||
| 3434 | { | ||
| 3435 | /* Don't allow the global zero_vector to become a byte code object. */ | ||
| 3436 | eassert (0 < v->header.size); | ||
| 3437 | |||
| 3438 | if (v->header.size > 1 && STRINGP (v->contents[1]) | ||
| 3439 | && STRING_MULTIBYTE (v->contents[1])) | ||
| 3440 | /* BYTECODE-STRING must have been produced by Emacs 20.2 or the | ||
| 3441 | earlier because they produced a raw 8-bit string for byte-code | ||
| 3442 | and now such a byte-code string is loaded as multibyte while | ||
| 3443 | raw 8-bit characters converted to multibyte form. Thus, now we | ||
| 3444 | must convert them back to the original unibyte form. */ | ||
| 3445 | v->contents[1] = Fstring_as_unibyte (v->contents[1]); | ||
| 3446 | XSETPVECTYPE (v, PVEC_COMPILED); | ||
| 3447 | } | ||
| 3448 | |||
| 3449 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, | 3432 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, |
| 3450 | doc: /* Create a byte-code object with specified arguments as elements. | 3433 | doc: /* Create a byte-code object with specified arguments as elements. |
| 3451 | The arguments should be the ARGLIST, bytecode-string BYTE-CODE, constant | 3434 | The arguments should be the ARGLIST, bytecode-string BYTE-CODE, constant |
| @@ -3464,8 +3447,14 @@ stack before executing the byte-code. | |||
| 3464 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) | 3447 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) |
| 3465 | (ptrdiff_t nargs, Lisp_Object *args) | 3448 | (ptrdiff_t nargs, Lisp_Object *args) |
| 3466 | { | 3449 | { |
| 3467 | Lisp_Object val = make_uninit_vector (nargs); | 3450 | if (! ((FIXNUMP (args[COMPILED_ARGLIST]) |
| 3468 | struct Lisp_Vector *p = XVECTOR (val); | 3451 | || CONSP (args[COMPILED_ARGLIST]) |
| 3452 | || NILP (args[COMPILED_ARGLIST])) | ||
| 3453 | && STRINGP (args[COMPILED_BYTECODE]) | ||
| 3454 | && !STRING_MULTIBYTE (args[COMPILED_BYTECODE]) | ||
| 3455 | && VECTORP (args[COMPILED_CONSTANTS]) | ||
| 3456 | && FIXNATP (args[COMPILED_STACK_DEPTH]))) | ||
| 3457 | error ("Invalid byte-code object"); | ||
| 3469 | 3458 | ||
| 3470 | /* We used to purecopy everything here, if purify-flag was set. This worked | 3459 | /* We used to purecopy everything here, if purify-flag was set. This worked |
| 3471 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be | 3460 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be |
| @@ -3474,10 +3463,8 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3474 | copied into pure space, including its free variables, which is sometimes | 3463 | copied into pure space, including its free variables, which is sometimes |
| 3475 | just wasteful and other times plainly wrong (e.g. those free vars may want | 3464 | just wasteful and other times plainly wrong (e.g. those free vars may want |
| 3476 | to be setcar'd). */ | 3465 | to be setcar'd). */ |
| 3477 | 3466 | Lisp_Object val = Fvector (nargs, args); | |
| 3478 | memcpy (p->contents, args, nargs * sizeof *args); | 3467 | XSETPVECTYPE (XVECTOR (val), PVEC_COMPILED); |
| 3479 | make_byte_code (p); | ||
| 3480 | XSETCOMPILED (val, p); | ||
| 3481 | return val; | 3468 | return val; |
| 3482 | } | 3469 | } |
| 3483 | 3470 | ||
| @@ -5019,8 +5006,9 @@ mark_stack (char const *bottom, char const *end) | |||
| 5019 | #endif | 5006 | #endif |
| 5020 | } | 5007 | } |
| 5021 | 5008 | ||
| 5022 | /* This is a trampoline function that flushes registers to the stack, | 5009 | /* flush_stack_call_func is the trampoline function that flushes |
| 5023 | and then calls FUNC. ARG is passed through to FUNC verbatim. | 5010 | registers to the stack, and then calls FUNC. ARG is passed through |
| 5011 | to FUNC verbatim. | ||
| 5024 | 5012 | ||
| 5025 | This function must be called whenever Emacs is about to release the | 5013 | This function must be called whenever Emacs is about to release the |
| 5026 | global interpreter lock. This lets the garbage collector easily | 5014 | global interpreter lock. This lets the garbage collector easily |
| @@ -5028,7 +5016,20 @@ mark_stack (char const *bottom, char const *end) | |||
| 5028 | Lisp. | 5016 | Lisp. |
| 5029 | 5017 | ||
| 5030 | It is invalid to run any Lisp code or to allocate any GC memory | 5018 | It is invalid to run any Lisp code or to allocate any GC memory |
| 5031 | from FUNC. */ | 5019 | from FUNC. |
| 5020 | |||
| 5021 | Note: all register spilling is done in flush_stack_call_func before | ||
| 5022 | flush_stack_call_func1 is activated. | ||
| 5023 | |||
| 5024 | flush_stack_call_func1 is responsible for identifying the stack | ||
| 5025 | address range to be scanned. It *must* be carefully kept as | ||
| 5026 | noinline to make sure that registers has been spilled before it is | ||
| 5027 | called, otherwise given __builtin_frame_address (0) typically | ||
| 5028 | returns the frame pointer (base pointer) and not the stack pointer | ||
| 5029 | [1] GC will miss to scan callee-saved registers content | ||
| 5030 | (Bug#41357). | ||
| 5031 | |||
| 5032 | [1] <https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html>. */ | ||
| 5032 | 5033 | ||
| 5033 | NO_INLINE void | 5034 | NO_INLINE void |
| 5034 | flush_stack_call_func1 (void (*func) (void *arg), void *arg) | 5035 | flush_stack_call_func1 (void (*func) (void *arg), void *arg) |
diff --git a/src/buffer.c b/src/buffer.c index 53b3bd960c4..f1cb4d50414 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -119,6 +119,7 @@ static void free_buffer_text (struct buffer *b); | |||
| 119 | static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *); | 119 | static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *); |
| 120 | static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t); | 120 | static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t); |
| 121 | static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool); | 121 | static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool); |
| 122 | static Lisp_Object buffer_local_variables_1 (struct buffer *buf, int offset, Lisp_Object sym); | ||
| 122 | 123 | ||
| 123 | static void | 124 | static void |
| 124 | CHECK_OVERLAY (Lisp_Object x) | 125 | CHECK_OVERLAY (Lisp_Object x) |
| @@ -1300,6 +1301,25 @@ buffer_lisp_local_variables (struct buffer *buf, bool clone) | |||
| 1300 | return result; | 1301 | return result; |
| 1301 | } | 1302 | } |
| 1302 | 1303 | ||
| 1304 | |||
| 1305 | /* If the variable at position index OFFSET in buffer BUF has a | ||
| 1306 | buffer-local value, return (name . value). If SYM is non-nil, | ||
| 1307 | it replaces name. */ | ||
| 1308 | |||
| 1309 | static Lisp_Object | ||
| 1310 | buffer_local_variables_1 (struct buffer *buf, int offset, Lisp_Object sym) | ||
| 1311 | { | ||
| 1312 | int idx = PER_BUFFER_IDX (offset); | ||
| 1313 | if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx)) | ||
| 1314 | && SYMBOLP (PER_BUFFER_SYMBOL (offset))) | ||
| 1315 | { | ||
| 1316 | sym = NILP (sym) ? PER_BUFFER_SYMBOL (offset) : sym; | ||
| 1317 | Lisp_Object val = per_buffer_value (buf, offset); | ||
| 1318 | return EQ (val, Qunbound) ? sym : Fcons (sym, val); | ||
| 1319 | } | ||
| 1320 | return Qnil; | ||
| 1321 | } | ||
| 1322 | |||
| 1303 | DEFUN ("buffer-local-variables", Fbuffer_local_variables, | 1323 | DEFUN ("buffer-local-variables", Fbuffer_local_variables, |
| 1304 | Sbuffer_local_variables, 0, 1, 0, | 1324 | Sbuffer_local_variables, 0, 1, 0, |
| 1305 | doc: /* Return an alist of variables that are buffer-local in BUFFER. | 1325 | doc: /* Return an alist of variables that are buffer-local in BUFFER. |
| @@ -1311,25 +1331,25 @@ No argument or nil as argument means use current buffer as BUFFER. */) | |||
| 1311 | { | 1331 | { |
| 1312 | struct buffer *buf = decode_buffer (buffer); | 1332 | struct buffer *buf = decode_buffer (buffer); |
| 1313 | Lisp_Object result = buffer_lisp_local_variables (buf, 0); | 1333 | Lisp_Object result = buffer_lisp_local_variables (buf, 0); |
| 1334 | Lisp_Object tem; | ||
| 1314 | 1335 | ||
| 1315 | /* Add on all the variables stored in special slots. */ | 1336 | /* Add on all the variables stored in special slots. */ |
| 1316 | { | 1337 | { |
| 1317 | int offset, idx; | 1338 | int offset; |
| 1318 | 1339 | ||
| 1319 | FOR_EACH_PER_BUFFER_OBJECT_AT (offset) | 1340 | FOR_EACH_PER_BUFFER_OBJECT_AT (offset) |
| 1320 | { | 1341 | { |
| 1321 | idx = PER_BUFFER_IDX (offset); | 1342 | tem = buffer_local_variables_1 (buf, offset, Qnil); |
| 1322 | if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx)) | 1343 | if (!NILP (tem)) |
| 1323 | && SYMBOLP (PER_BUFFER_SYMBOL (offset))) | 1344 | result = Fcons (tem, result); |
| 1324 | { | ||
| 1325 | Lisp_Object sym = PER_BUFFER_SYMBOL (offset); | ||
| 1326 | Lisp_Object val = per_buffer_value (buf, offset); | ||
| 1327 | result = Fcons (EQ (val, Qunbound) ? sym : Fcons (sym, val), | ||
| 1328 | result); | ||
| 1329 | } | ||
| 1330 | } | 1345 | } |
| 1331 | } | 1346 | } |
| 1332 | 1347 | ||
| 1348 | tem = buffer_local_variables_1 (buf, PER_BUFFER_VAR_OFFSET (undo_list), | ||
| 1349 | intern ("buffer-undo-list")); | ||
| 1350 | if (!NILP (tem)) | ||
| 1351 | result = Fcons (tem, result); | ||
| 1352 | |||
| 1333 | return result; | 1353 | return result; |
| 1334 | } | 1354 | } |
| 1335 | 1355 | ||
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/emacs.c b/src/emacs.c index e75cb588349..93a837a44ef 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -124,6 +124,11 @@ static const char emacs_version[] = PACKAGE_VERSION; | |||
| 124 | static const char emacs_copyright[] = COPYRIGHT; | 124 | static const char emacs_copyright[] = COPYRIGHT; |
| 125 | static const char emacs_bugreport[] = PACKAGE_BUGREPORT; | 125 | static const char emacs_bugreport[] = PACKAGE_BUGREPORT; |
| 126 | 126 | ||
| 127 | /* Put version info into the executable in the form that 'ident' uses. */ | ||
| 128 | char const EXTERNALLY_VISIBLE RCS_Id[] | ||
| 129 | = "$Id" ": GNU Emacs " PACKAGE_VERSION | ||
| 130 | " (" EMACS_CONFIGURATION " " EMACS_CONFIG_FEATURES ") $"; | ||
| 131 | |||
| 127 | /* Empty lisp strings. To avoid having to build any others. */ | 132 | /* Empty lisp strings. To avoid having to build any others. */ |
| 128 | Lisp_Object empty_unibyte_string, empty_multibyte_string; | 133 | Lisp_Object empty_unibyte_string, empty_multibyte_string; |
| 129 | 134 | ||
diff --git a/src/eval.c b/src/eval.c index 1091b082552..37d466f69ed 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -2913,6 +2913,21 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args) | |||
| 2913 | } | 2913 | } |
| 2914 | } | 2914 | } |
| 2915 | 2915 | ||
| 2916 | /* Call the compiled Lisp function FUN. If we have not yet read FUN's | ||
| 2917 | bytecode string and constants vector, fetch them from the file first. */ | ||
| 2918 | |||
| 2919 | static Lisp_Object | ||
| 2920 | fetch_and_exec_byte_code (Lisp_Object fun, Lisp_Object syms_left, | ||
| 2921 | ptrdiff_t nargs, Lisp_Object *args) | ||
| 2922 | { | ||
| 2923 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | ||
| 2924 | Ffetch_bytecode (fun); | ||
| 2925 | return exec_byte_code (AREF (fun, COMPILED_BYTECODE), | ||
| 2926 | AREF (fun, COMPILED_CONSTANTS), | ||
| 2927 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 2928 | syms_left, nargs, args); | ||
| 2929 | } | ||
| 2930 | |||
| 2916 | static Lisp_Object | 2931 | static Lisp_Object |
| 2917 | apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) | 2932 | apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) |
| 2918 | { | 2933 | { |
| @@ -2977,9 +2992,6 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, | |||
| 2977 | } | 2992 | } |
| 2978 | else if (COMPILEDP (fun)) | 2993 | else if (COMPILEDP (fun)) |
| 2979 | { | 2994 | { |
| 2980 | ptrdiff_t size = PVSIZE (fun); | ||
| 2981 | if (size <= COMPILED_STACK_DEPTH) | ||
| 2982 | xsignal1 (Qinvalid_function, fun); | ||
| 2983 | syms_left = AREF (fun, COMPILED_ARGLIST); | 2995 | syms_left = AREF (fun, COMPILED_ARGLIST); |
| 2984 | if (FIXNUMP (syms_left)) | 2996 | if (FIXNUMP (syms_left)) |
| 2985 | /* A byte-code object with an integer args template means we | 2997 | /* A byte-code object with an integer args template means we |
| @@ -2991,15 +3003,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, | |||
| 2991 | argument-binding code below instead (as do all interpreted | 3003 | argument-binding code below instead (as do all interpreted |
| 2992 | functions, even lexically bound ones). */ | 3004 | functions, even lexically bound ones). */ |
| 2993 | { | 3005 | { |
| 2994 | /* If we have not actually read the bytecode string | 3006 | return fetch_and_exec_byte_code (fun, syms_left, nargs, arg_vector); |
| 2995 | and constants vector yet, fetch them from the file. */ | ||
| 2996 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | ||
| 2997 | Ffetch_bytecode (fun); | ||
| 2998 | return exec_byte_code (AREF (fun, COMPILED_BYTECODE), | ||
| 2999 | AREF (fun, COMPILED_CONSTANTS), | ||
| 3000 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 3001 | syms_left, | ||
| 3002 | nargs, arg_vector); | ||
| 3003 | } | 3007 | } |
| 3004 | lexenv = Qnil; | 3008 | lexenv = Qnil; |
| 3005 | } | 3009 | } |
| @@ -3068,16 +3072,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, | |||
| 3068 | if (CONSP (fun)) | 3072 | if (CONSP (fun)) |
| 3069 | val = Fprogn (XCDR (XCDR (fun))); | 3073 | val = Fprogn (XCDR (XCDR (fun))); |
| 3070 | else | 3074 | else |
| 3071 | { | 3075 | val = fetch_and_exec_byte_code (fun, Qnil, 0, NULL); |
| 3072 | /* If we have not actually read the bytecode string | ||
| 3073 | and constants vector yet, fetch them from the file. */ | ||
| 3074 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | ||
| 3075 | Ffetch_bytecode (fun); | ||
| 3076 | val = exec_byte_code (AREF (fun, COMPILED_BYTECODE), | ||
| 3077 | AREF (fun, COMPILED_CONSTANTS), | ||
| 3078 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 3079 | Qnil, 0, 0); | ||
| 3080 | } | ||
| 3081 | 3076 | ||
| 3082 | return unbind_to (count, val); | 3077 | return unbind_to (count, val); |
| 3083 | } | 3078 | } |
| @@ -3162,9 +3157,6 @@ lambda_arity (Lisp_Object fun) | |||
| 3162 | } | 3157 | } |
| 3163 | else if (COMPILEDP (fun)) | 3158 | else if (COMPILEDP (fun)) |
| 3164 | { | 3159 | { |
| 3165 | ptrdiff_t size = PVSIZE (fun); | ||
| 3166 | if (size <= COMPILED_STACK_DEPTH) | ||
| 3167 | xsignal1 (Qinvalid_function, fun); | ||
| 3168 | syms_left = AREF (fun, COMPILED_ARGLIST); | 3160 | syms_left = AREF (fun, COMPILED_ARGLIST); |
| 3169 | if (FIXNUMP (syms_left)) | 3161 | if (FIXNUMP (syms_left)) |
| 3170 | return get_byte_code_arity (syms_left); | 3162 | return get_byte_code_arity (syms_left); |
| @@ -3207,13 +3199,11 @@ DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode, | |||
| 3207 | 3199 | ||
| 3208 | if (COMPILEDP (object)) | 3200 | if (COMPILEDP (object)) |
| 3209 | { | 3201 | { |
| 3210 | ptrdiff_t size = PVSIZE (object); | ||
| 3211 | if (size <= COMPILED_STACK_DEPTH) | ||
| 3212 | xsignal1 (Qinvalid_function, object); | ||
| 3213 | if (CONSP (AREF (object, COMPILED_BYTECODE))) | 3202 | if (CONSP (AREF (object, COMPILED_BYTECODE))) |
| 3214 | { | 3203 | { |
| 3215 | tem = read_doc_string (AREF (object, COMPILED_BYTECODE)); | 3204 | tem = read_doc_string (AREF (object, COMPILED_BYTECODE)); |
| 3216 | if (!CONSP (tem)) | 3205 | if (! (CONSP (tem) && STRINGP (XCAR (tem)) |
| 3206 | && VECTORP (XCDR (tem)))) | ||
| 3217 | { | 3207 | { |
| 3218 | tem = AREF (object, COMPILED_BYTECODE); | 3208 | tem = AREF (object, COMPILED_BYTECODE); |
| 3219 | if (CONSP (tem) && STRINGP (XCAR (tem))) | 3209 | if (CONSP (tem) && STRINGP (XCAR (tem))) |
| @@ -3221,7 +3211,19 @@ DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode, | |||
| 3221 | else | 3211 | else |
| 3222 | error ("Invalid byte code"); | 3212 | error ("Invalid byte code"); |
| 3223 | } | 3213 | } |
| 3224 | ASET (object, COMPILED_BYTECODE, XCAR (tem)); | 3214 | |
| 3215 | Lisp_Object bytecode = XCAR (tem); | ||
| 3216 | if (STRING_MULTIBYTE (bytecode)) | ||
| 3217 | { | ||
| 3218 | /* BYTECODE must have been produced by Emacs 20.2 or earlier | ||
| 3219 | because it produced a raw 8-bit string for byte-code and now | ||
| 3220 | such a byte-code string is loaded as multibyte with raw 8-bit | ||
| 3221 | characters converted to multibyte form. Convert them back to | ||
| 3222 | the original unibyte form. */ | ||
| 3223 | bytecode = Fstring_as_unibyte (bytecode); | ||
| 3224 | } | ||
| 3225 | |||
| 3226 | ASET (object, COMPILED_BYTECODE, bytecode); | ||
| 3225 | ASET (object, COMPILED_CONSTANTS, XCDR (tem)); | 3227 | ASET (object, COMPILED_CONSTANTS, XCDR (tem)); |
| 3226 | } | 3228 | } |
| 3227 | } | 3229 | } |
| @@ -2508,26 +2508,36 @@ ARRAY is a vector, string, char-table, or bool-vector. */) | |||
| 2508 | } | 2508 | } |
| 2509 | else if (STRINGP (array)) | 2509 | else if (STRINGP (array)) |
| 2510 | { | 2510 | { |
| 2511 | register unsigned char *p = SDATA (array); | 2511 | unsigned char *p = SDATA (array); |
| 2512 | int charval; | ||
| 2513 | CHECK_CHARACTER (item); | 2512 | CHECK_CHARACTER (item); |
| 2514 | charval = XFIXNAT (item); | 2513 | int charval = XFIXNAT (item); |
| 2515 | size = SCHARS (array); | 2514 | size = SCHARS (array); |
| 2516 | if (STRING_MULTIBYTE (array)) | 2515 | if (size != 0) |
| 2517 | { | 2516 | { |
| 2517 | CHECK_IMPURE (array, XSTRING (array)); | ||
| 2518 | unsigned char str[MAX_MULTIBYTE_LENGTH]; | 2518 | unsigned char str[MAX_MULTIBYTE_LENGTH]; |
| 2519 | int len = CHAR_STRING (charval, str); | 2519 | int len; |
| 2520 | ptrdiff_t size_byte = SBYTES (array); | 2520 | if (STRING_MULTIBYTE (array)) |
| 2521 | ptrdiff_t product; | 2521 | len = CHAR_STRING (charval, str); |
| 2522 | else | ||
| 2523 | { | ||
| 2524 | str[0] = charval; | ||
| 2525 | len = 1; | ||
| 2526 | } | ||
| 2522 | 2527 | ||
| 2523 | if (INT_MULTIPLY_WRAPV (size, len, &product) || product != size_byte) | 2528 | ptrdiff_t size_byte = SBYTES (array); |
| 2524 | error ("Attempt to change byte length of a string"); | 2529 | if (len == 1 && size == size_byte) |
| 2525 | for (idx = 0; idx < size_byte; idx++) | 2530 | memset (p, str[0], size); |
| 2526 | *p++ = str[idx % len]; | 2531 | else |
| 2532 | { | ||
| 2533 | ptrdiff_t product; | ||
| 2534 | if (INT_MULTIPLY_WRAPV (size, len, &product) | ||
| 2535 | || product != size_byte) | ||
| 2536 | error ("Attempt to change byte length of a string"); | ||
| 2537 | for (idx = 0; idx < size_byte; idx++) | ||
| 2538 | *p++ = str[idx % len]; | ||
| 2539 | } | ||
| 2527 | } | 2540 | } |
| 2528 | else | ||
| 2529 | for (idx = 0; idx < size; idx++) | ||
| 2530 | p[idx] = charval; | ||
| 2531 | } | 2541 | } |
| 2532 | else if (BOOL_VECTOR_P (array)) | 2542 | else if (BOOL_VECTOR_P (array)) |
| 2533 | return bool_vector_fill (array, item); | 2543 | return bool_vector_fill (array, item); |
| @@ -2542,12 +2552,15 @@ DEFUN ("clear-string", Fclear_string, Sclear_string, | |||
| 2542 | This makes STRING unibyte and may change its length. */) | 2552 | This makes STRING unibyte and may change its length. */) |
| 2543 | (Lisp_Object string) | 2553 | (Lisp_Object string) |
| 2544 | { | 2554 | { |
| 2545 | ptrdiff_t len; | ||
| 2546 | CHECK_STRING (string); | 2555 | CHECK_STRING (string); |
| 2547 | len = SBYTES (string); | 2556 | ptrdiff_t len = SBYTES (string); |
| 2548 | memset (SDATA (string), 0, len); | 2557 | if (len != 0 || STRING_MULTIBYTE (string)) |
| 2549 | STRING_SET_CHARS (string, len); | 2558 | { |
| 2550 | STRING_SET_UNIBYTE (string); | 2559 | CHECK_IMPURE (string, XSTRING (string)); |
| 2560 | memset (SDATA (string), 0, len); | ||
| 2561 | STRING_SET_CHARS (string, len); | ||
| 2562 | STRING_SET_UNIBYTE (string); | ||
| 2563 | } | ||
| 2551 | return Qnil; | 2564 | return Qnil; |
| 2552 | } | 2565 | } |
| 2553 | 2566 | ||
diff --git a/src/lisp.h b/src/lisp.h index 9e4d53ccf17..4c0057b2552 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -1343,7 +1343,6 @@ dead_object (void) | |||
| 1343 | #define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) | 1343 | #define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) |
| 1344 | #define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) | 1344 | #define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) |
| 1345 | #define XSETSUBR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUBR)) | 1345 | #define XSETSUBR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUBR)) |
| 1346 | #define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED)) | ||
| 1347 | #define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) | 1346 | #define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) |
| 1348 | #define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) | 1347 | #define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) |
| 1349 | #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)) | 1348 | #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)) |
| @@ -3943,7 +3942,6 @@ build_string (const char *str) | |||
| 3943 | 3942 | ||
| 3944 | extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object); | 3943 | extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object); |
| 3945 | extern Lisp_Object make_vector (ptrdiff_t, Lisp_Object); | 3944 | extern Lisp_Object make_vector (ptrdiff_t, Lisp_Object); |
| 3946 | extern void make_byte_code (struct Lisp_Vector *); | ||
| 3947 | extern struct Lisp_Vector *allocate_vector (ptrdiff_t); | 3945 | extern struct Lisp_Vector *allocate_vector (ptrdiff_t); |
| 3948 | extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t); | 3946 | extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t); |
| 3949 | 3947 | ||
diff --git a/src/lread.c b/src/lread.c index 01f359ca581..46725d9b0ff 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -3030,8 +3030,26 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 3030 | struct Lisp_Vector *vec; | 3030 | struct Lisp_Vector *vec; |
| 3031 | tmp = read_vector (readcharfun, 1); | 3031 | tmp = read_vector (readcharfun, 1); |
| 3032 | vec = XVECTOR (tmp); | 3032 | vec = XVECTOR (tmp); |
| 3033 | if (vec->header.size == 0) | 3033 | if (! (COMPILED_STACK_DEPTH < vec->header.size |
| 3034 | invalid_syntax ("Empty byte-code object"); | 3034 | && (FIXNUMP (vec->contents[COMPILED_ARGLIST]) |
| 3035 | || CONSP (vec->contents[COMPILED_ARGLIST]) | ||
| 3036 | || NILP (vec->contents[COMPILED_ARGLIST])) | ||
| 3037 | && ((STRINGP (vec->contents[COMPILED_BYTECODE]) | ||
| 3038 | && VECTORP (vec->contents[COMPILED_CONSTANTS])) | ||
| 3039 | || CONSP (vec->contents[COMPILED_BYTECODE])) | ||
| 3040 | && FIXNATP (vec->contents[COMPILED_STACK_DEPTH]))) | ||
| 3041 | invalid_syntax ("Invalid byte-code object"); | ||
| 3042 | |||
| 3043 | if (STRING_MULTIBYTE (AREF (tmp, COMPILED_BYTECODE))) | ||
| 3044 | { | ||
| 3045 | /* BYTESTR must have been produced by Emacs 20.2 or earlier | ||
| 3046 | because it produced a raw 8-bit string for byte-code and | ||
| 3047 | now such a byte-code string is loaded as multibyte with | ||
| 3048 | raw 8-bit characters converted to multibyte form. | ||
| 3049 | Convert them back to the original unibyte form. */ | ||
| 3050 | ASET (tmp, COMPILED_BYTECODE, | ||
| 3051 | Fstring_as_unibyte (AREF (tmp, COMPILED_BYTECODE))); | ||
| 3052 | } | ||
| 3035 | 3053 | ||
| 3036 | if (COMPILED_DOC_STRING < vec->header.size | 3054 | if (COMPILED_DOC_STRING < vec->header.size |
| 3037 | && EQ (AREF (tmp, COMPILED_DOC_STRING), make_fixnum (0))) | 3055 | && EQ (AREF (tmp, COMPILED_DOC_STRING), make_fixnum (0))) |
| @@ -3050,7 +3068,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 3050 | ASET (tmp, COMPILED_DOC_STRING, make_ufixnum (hash)); | 3068 | ASET (tmp, COMPILED_DOC_STRING, make_ufixnum (hash)); |
| 3051 | } | 3069 | } |
| 3052 | 3070 | ||
| 3053 | make_byte_code (vec); | 3071 | XSETPVECTYPE (vec, PVEC_COMPILED); |
| 3054 | return tmp; | 3072 | return tmp; |
| 3055 | } | 3073 | } |
| 3056 | if (c == '(') | 3074 | if (c == '(') |
| @@ -3888,8 +3906,6 @@ read_vector (Lisp_Object readcharfun, bool bytecodeflag) | |||
| 3888 | { | 3906 | { |
| 3889 | Lisp_Object tem = read_list (1, readcharfun); | 3907 | Lisp_Object tem = read_list (1, readcharfun); |
| 3890 | ptrdiff_t size = list_length (tem); | 3908 | ptrdiff_t size = list_length (tem); |
| 3891 | if (bytecodeflag && size <= COMPILED_STACK_DEPTH) | ||
| 3892 | error ("Invalid byte code"); | ||
| 3893 | Lisp_Object vector = make_nil_vector (size); | 3909 | Lisp_Object vector = make_nil_vector (size); |
| 3894 | 3910 | ||
| 3895 | Lisp_Object *ptr = XVECTOR (vector)->contents; | 3911 | Lisp_Object *ptr = XVECTOR (vector)->contents; |
| @@ -6519,7 +6519,15 @@ acl_get_file (const char *fname, acl_type_t type) | |||
| 6519 | if (!get_file_security (fname, si, psd, sd_len, &sd_len)) | 6519 | if (!get_file_security (fname, si, psd, sd_len, &sd_len)) |
| 6520 | { | 6520 | { |
| 6521 | xfree (psd); | 6521 | xfree (psd); |
| 6522 | errno = EIO; | 6522 | err = GetLastError (); |
| 6523 | if (err == ERROR_NOT_SUPPORTED) | ||
| 6524 | errno = ENOTSUP; | ||
| 6525 | else if (err == ERROR_FILE_NOT_FOUND | ||
| 6526 | || err == ERROR_PATH_NOT_FOUND | ||
| 6527 | || err == ERROR_INVALID_NAME) | ||
| 6528 | errno = ENOENT; | ||
| 6529 | else | ||
| 6530 | errno = EIO; | ||
| 6523 | psd = NULL; | 6531 | psd = NULL; |
| 6524 | } | 6532 | } |
| 6525 | } | 6533 | } |
| @@ -6530,6 +6538,8 @@ acl_get_file (const char *fname, acl_type_t type) | |||
| 6530 | be encoded in the current ANSI codepage. */ | 6538 | be encoded in the current ANSI codepage. */ |
| 6531 | || err == ERROR_INVALID_NAME) | 6539 | || err == ERROR_INVALID_NAME) |
| 6532 | errno = ENOENT; | 6540 | errno = ENOENT; |
| 6541 | else if (err == ERROR_NOT_SUPPORTED) | ||
| 6542 | errno = ENOTSUP; | ||
| 6533 | else | 6543 | else |
| 6534 | errno = EIO; | 6544 | errno = EIO; |
| 6535 | } | 6545 | } |