* lisp/emacs-lisp/comp-cstr.el (comp-cstr-set-cmp-range)
(comp-cstr->, comp-cstr->=, comp-cstr-<, comp-cstr-<=): New
functions.
* lisp/emacs-lisp/comp.el (comp-equality-fun-p)
(comp-range-cmp-fun-p): New functions.
(comp-collect-rhs): Use `comp-assign-op-p' in place of
`comp-set-op-p'.
(comp-negate-range-cmp-fun, comp-reverse-cmp-fun): New functions.
(comp-emit-assume): Rework to be able to emit also comparision
assumption.
(comp-add-cond-cstrs-simple): Update for new `comp-emit-assume'.
(comp-add-cond-cstrs-simple): Update to emit range assumption.
(comp-fwprop-insn): Execute range assumptions.
* test/src/comp-tests.el (comp-tests-type-spec-tests): Add tests.
Such filenames are dangerous, as Emacs would silently only use the
part up to the first NUL byte. Reject them explicitly instead.
* src/coding.c (encode_file_name_1): New helper function.
(encode_file_name): Check that encoded filename doesn't contain a
NUL byte.
(syms_of_coding): Define 'filenamep' symbol.
* test/src/fileio-tests.el (fileio-tests/null-character): New unit
test.
* etc/NEWS: Document change.
* lisp/emacs-lisp/comp.el (comp-add-call-cstr): Fix it.
* test/src/comp-tests.el (assume-in-loop-1): New test.
* test/src/comp-test-funcs.el (comp-test-assume-in-loop-1-f): New
function.
* lisp/emacs-lisp/comp.el (comp-fwprop-insn): Do not propagate in
case of double negation.
* test/src/comp-test-funcs.el (comp-test-assume-double-neg-f):
New function.
* test/src/comp-tests.el (assume-double-neg): New test.
* lisp/emacs-lisp/comp.el: Add some commentary.
(comp-cond-cstrs-target-mvar): Rename and update docstring.
(comp-add-cond-cstrs): Update to use
`comp-cond-cstrs-target-mvar'.
(comp-emit-call-cstr, comp-lambda-list-gen, comp-add-call-cstr):
New functions.
(comp-add-cstrs): Call `comp-add-call-cstr'.
* test/src/comp-tests.el (comp-tests-type-spec-tests): Update two
type specifier tests.
* test/src/comp-tests.el (comp-tests-type-spec-tests): Enumerate.
(comp-tests-define-type-spec-test): New function.
(comp-tests-define-type-spec-tests): New macro to expand tests.
* lisp/emacs-lisp/comp.el (comp-final): Escape multibyte string
when offloading compilation to child process.
* test/src/comp-test-funcs.el (comp-test-45342-f): New function
* test/src/comp-tests.el (bug-45342): New test
Give get-buffer-create an optional argument to inhibit buffer hooks
in internal or temporary buffers for efficiency (bug#34765).
* etc/NEWS: Announce new parameter of get-buffer-create and
generate-new-buffer, and that with-temp-buffer and with-temp-file
now inhibit buffer hooks.
* doc/lispref/buffers.texi (Buffer Names): Fix typo.
(Creating Buffers): Document new parameter of get-buffer-create and
generate-new-buffer.
(Buffer List, Killing Buffers): Document when buffer hooks are
inhibited.
(Current Buffer):
* doc/lispref/files.texi (Writing to Files): Document that
with-temp-buffer and with-temp-file inhibit buffer hooks.
* doc/lispref/internals.texi (Buffer Internals): Document
inhibit_buffer_hooks flag. Remove stale comment.
* doc/misc/gnus-faq.texi (FAQ 5-8):
* lisp/simple.el (shell-command-on-region): Fix indentation.
* lisp/files.el (kill-buffer-hook): Document when hook is inhibited.
(create-file-buffer):
* lisp/gnus/gnus-uu.el (gnus-uu-unshar-article):
* lisp/international/mule.el (load-with-code-conversion):
* lisp/mh-e/mh-xface.el (mh-x-image-url-fetch-image):
* lisp/net/imap.el (imap-open):
* lisp/net/mailcap.el (mailcap-maybe-eval):
* lisp/progmodes/flymake-proc.el
(flymake-proc--read-file-to-temp-buffer)
(flymake-proc--copy-buffer-to-temp-buffer): Simplify.
* lisp/subr.el (generate-new-buffer): Forward new optional argument
to inhibit buffer hooks to get-buffer-create.
(with-temp-file, with-temp-buffer, with-output-to-string):
* lisp/json.el (json-encode-string): Inhibit buffer hooks in buffer
used.
* src/buffer.c (run_buffer_list_update_hook): New helper function.
(Fget_buffer_create): Use it. Add optional argument to set
inhibit_buffer_hooks flag instead of comparing the buffer name to
Vcode_conversion_workbuf_name. All callers changed.
(Fmake_indirect_buffer, Frename_buffer, Fbury_buffer_internal)
(record_buffer): Use run_buffer_list_update_hook.
(Fkill_buffer): Document when buffer hooks are inhibited. Use
run_buffer_list_update_hook.
(init_buffer_once): Inhibit buffer hooks in Vprin1_to_string_buffer.
(Vkill_buffer_query_functions, Vbuffer_list_update_hook): Document
when hooks are inhibited.
* src/buffer.h (struct buffer): Update inhibit_buffer_hooks
commentary.
* src/coding.h (Vcode_conversion_workbuf_name):
* src/coding.c (Vcode_conversion_workbuf_name): Make static again
since it is no longer needed in src/buffer.c.
(code_conversion_restore, code_conversion_save, syms_of_coding):
Prefer boolean over integer constants.
* src/fileio.c (Finsert_file_contents): Inhibit buffer hooks in
" *code-converting-work*" buffer.
* src/window.c (Fselect_window): Fix grammar. Mention
window-selection-change-functions alongside buffer-list-update-hook.
* test/src/buffer-tests.el: Fix requires.
(buffer-tests-inhibit-buffer-hooks): New test.
This runs insignificantly faster in C, and is already fast enough on
reasonably modern hardware. We might as well lift it to Lisp.
This benchmark can be used to verify:
(benchmark-run 10 (apropos-command "test"))
=> (0.12032415399999999 2 0.014772391999999995) ; C
=> (0.13513192100000002 2 0.017216643000000004) ; Lisp
* lisp/subr.el (apropos-internal): New defun, converted from C.
* src/keymap.c (Fapropos_internal): Remove defun.
(apropos_accum): Remove function.
(apropos_predicate, apropos_accumulate): Remove variables.
(syms_of_keymap): Remove defsubr for Fapropos_internal, and
definitions of the above variables.
* test/src/keymap-tests.el (keymap-apropos-internal)
(keymap-apropos-internal/predicate): Move tests from here...
* test/lisp/subr-tests.el (apropos-apropos-internal)
(apropos-apropos-internal/predicate): ...to here.
When creating multibyte or unibyte strings, we should guarantee the
following invariants:
- When creating empty strings, a NULL data pointer should be allowed.
This often arises in practice if the string length isn't known in
advance, and we don't want to unnecessarily trigger undefined
behavior. Since functions like memcpy might not accept NULL
pointers, use the canonical empty string objects in this case.
- Nonzero strings should be guaranteed to be unique and mutable.
These are the same guarantees expected from Lisp functions such as
'make-string' or 'unibyte-string'. On the other hand, empty strings
might not be unique.
* src/emacs-module.c (module_make_string)
(module_make_unibyte_string): Correctly handle empty strings.
* test/src/emacs-module-resources/mod-test.c (Fmod_test_make_string):
New test function.
(emacs_module_init): Expose it.
* test/src/emacs-module-tests.el (mod-test-make-string/empty)
(mod-test-make-string/nonempty): New unit tests.
* doc/lispref/internals.texi (Module Values): Document properties and
corner cases for strings.
* test/src/casefiddle-tests.el (casefiddle-tests-char-casing):
(upcase ?ß) now returns ?ẞ (U+7838), partly for technical reasons but
the previous behaviour was arbitrary and arguably less useful.
Correct upcasing of ß is normally SS, which is what Fupcase returns if
given a string, or (for special purposes) ẞ.
ß was incorrectly treated as a caseless character and thus not matched
by the regexp [[:lower:]] (or, in case-folding mode, [[:upper:]]).
The reason is that the upcase table maps it to itself, which can be
remedied by mapping it to ẞ (U+7838) instead. Doing so does not
affect upcasing since the special-uppercase property maps it to SS.
* lisp/international/characters.el (tbl): Map ß to ẞ in the upcase
table.
* test/src/regex-emacs-tests.el (regexp-eszett): Uncomment previously
failing tests. Add checks to make sure that case transformations
remain valid.
* src/regex-emacs.c (execute_charset): Add canon_table argument to
allow expression of a correct predicate for [:upper:] and [:lower:].
(mutually_exclusive_p, re_match_2_internal): Pass extra argument.
* test/src/regex-emacs-tests.el (regexp-case-fold, regexp-eszett):
New tests. Parts of regexp-eszett still fail and are commented out.
* src/eval.c (syms_of_eval): Define new variable
'backtrace-on-error-noninteractive' to selectively enable backtrace
printing in batch mode.
(signal_or_quit): Use it.
* etc/NEWS: Document new variable.
* test/src/eval-tests.el (eval-tests/backtrace-in-batch-mode/inhibit):
New unit test.
* src/eval.c (signal_or_quit): Print a backtrace in batch mode if no
error handler was found.
* test/src/eval-tests.el (eval-tests/backtrace-in-batch-mode)
(eval-tests/backtrace-in-batch-mode/demoted-errors): New unit tests.
* etc/NEWS: Document change.
* lisp/emacs-lisp/comp.el (comp-mvar-symbol-p): As all slots into
a `comp-cstr' are in or fix this logic.
(comp-mvar-cons-p): Likewise.
* test/src/comp-tests.el (bug-44968): New testcase.
* test/src/comp-test-funcs.el (comp-test-44968-f): New test
function.
We used to store module runtime and environment pointers in the static
lists Vmodule_runtimes and Vmodule_environments. However, this is
incorrect because these objects have to be kept per-thread. With this
naive approach, interleaving module function calls in separate threads
leads to environments being removed in the wrong order, which in turn
can cause local module values to be incorrectly garbage-collected.
The fix isn't completely trivial: specbinding the lists wouldn't work
either, because then the garbage collector wouldn't find the
environments in other threads than the current ones, again leading to
objects being garbage-collected incorrectly. While introducing custom
pseudovector types would fix this, it's simpler to put the runtime and
environment pointers into the specbinding list as new specbinding
kinds. This works since we need to unwind them anyway, and we only
ever treat the lists as a stack. The thread switching machinery
ensures that the specbinding lists are thread-local, and that all
elements of the specbinding lists in all threads are marked during
garbage collection.
Module assertions now have to walk the specbinding list for the
current thread, which is more correct since they now only find
environments for the current thread. As a result, we can now remove
the faulty Vmodule_runtimes and Vmodule_environments variables
entirely.
Also add a unit test that exemplifies the problem. It interleaves two
module calls in two threads so that the first call ends while the
second one is still active. Without this change, this test triggers
an assertion failure.
* src/lisp.h (enum specbind_tag): Add new tags for module runtimes and
environments.
* src/eval.c (record_unwind_protect_module): New function to record a
module object in the specpdl list.
(do_one_unbind): Unwind module objects.
(backtrace_eval_unrewind, default_toplevel_binding, lexbound_p)
(Fbacktrace__locals): Deal with new specbinding types.
(mark_specpdl): Mark module environments as needed.
* src/alloc.c (garbage_collect): Remove call to 'mark-modules'.
Garbage collection of module values is now handled as part of marking
the specpdl of each thread.
* src/emacs-module.c (Fmodule_load, funcall_module): Use specpdl to
record module runtimes and environments.
(module_assert_runtime, module_assert_env, value_to_lisp): Walk
through specpdl list instead of list variables.
(mark_module_environment): Rename from 'mark_modules'. Don't attempt
to walk though current thread's environments only, since that would
miss other threads.
(initialize_environment, finalize_environment): Don't change
Vmodule_environments variable; environments are now in the specpdl
list.
(finalize_environment_unwind, finalize_runtime_unwind): Make 'extern'
since do_one_unbind now calls them.
(finalize_runtime_unwind): Don't change Vmodule_runtimes variable;
runtimes are now in the specpdl list.
(syms_of_module): Remove Vmodule_runtimes and Vmodule_environments.
* test/data/emacs-module/mod-test.c (Fmod_test_funcall): New test
function.
(emacs_module_init): Bind it.
* test/src/emacs-module-tests.el (emacs-module-tests--variable): New
helper type to guard access to state in a thread-safe way.
(emacs-module-tests--wait-for-variable)
(emacs-module-tests--change-variable): New helper functions.
(emacs-module-tests/interleaved-threads): New unit test.
As the constraint logic of the compiler is not trivial and largely
independent from the rest of the code move it into comp-cstr.el to
ease separation and maintainability.
This commit improve the conversion type
specifier -> constraint for generality.
Lastly this should help with bootstrap time as comp.el compilation
unit is slimmed down.
* lisp/emacs-lisp/comp-cstr.el: New file.
(comp--typeof-types, comp--all-builtin-types): Move from comp.el.
(comp-cstr, comp-cstr-f): Same + rename.
(comp-cstr-ctxt): New struct.
(comp-supertypes, comp-common-supertype-2)
(comp-common-supertype, comp-subtype-p, comp-union-typesets)
(comp-range-1+, comp-range-1-, comp-range-<, comp-range-union)
(comp-range-intersection): Move from comp.el.
(comp-cstr-union-no-range, comp-cstr-union): Move from comp.el and
rename.
(comp-cstr-union-make): New function.
(comp-type-spec-to-cstr, comp-cstr-to-type-spec): Move from
comp.el, rename it and rework it.
* lisp/emacs-lisp/comp.el (comp-known-func-cstr-h): Rework.
(comp-ctxt): Remove two fields and include `comp-cstr-ctxt'.
(comp-mvar, comp-fwprop-call): Update for `comp-cstr' being
renamed.
(comp-fwprop-insn): Use `comp-cstr-union-no-range' or
`comp-cstr-union'.
(comp-ret-type-spec): Use `comp-cstr-union' and rework.
* test/lisp/emacs-lisp/comp-cstr-tests.el: New file.
(comp-cstr-test-ts, comp-cstr-typespec-test): New functions.
(comp-cstr-typespec-tests-alist): New defconst to generate tests
on.
(comp-cstr-generate-tests): New macro.
* test/src/comp-tests.el (comp-tests-type-spec-tests): Update.
(ret-type-spec): Initialize constraint context.
* src/keymap.c (describe_vector): Say which command shadows this
binding. (Bug#9293)
* test/src/keymap-tests.el
(help--describe-vector/bug-9293-one-shadowed-in-range): Adapt
test.
* src/keymap.c (describe_vector): Do not say binding is shadowed if
the other key binding points to the same command. (Bug#9293)
* test/src/keymap-tests.el
(help--describe-vector/bug-9293-same-command-does-not-shadow): New
test.
* src/keymap.c (describe_vector): Make sure found consecutive keys
are either not shadowed or, if they are, that they are shadowed by
the same command. (Bug#9293)
* test/src/keymap-tests.el
(help--describe-vector/bug-9293-one-shadowed-in-range): New test.
Set the default value when `set` encounters a PER_BUFFER variable
which has been let-bound globally, to match the behavior seen with
`make-variable-buffer-local`.
* test/src/data-tests.el (binding-test--let-buffer-local):
Add corresponding test.
(data-tests--set-default-per-buffer): Add tentative test for the
performance problem encountered in bug#41029.
All-ASCII strings cannot have substrings with non-ASCII characters in
them; use this fact to avoid searching entirely.
* src/fns.c (Fstring_search): For multibyte non-ASCII needle and
unibyte haystack, don't check if the haystack is all-ASCII; it's a
waste of time. For multibyte non-ASCII needle and multibyte
all-ASCII haystack, fail immediately.
* test/src/fns-tests.el (string-search): Add more test cases.
Also add some tests for braces and parse-partial-sexp amongst Lisp style
comments.
* test/src/syntax-tests.el (\;-in, \;-out): Add syntax for { and }.
(top-level): Add new tests for Lisp style comments.
(\#|-in, \#|-out): New functions.
(top-level): Add new tests for nested Lisp style comments, and mixtures of
nested comments with "ordinary" comments.
* test/src/syntax-resources/syntax-comments.txt (top-level): Add new test
fragments for #|...|#, etc.
* lisp/emacs-lisp/comp.el (comp-mvar-symbol-p): Improve it.
(comp-cond-rw-func): Fix logic for multiple predecessor on target
block.
* test/src/comp-tests.el (comp-test-cond-rw-1): New test.
* test/src/comp-test-funcs.el (comp-test-cond-rw-1-1-f)
(comp-test-cond-rw-1-2-f): New functions.
* lisp/help.el (describe-map): Fix running `menu-item' :filter
functions. This fixes a mistake in the previous conversion of this
defun from the old C function describe_map. See the discussion in
Bug#39149.
* test/src/keymap-tests.el
(keymap---get-keyelt/runs-menu-item-filter)
(describe-buffer-bindings/menu-item-filter-show-binding)
(describe-buffer-bindings/menu-item-filter-hide-binding):
New tests.
(keymap-tests--test-menu-item-filter): New defun.
* lisp/emacs-lisp/comp.el (comp-constraint-to-type-spec): New
function splitting out code from comp-ret-type-spec + better
handle boolean type specifier.
(comp-ret-type-spec): Rework to leverage
`comp-constraint-to-type-spec'.
* test/src/comp-tests.el (comp-tests-type-spec-tests): Add a
testcase.
* lisp/emacs-lisp/comp.el (comp-known-type-specifiers): New const
in place of `comp-known-ret-types' and `comp-known-ret-ranges'.
(comp-constraint): New struct to separate the constraint side of
an mvar.
(comp-constraint-f): Analogous for functions.
(comp-mvar): Rework and include `comp-constraint'.
(comp-type-spec-to-constraint): New function.
(comp-known-constraints-h): New const.
(comp-func-ret-typeset, comp-func-ret-range): Rework.
(comp-fwprop-insn): Fix.
* test/src/comp-tests.el (destructure-type-spec): New testcase.