This leads to simpler code in the users, and more efficient machine
code because we don't repeatedly need to fetch the `table_size`
and `key_and_value` fields of the hash table object.
* src/lisp.h (DOHASH): Rewrite.
* src/composite.c (composition_gstring_lookup_cache): Simplify.
(composition_gstring_cache_clear_font):
* src/print.c (print):
* src/pdumper.c (hash_table_contents):
* src/minibuf.c (Ftest_completion):
* src/json.c (lisp_to_json_nonscalar_1):
* src/emacs-module.c (module_global_reference_p):
* src/comp.c (compile_function, Fcomp__compile_ctxt_to_file):
* src/fns.c (Fmaphash): Adjust to new calling convention.
This improves performance in several ways. Separate functions are
used depending on whether the caller has a hash value computed or not.
* src/fns.c (hash_lookup_with_hash, hash_lookup_get_hash): New.
(hash_lookup): Remove hash return argument.
All callers adapted.
hash_lookup_with_hash hash_hash_t arg
This improves typing, saves pointless tagging and untagging, and
prepares for further changes. The new typedef hash_hash_t is an alias
for EMACS_UINT, and hash values are still limited to the fixnum range.
We now use hash_unused instead of Qnil to mark unused entries.
* src/lisp.h (hash_hash_t): New typedef for EMACS_UINT.
(hash_unused): New constant.
(struct hash_table_test): `hashfn` now returns
hash_hash_t. All callers and implementations changed.
(struct Lisp_Hash_Table): Retype hash vector to an array of
hash_hash_t. All code using it changed accordingly.
(HASH_HASH, hash_from_key):
* src/fns.c (set_hash_index_slot, hash_index_index)
(hash_lookup_with_hash, hash_lookup_get_hash, hash_put):
(hash_lookup, hash_put): Retype hash value arguments
and return values. All callers adapted.
Qunbound is used for many things; using a predicate and constant for
the specific purpose of unused hash entry keys allows us to locate
them and make changes much more easily.
* src/lisp.h (HASH_UNUSED_ENTRY_KEY, hash_unused_entry_key_p):
New constant and function.
* src/comp.c (compile_function, Fcomp__compile_ctxt_to_file):
* src/composite.c (composition_gstring_cache_clear_font):
* src/emacs-module.c (module_global_reference_p):
* src/fns.c (make_hash_table, maybe_resize_hash_table, hash_put)
(hash_remove_from_table, hash_clear, sweep_weak_table, Fmaphash):
* src/json.c (lisp_to_json_nonscalar_1):
* src/minibuf.c (Ftry_completion, Fall_completions, Ftest_completion):
* src/print.c (print, print_object):
Use them.
* src/json.c (json_available_p): Use original code. Always return
true for !WINDOWSNT.
(ensure_json_available): Now defined only on WINDOWSNT.
(Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): Call ensure_json_available only on
WINDOWSNT.
* lisp/subr.el (json-available-p): Simplify.
* configure.ac (HAVE_TREE_SITTER, TREE_SITTER_OBJ): New variables.
(DYNAMIC_LIB_SUFFIX): new variable, I copied code from MODULES_SUFFIX
so the diff looks this way.
* doc/lispref/elisp.texi (Top): Add tree-sitter manual.
* doc/lispref/modes.texi (Font Lock Mode): mention tree-sitter.
(Parser-based Font Lock): New section.
(Auto-Indentation): Mention tree-sitter.
(Parser-based Indentation): New section.
* doc/lispref/parsing.texi (Parsing Program Source): New chapter.
* lisp/emacs-lisp/cl-preloaded.el (cl--typeof-types): Add
treesit-parser and treesit-node type.
* lisp/treesit.el: New file.
* src/Makefile.in (TREE_SITTER_LIBS, TREE_SITTER_FLAGS,
TREE_SITTER_OBJ): New variables.
* src/alloc.c:
(cleanup_vector): Add cleanup code for treesit-parser and
treesit-node.
* src/casefiddle.c (casify_region): Notify tree-sitter parser of
buffer change.
* src/data.c (Ftype_of): Add treesit-parser and treesit-node type
(Qtreesit_parser, Qtreesit_node): New symbol.
* src/emacs.c (main): Add symbols in treesit.c.
* src/eval.c (define_error): Move the function to here.
* src/insdel.c (insert_1_both, insert_from_string_1, insert_from_gap,
insert_from_buffer_1, replace_range, del_range_2): Notify tree-sitter
parser of buffer change.
* src/json.c (define_error): Move this function out.
* src/lisp.h (DEFINE_GDB_SYMBOL_BEGIN): Add treesit-parser and
treesit-node.
* src/lread.c (Vdynamic_library_suffixes): New variable.
* src/print.c (print_vectorlike): Add code for printing
treesit-parser and treesit-node.
* src/treesit.c: New file.
* src/treesit.h: New file.
* test/src/treesit-tests.el: New file.
* src/json.c (Fjson_serialize, Fjson_insert)
(Fjson_parse_string, Fjson_parse_buffer, syms_of_json): Signal
`json-unavailable' if jansson isn't available (bug#48228).
The JSON serialization and parsing functions don't need to modify
these structures.
* src/json.c (lisp_to_json_nonscalar_1, lisp_to_json_nonscalar)
(lisp_to_json, json_to_lisp): Mark configuration object parameter as
const.
Newer standards like RFC 8259, which obsoletes the earlier RFC 4627,
now allow any top-level value unconditionally, so Emacs should too.
* src/json.c (Fjson_serialize, Fjson_insert): Pass JSON_ENCODE_ANY to
allow serialization of any JSON value. Call 'lisp_to_json' instead of
'lisp_to_json_toplevel'. Remove obsolete comments
(neither JSON_DECODE_ANY nor JSON_ALLOW_NUL are allowed here). Reword
documentation strings.
(Fjson_parse_string, Fjson_parse_buffer): Pass JSON_DECODE_ANY to
allow deserialization of any JSON value. Reword documentation
strings.
(lisp_to_json_nonscalar, lisp_to_json_nonscalar_1): Rename from
"toplevel" to avoid confusion.
(lisp_to_json): Adapt caller.
* test/src/json-tests.el (json-serialize/roundtrip-scalars): New unit
test.
* doc/lispref/text.texi (Parsing JSON): Update documentation.
Now that decode_string_utf_8 is available, we can use it to signal
errors on invalid input.
* src/coding.c (syms_of_coding): Move Qutf_8_string_p from json.c
since it’s now used outside json.c.
* src/emacs-module.c (module_decode_utf_8): New helper function.
(module_make_function, module_copy_string_contents): Use it.
* src/coding.c (get_char_bytes, encode_string_utf_8)
(decode_string_utf_8): Fix commentary.
(encode_string_utf_8): Return the original ASCII string only
if NOCOPY is non-zero.
(decode_string_utf_8): Accept 2 additional arguments STR and
STR_LEN, which allow to pass the input text as a C string.
(make_string_from_utf8): Delegate the job to decode_string_utf_8.
* src/coding.h: Update the prototype of decode_string_utf_8.
* src/json.c (json_encode): Call encode_string_utf_8.
* src/fns.c (cmpfn_eql, cmpfn_equal, cmpfn_user_defined)
(hashfn_eq, hashfn_equal, hashfn_eql, hashfn_user_defined):
* src/profiler.c (cmpfn_profiler, hashfn_profiler):
Use new calling convention where the return value is a fixnum
instead of EMACS_UINT. While we’re at it, put the hash table
at the end, since that’s a bit simpler and generates better
code (at least on the x86-64). All callers changed.
* src/fns.c (hash_lookup): Store fixnum rather than EMACS_UINT.
All callers changed.
(hash_put): Take a fixnum rather than an EMACS_UINT.
All callers changed. Remove unnecessary eassert (XUFIXNUM does it).
* src/lisp.h (struct hash_table_test):
Adjust signatures of cmpfn and hashfn.
* src/coding.h (build_string_from_utf8): Rename from
build_utf8_string. All callers changed.
* src/coding.c (make_string_from_utf8): Rename from
make_utf8_string. All callers changed.
json_make_string and json_build_string are generally useful and not
JSON-specific. Move them to coding.[ch].
* src/coding.h (build_utf8_string): Move from json.c.
* src/coding.c (make_utf8_string): Move from json.c.
* src/json.c (json_make_string, json_build_string): Move to
coding.[ch]. Split out JSON-specific comment.
(json_parse_error, Fjson_serialize, json_to_lisp): Fix callers.
* src/emacs-module.c (module_make_function, module_make_string): Use
new functions.
(module_decode, module_decode_copy): Remove.
INT_TO_INTEGER is more obviously correct and means we don’t have to
worry about data type sizes and signedness.
* src/json.c (json_parse_error): Use INT_TO_INTEGER. The tiny
performance gain of make_fixed_natnum isn’t worth the trouble then
signaling an error.
Thanks to Dmitry Gutov <dgutov@yandex.ru> for running many
benchmarks and for useful discussions.
* src/json.c (json_make_string): Speed up parsing of JSON
strings by optimizing the normal case of a valid UTF-8 string
being returned from libjansson. (Bug#31138)
Although the lisp.h macros really need improvement,
INTEGER_TO_INT is not the right way to go about it, as it
causes conversion from intmax_t to uintmax_t and back again,
which can cause a signal if the value is negative.
* src/lisp.h (INTEGER_TO_INT, ranged_integer_to_int)
(ranged_integer_to_uint): Remove, reverting recent changes to
this file.
* src/json.c (lisp_to_json): Revert to previous code,
as the change messes up with uintmax_t<->intmax_t conversion.
This is similar to CONS_TO_INTEGER. The inverse (INT_TO_INTEGER)
already exists.
* src/lisp.h (INTEGER_TO_INT): New macro.
(ranged_integer_to_int, ranged_integer_to_uint): New
functions.
* src/json.c (lisp_to_json): Use helper macro.
In all cases where we use a CATCHER_ALL handler we also want to catch
signals. Therefore have 'signal' respect CATCHER_ALL. Adapt internal
interfaces so that handlers can distinguish among the two types of
nonlocal exits in CATCHER_ALL handlers.
* src/lisp.h (enum nonlocal_exit): New enum.
(struct handler): Add member 'nonlocal_exit' to hold the type of
nonlocal exit during stack unwinding.
* src/eval.c (signal_or_quit): Also respect CATCHER_ALL handlers.
(unwind_to_catch): Store nonlocal exit type in catch structure.
(Fthrow, signal_or_quit): Adapt callers.
(internal_catch_all): Install only one handler. Give handler a
nonlocal exit type argument.
(internal_catch_all_1): Remove, no longer needed.
* src/emacs-module.c (MODULE_SETJMP): Install only one handler.
(module_handle_nonlocal_exit): New function to handle all nonlocal
exits.
(MODULE_SETJMP_1): Pass nonlocal exit type to handler function.
(module_handle_signal, module_handle_throw): Remove, no longer needed.
* src/json.c (json_handle_nonlocal_exit): New helper function.
(json_insert_callback): Adapt to change in 'internal_catch_all'.
* doc/lispref/text.texi (Parsing JSON): Improve wording of the
documentation of 'json-parse-string' and 'json-parse-buffer'.
* src/json.c (Fjson_parse_string, Fjson_parse_buffer): Doc fix.
(Bug#34763)
* src/json.c (enum json_array_type): New type.
(struct json_configuration): New field array_type.
(json_parse_args): Rename the last argument. Handle the
:array-type keyword argument (bug#32793).
(Fjson_parse_string): Update the docstring accordingly.
(json_to_lisp): Handle the case of :array-type being `list'. Add
a call to 'rarely_quit' inside the loop.
(syms_of_json): Define new symbols.
(Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): Update the config struct initializers.