diff options
| author | Stefan Monnier | 2024-03-18 09:35:11 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2024-03-18 09:35:11 -0400 |
| commit | be08372bf9b7ebe244ba6940f3e78fc754910d86 (patch) | |
| tree | bb192d43d3e87a0945f0f05967da310aae29030a | |
| parent | 1a8b34a503e5af32851c1aac27a3f09e2345673b (diff) | |
| parent | 63e67916b01569da5bb24f6d9a354dc72897c468 (diff) | |
| download | emacs-be08372bf9b7ebe244ba6940f3e78fc754910d86.tar.gz emacs-be08372bf9b7ebe244ba6940f3e78fc754910d86.zip | |
Merge branch 'cl-type-of' (bug#69739)
| -rw-r--r-- | doc/lispref/objects.texi | 27 | ||||
| -rw-r--r-- | etc/NEWS | 9 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-generic.el | 6 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-preloaded.el | 13 | ||||
| -rw-r--r-- | lisp/emacs-lisp/eieio-core.el | 2 | ||||
| -rw-r--r-- | lisp/emacs-lisp/seq.el | 3 | ||||
| -rw-r--r-- | lisp/subr.el | 11 | ||||
| -rw-r--r-- | src/comp.c | 2 | ||||
| -rw-r--r-- | src/data.c | 40 | ||||
| -rw-r--r-- | src/lisp.h | 6 | ||||
| -rw-r--r-- | src/puresize.h | 2 | ||||
| -rw-r--r-- | src/sqlite.c | 17 | ||||
| -rw-r--r-- | test/src/data-tests.el | 35 |
13 files changed, 134 insertions, 39 deletions
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi index 279f449a994..aa1e073042f 100644 --- a/doc/lispref/objects.texi +++ b/doc/lispref/objects.texi | |||
| @@ -1485,8 +1485,8 @@ types that are not built into Emacs. | |||
| 1485 | @subsection Type Descriptors | 1485 | @subsection Type Descriptors |
| 1486 | 1486 | ||
| 1487 | A @dfn{type descriptor} is a @code{record} which holds information | 1487 | A @dfn{type descriptor} is a @code{record} which holds information |
| 1488 | about a type. Slot 1 in the record must be a symbol naming the type, and | 1488 | about a type. The first slot in the record must be a symbol naming the type, |
| 1489 | @code{type-of} relies on this to return the type of @code{record} | 1489 | and @code{type-of} relies on this to return the type of @code{record} |
| 1490 | objects. No other type descriptor slot is used by Emacs; they are | 1490 | objects. No other type descriptor slot is used by Emacs; they are |
| 1491 | free for use by Lisp extensions. | 1491 | free for use by Lisp extensions. |
| 1492 | 1492 | ||
| @@ -2175,7 +2175,7 @@ with references to further information. | |||
| 2175 | function @code{type-of}. Recall that each object belongs to one and | 2175 | function @code{type-of}. Recall that each object belongs to one and |
| 2176 | only one primitive type; @code{type-of} tells you which one (@pxref{Lisp | 2176 | only one primitive type; @code{type-of} tells you which one (@pxref{Lisp |
| 2177 | Data Types}). But @code{type-of} knows nothing about non-primitive | 2177 | Data Types}). But @code{type-of} knows nothing about non-primitive |
| 2178 | types. In most cases, it is more convenient to use type predicates than | 2178 | types. In most cases, it is preferable to use type predicates than |
| 2179 | @code{type-of}. | 2179 | @code{type-of}. |
| 2180 | 2180 | ||
| 2181 | @defun type-of object | 2181 | @defun type-of object |
| @@ -2207,6 +2207,27 @@ slot is returned; @ref{Records}. | |||
| 2207 | @end example | 2207 | @end example |
| 2208 | @end defun | 2208 | @end defun |
| 2209 | 2209 | ||
| 2210 | @defun cl-type-of object | ||
| 2211 | This function returns a symbol naming @emph{the} type of | ||
| 2212 | @var{object}. It usually behaves like @code{type-of}, except | ||
| 2213 | that it guarantees to return the most precise type possible, which also | ||
| 2214 | implies that the specific type it returns may change depending on the | ||
| 2215 | Emacs version. For this reason, as a rule you should never compare its | ||
| 2216 | return value against some fixed set of types. | ||
| 2217 | |||
| 2218 | @example | ||
| 2219 | (cl-type-of 1) | ||
| 2220 | @result{} fixnum | ||
| 2221 | @group | ||
| 2222 | (cl-type-of 'nil) | ||
| 2223 | @result{} null | ||
| 2224 | (cl-type-of (record 'foo)) | ||
| 2225 | @result{} foo | ||
| 2226 | @end group | ||
| 2227 | @end example | ||
| 2228 | @end defun | ||
| 2229 | |||
| 2230 | |||
| 2210 | @node Equality Predicates | 2231 | @node Equality Predicates |
| 2211 | @section Equality Predicates | 2232 | @section Equality Predicates |
| 2212 | @cindex equality | 2233 | @cindex equality |
| @@ -1647,6 +1647,15 @@ values. | |||
| 1647 | 1647 | ||
| 1648 | * Lisp Changes in Emacs 30.1 | 1648 | * Lisp Changes in Emacs 30.1 |
| 1649 | 1649 | ||
| 1650 | ** New function 'cl-type-of'. | ||
| 1651 | This function is like 'type-of' except that it sometimes returns | ||
| 1652 | a more precise type. For example, for nil and t it returns 'null' | ||
| 1653 | and 'boolean' respectively, instead of just 'symbol'. | ||
| 1654 | |||
| 1655 | ** New function `primitive-function-p`. | ||
| 1656 | This is like `subr-primitive-p` except that it returns t only if the | ||
| 1657 | argument is a function rather than a special-form. | ||
| 1658 | |||
| 1650 | ** Built-in types have now corresponding classes. | 1659 | ** Built-in types have now corresponding classes. |
| 1651 | At the Lisp level, this means that things like (cl-find-class 'integer) | 1660 | At the Lisp level, this means that things like (cl-find-class 'integer) |
| 1652 | will now return a class object, and at the UI level it means that | 1661 | will now return a class object, and at the UI level it means that |
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 613ecf82a92..62abe8d1589 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el | |||
| @@ -1334,8 +1334,7 @@ These match if the argument is `eql' to VAL." | |||
| 1334 | 1334 | ||
| 1335 | (defconst cl--generic--unreachable-types | 1335 | (defconst cl--generic--unreachable-types |
| 1336 | ;; FIXME: Try to make that list empty? | 1336 | ;; FIXME: Try to make that list empty? |
| 1337 | '(fixnum bignum boolean keyword | 1337 | '(keyword) |
| 1338 | special-form subr-primitive subr-native-elisp) | ||
| 1339 | "Built-in classes on which we cannot dispatch for technical reasons.") | 1338 | "Built-in classes on which we cannot dispatch for technical reasons.") |
| 1340 | 1339 | ||
| 1341 | (defun cl--generic-type-specializers (tag &rest _) | 1340 | (defun cl--generic-type-specializers (tag &rest _) |
| @@ -1345,8 +1344,7 @@ These match if the argument is `eql' to VAL." | |||
| 1345 | (cl--class-allparents class))))) | 1344 | (cl--class-allparents class))))) |
| 1346 | 1345 | ||
| 1347 | (cl-generic-define-generalizer cl--generic-typeof-generalizer | 1346 | (cl-generic-define-generalizer cl--generic-typeof-generalizer |
| 1348 | ;; FIXME: We could also change `type-of' to return `null' for nil. | 1347 | 10 (lambda (name &rest _) `(cl-type-of ,name)) |
| 1349 | 10 (lambda (name &rest _) `(if ,name (type-of ,name) 'null)) | ||
| 1350 | #'cl--generic-type-specializers) | 1348 | #'cl--generic-type-specializers) |
| 1351 | 1349 | ||
| 1352 | (cl-defmethod cl-generic-generalizers :extra "typeof" (type) | 1350 | (cl-defmethod cl-generic-generalizers :extra "typeof" (type) |
diff --git a/lisp/emacs-lisp/cl-preloaded.el b/lisp/emacs-lisp/cl-preloaded.el index 515aa99549d..cba56e0bbd4 100644 --- a/lisp/emacs-lisp/cl-preloaded.el +++ b/lisp/emacs-lisp/cl-preloaded.el | |||
| @@ -339,8 +339,6 @@ | |||
| 339 | ',parents)))))) | 339 | ',parents)))))) |
| 340 | 340 | ||
| 341 | ;; FIXME: Our type DAG has various quirks: | 341 | ;; FIXME: Our type DAG has various quirks: |
| 342 | ;; - `subr' says it's a `compiled-function' but that's not true | ||
| 343 | ;; for those subrs that are special forms! | ||
| 344 | ;; - Some `keyword's are also `symbol-with-pos' but that's not reflected | 342 | ;; - Some `keyword's are also `symbol-with-pos' but that's not reflected |
| 345 | ;; in the DAG. | 343 | ;; in the DAG. |
| 346 | ;; - An OClosure can be an interpreted function or a `byte-code-function', | 344 | ;; - An OClosure can be an interpreted function or a `byte-code-function', |
| @@ -367,6 +365,7 @@ | |||
| 367 | (cl--define-built-in-type buffer atom) | 365 | (cl--define-built-in-type buffer atom) |
| 368 | (cl--define-built-in-type window atom) | 366 | (cl--define-built-in-type window atom) |
| 369 | (cl--define-built-in-type process atom) | 367 | (cl--define-built-in-type process atom) |
| 368 | (cl--define-built-in-type finalizer atom) | ||
| 370 | (cl--define-built-in-type window-configuration atom) | 369 | (cl--define-built-in-type window-configuration atom) |
| 371 | (cl--define-built-in-type overlay atom) | 370 | (cl--define-built-in-type overlay atom) |
| 372 | (cl--define-built-in-type number-or-marker atom | 371 | (cl--define-built-in-type number-or-marker atom |
| @@ -428,15 +427,17 @@ For this build of Emacs it's %dbit." | |||
| 428 | "Abstract type of functions that have been compiled.") | 427 | "Abstract type of functions that have been compiled.") |
| 429 | (cl--define-built-in-type byte-code-function (compiled-function) | 428 | (cl--define-built-in-type byte-code-function (compiled-function) |
| 430 | "Type of functions that have been byte-compiled.") | 429 | "Type of functions that have been byte-compiled.") |
| 431 | (cl--define-built-in-type subr (compiled-function) | 430 | (cl--define-built-in-type subr (atom) |
| 432 | "Abstract type of functions compiled to machine code.") | 431 | "Abstract type of functions compiled to machine code.") |
| 433 | (cl--define-built-in-type module-function (function) | 432 | (cl--define-built-in-type module-function (function) |
| 434 | "Type of functions provided via the module API.") | 433 | "Type of functions provided via the module API.") |
| 435 | (cl--define-built-in-type interpreted-function (function) | 434 | (cl--define-built-in-type interpreted-function (function) |
| 436 | "Type of functions that have not been compiled.") | 435 | "Type of functions that have not been compiled.") |
| 437 | (cl--define-built-in-type subr-native-elisp (subr) | 436 | (cl--define-built-in-type special-form (subr) |
| 438 | "Type of function that have been compiled by the native compiler.") | 437 | "Type of the core syntactic elements of the Emacs Lisp language.") |
| 439 | (cl--define-built-in-type subr-primitive (subr) | 438 | (cl--define-built-in-type subr-native-elisp (subr compiled-function) |
| 439 | "Type of functions that have been compiled by the native compiler.") | ||
| 440 | (cl--define-built-in-type primitive-function (subr compiled-function) | ||
| 440 | "Type of functions hand written in C.") | 441 | "Type of functions hand written in C.") |
| 441 | 442 | ||
| 442 | (unless (cl--class-parents (cl--find-class 'cl-structure-object)) | 443 | (unless (cl--class-parents (cl--find-class 'cl-structure-object)) |
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index a2f7c4172a3..cf8bd749f2a 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el | |||
| @@ -1046,7 +1046,7 @@ method invocation orders of the involved classes." | |||
| 1046 | 1046 | ||
| 1047 | (defun cl--generic-struct-tag (name &rest _) | 1047 | (defun cl--generic-struct-tag (name &rest _) |
| 1048 | ;; Use exactly the same code as for `typeof'. | 1048 | ;; Use exactly the same code as for `typeof'. |
| 1049 | `(if ,name (type-of ,name) 'null)) | 1049 | `(cl-type-of ,name)) |
| 1050 | 1050 | ||
| 1051 | (cl-generic-define-generalizer eieio--generic-generalizer | 1051 | (cl-generic-define-generalizer eieio--generic-generalizer |
| 1052 | ;; Use the exact same tagcode as for cl-struct, so that methods | 1052 | ;; Use the exact same tagcode as for cl-struct, so that methods |
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 20077db9e60..a20cff16982 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el | |||
| @@ -362,8 +362,7 @@ the result. | |||
| 362 | 362 | ||
| 363 | The result is a sequence of the same type as SEQUENCE." | 363 | The result is a sequence of the same type as SEQUENCE." |
| 364 | (seq-concatenate | 364 | (seq-concatenate |
| 365 | (let ((type (type-of sequence))) | 365 | (if (listp sequence) 'list (type-of sequence)) |
| 366 | (if (eq type 'cons) 'list type)) | ||
| 367 | (seq-subseq sequence 0 n) | 366 | (seq-subseq sequence 0 n) |
| 368 | (seq-subseq sequence (1+ n)))) | 367 | (seq-subseq sequence (1+ n)))) |
| 369 | 368 | ||
diff --git a/lisp/subr.el b/lisp/subr.el index 38a3f6edb34..3de4412637f 100644 --- a/lisp/subr.el +++ b/lisp/subr.el | |||
| @@ -312,11 +312,20 @@ value of last one, or nil if there are none." | |||
| 312 | cond '(empty-body unless) t))) | 312 | cond '(empty-body unless) t))) |
| 313 | 313 | ||
| 314 | (defsubst subr-primitive-p (object) | 314 | (defsubst subr-primitive-p (object) |
| 315 | "Return t if OBJECT is a built-in primitive function." | 315 | "Return t if OBJECT is a built-in primitive written in C. |
| 316 | Such objects can be functions or special forms." | ||
| 316 | (declare (side-effect-free error-free)) | 317 | (declare (side-effect-free error-free)) |
| 317 | (and (subrp object) | 318 | (and (subrp object) |
| 318 | (not (subr-native-elisp-p object)))) | 319 | (not (subr-native-elisp-p object)))) |
| 319 | 320 | ||
| 321 | (defsubst primitive-function-p (object) | ||
| 322 | "Return t if OBJECT is a built-in primitive function. | ||
| 323 | This excludes special forms, since they are not functions." | ||
| 324 | (declare (side-effect-free error-free)) | ||
| 325 | (and (subrp object) | ||
| 326 | (not (or (subr-native-elisp-p object) | ||
| 327 | (eq (cdr (subr-arity object)) 'unevalled))))) | ||
| 328 | |||
| 320 | (defsubst xor (cond1 cond2) | 329 | (defsubst xor (cond1 cond2) |
| 321 | "Return the boolean exclusive-or of COND1 and COND2. | 330 | "Return the boolean exclusive-or of COND1 and COND2. |
| 322 | If only one of the arguments is non-nil, return it; otherwise | 331 | If only one of the arguments is non-nil, return it; otherwise |
diff --git a/src/comp.c b/src/comp.c index 3f989c722d4..76cf1f3ab6e 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -2442,7 +2442,7 @@ emit_limple_insn (Lisp_Object insn) | |||
| 2442 | { | 2442 | { |
| 2443 | Lisp_Object arg1 = arg[1]; | 2443 | Lisp_Object arg1 = arg[1]; |
| 2444 | 2444 | ||
| 2445 | if (EQ (Ftype_of (arg1), Qcomp_mvar)) | 2445 | if (EQ (Fcl_type_of (arg1), Qcomp_mvar)) |
| 2446 | res = emit_mvar_rval (arg1); | 2446 | res = emit_mvar_rval (arg1); |
| 2447 | else if (EQ (FIRST (arg1), Qcall)) | 2447 | else if (EQ (FIRST (arg1), Qcall)) |
| 2448 | res = emit_limple_call (XCDR (arg1)); | 2448 | res = emit_limple_call (XCDR (arg1)); |
diff --git a/src/data.c b/src/data.c index 35f4c82c68f..69b990bed76 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -193,16 +193,37 @@ DEFUN ("null", Fnull, Snull, 1, 1, 0, | |||
| 193 | DEFUN ("type-of", Ftype_of, Stype_of, 1, 1, 0, | 193 | DEFUN ("type-of", Ftype_of, Stype_of, 1, 1, 0, |
| 194 | doc: /* Return a symbol representing the type of OBJECT. | 194 | doc: /* Return a symbol representing the type of OBJECT. |
| 195 | The symbol returned names the object's basic type; | 195 | The symbol returned names the object's basic type; |
| 196 | for example, (type-of 1) returns `integer'. */) | 196 | for example, (type-of 1) returns `integer'. |
| 197 | Contrary to `cl-type-of', the returned type is not always the most | ||
| 198 | precise type possible, because instead this function tries to preserve | ||
| 199 | compatibility with the return value of previous Emacs versions. */) | ||
| 200 | (Lisp_Object object) | ||
| 201 | { | ||
| 202 | return SYMBOLP (object) ? Qsymbol | ||
| 203 | : INTEGERP (object) ? Qinteger | ||
| 204 | : SUBRP (object) ? Qsubr | ||
| 205 | : Fcl_type_of (object); | ||
| 206 | } | ||
| 207 | |||
| 208 | DEFUN ("cl-type-of", Fcl_type_of, Scl_type_of, 1, 1, 0, | ||
| 209 | doc: /* Return a symbol representing the type of OBJECT. | ||
| 210 | The returned symbol names the most specific possible type of the object. | ||
| 211 | for example, (cl-type-of nil) returns `null'. | ||
| 212 | The specific type returned may change depending on Emacs versions, | ||
| 213 | so we recommend you use `cl-typep', `cl-typecase', or other predicates | ||
| 214 | rather than compare the return value of this function against | ||
| 215 | a fixed set of types. */) | ||
| 197 | (Lisp_Object object) | 216 | (Lisp_Object object) |
| 198 | { | 217 | { |
| 199 | switch (XTYPE (object)) | 218 | switch (XTYPE (object)) |
| 200 | { | 219 | { |
| 201 | case_Lisp_Int: | 220 | case_Lisp_Int: |
| 202 | return Qinteger; | 221 | return Qfixnum; |
| 203 | 222 | ||
| 204 | case Lisp_Symbol: | 223 | case Lisp_Symbol: |
| 205 | return Qsymbol; | 224 | return NILP (object) ? Qnull |
| 225 | : EQ (object, Qt) ? Qboolean | ||
| 226 | : Qsymbol; | ||
| 206 | 227 | ||
| 207 | case Lisp_String: | 228 | case Lisp_String: |
| 208 | return Qstring; | 229 | return Qstring; |
| @@ -215,7 +236,7 @@ for example, (type-of 1) returns `integer'. */) | |||
| 215 | switch (PSEUDOVECTOR_TYPE (XVECTOR (object))) | 236 | switch (PSEUDOVECTOR_TYPE (XVECTOR (object))) |
| 216 | { | 237 | { |
| 217 | case PVEC_NORMAL_VECTOR: return Qvector; | 238 | case PVEC_NORMAL_VECTOR: return Qvector; |
| 218 | case PVEC_BIGNUM: return Qinteger; | 239 | case PVEC_BIGNUM: return Qbignum; |
| 219 | case PVEC_MARKER: return Qmarker; | 240 | case PVEC_MARKER: return Qmarker; |
| 220 | case PVEC_SYMBOL_WITH_POS: return Qsymbol_with_pos; | 241 | case PVEC_SYMBOL_WITH_POS: return Qsymbol_with_pos; |
| 221 | case PVEC_OVERLAY: return Qoverlay; | 242 | case PVEC_OVERLAY: return Qoverlay; |
| @@ -224,7 +245,10 @@ for example, (type-of 1) returns `integer'. */) | |||
| 224 | case PVEC_WINDOW_CONFIGURATION: return Qwindow_configuration; | 245 | case PVEC_WINDOW_CONFIGURATION: return Qwindow_configuration; |
| 225 | case PVEC_PROCESS: return Qprocess; | 246 | case PVEC_PROCESS: return Qprocess; |
| 226 | case PVEC_WINDOW: return Qwindow; | 247 | case PVEC_WINDOW: return Qwindow; |
| 227 | case PVEC_SUBR: return Qsubr; | 248 | case PVEC_SUBR: |
| 249 | return XSUBR (object)->max_args == UNEVALLED ? Qspecial_form | ||
| 250 | : SUBR_NATIVE_COMPILEDP (object) ? Qsubr_native_elisp | ||
| 251 | : Qprimitive_function; | ||
| 228 | case PVEC_COMPILED: return Qcompiled_function; | 252 | case PVEC_COMPILED: return Qcompiled_function; |
| 229 | case PVEC_BUFFER: return Qbuffer; | 253 | case PVEC_BUFFER: return Qbuffer; |
| 230 | case PVEC_CHAR_TABLE: return Qchar_table; | 254 | case PVEC_CHAR_TABLE: return Qchar_table; |
| @@ -4202,7 +4226,9 @@ syms_of_data (void) | |||
| 4202 | "Variable binding depth exceeds max-specpdl-size"); | 4226 | "Variable binding depth exceeds max-specpdl-size"); |
| 4203 | 4227 | ||
| 4204 | /* Types that type-of returns. */ | 4228 | /* Types that type-of returns. */ |
| 4229 | DEFSYM (Qboolean, "boolean"); | ||
| 4205 | DEFSYM (Qinteger, "integer"); | 4230 | DEFSYM (Qinteger, "integer"); |
| 4231 | DEFSYM (Qbignum, "bignum"); | ||
| 4206 | DEFSYM (Qsymbol, "symbol"); | 4232 | DEFSYM (Qsymbol, "symbol"); |
| 4207 | DEFSYM (Qstring, "string"); | 4233 | DEFSYM (Qstring, "string"); |
| 4208 | DEFSYM (Qcons, "cons"); | 4234 | DEFSYM (Qcons, "cons"); |
| @@ -4218,6 +4244,9 @@ syms_of_data (void) | |||
| 4218 | DEFSYM (Qprocess, "process"); | 4244 | DEFSYM (Qprocess, "process"); |
| 4219 | DEFSYM (Qwindow, "window"); | 4245 | DEFSYM (Qwindow, "window"); |
| 4220 | DEFSYM (Qsubr, "subr"); | 4246 | DEFSYM (Qsubr, "subr"); |
| 4247 | DEFSYM (Qspecial_form, "special-form"); | ||
| 4248 | DEFSYM (Qprimitive_function, "primitive-function"); | ||
| 4249 | DEFSYM (Qsubr_native_elisp, "subr-native-elisp"); | ||
| 4221 | DEFSYM (Qcompiled_function, "compiled-function"); | 4250 | DEFSYM (Qcompiled_function, "compiled-function"); |
| 4222 | DEFSYM (Qbuffer, "buffer"); | 4251 | DEFSYM (Qbuffer, "buffer"); |
| 4223 | DEFSYM (Qframe, "frame"); | 4252 | DEFSYM (Qframe, "frame"); |
| @@ -4255,6 +4284,7 @@ syms_of_data (void) | |||
| 4255 | defsubr (&Seq); | 4284 | defsubr (&Seq); |
| 4256 | defsubr (&Snull); | 4285 | defsubr (&Snull); |
| 4257 | defsubr (&Stype_of); | 4286 | defsubr (&Stype_of); |
| 4287 | defsubr (&Scl_type_of); | ||
| 4258 | defsubr (&Slistp); | 4288 | defsubr (&Slistp); |
| 4259 | defsubr (&Snlistp); | 4289 | defsubr (&Snlistp); |
| 4260 | defsubr (&Sconsp); | 4290 | defsubr (&Sconsp); |
diff --git a/src/lisp.h b/src/lisp.h index f353e4956eb..f86758c88fb 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -569,10 +569,8 @@ enum Lisp_Fwd_Type | |||
| 569 | your object -- this way, the same object could be used to represent | 569 | your object -- this way, the same object could be used to represent |
| 570 | several disparate C structures. | 570 | several disparate C structures. |
| 571 | 571 | ||
| 572 | In addition, you need to add switch branches in data.c for Ftype_of. | 572 | In addition, you need to add switch branches in data.c for Fcl_type_of |
| 573 | 573 | and `cl--define-builtin-type` in lisp/emacs-lisp/cl-preloaded.el. */ | |
| 574 | You also need to add the new type to the constant | ||
| 575 | `cl--typeof-types' in lisp/emacs-lisp/cl-preloaded.el. */ | ||
| 576 | 574 | ||
| 577 | 575 | ||
| 578 | /* A Lisp_Object is a tagged pointer or integer. Ordinarily it is a | 576 | /* A Lisp_Object is a tagged pointer or integer. Ordinarily it is a |
diff --git a/src/puresize.h b/src/puresize.h index ac5d2da30dc..2a716872832 100644 --- a/src/puresize.h +++ b/src/puresize.h | |||
| @@ -47,7 +47,7 @@ INLINE_HEADER_BEGIN | |||
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #ifndef BASE_PURESIZE | 49 | #ifndef BASE_PURESIZE |
| 50 | #define BASE_PURESIZE (2750000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA) | 50 | #define BASE_PURESIZE (3000000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA) |
| 51 | #endif | 51 | #endif |
| 52 | 52 | ||
| 53 | /* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */ | 53 | /* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */ |
diff --git a/src/sqlite.c b/src/sqlite.c index 7a018b28aa4..261080da673 100644 --- a/src/sqlite.c +++ b/src/sqlite.c | |||
| @@ -349,9 +349,7 @@ bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values) | |||
| 349 | value = XCAR (values); | 349 | value = XCAR (values); |
| 350 | values = XCDR (values); | 350 | values = XCDR (values); |
| 351 | } | 351 | } |
| 352 | Lisp_Object type = Ftype_of (value); | 352 | if (STRINGP (value)) |
| 353 | |||
| 354 | if (EQ (type, Qstring)) | ||
| 355 | { | 353 | { |
| 356 | Lisp_Object encoded; | 354 | Lisp_Object encoded; |
| 357 | bool blob = false; | 355 | bool blob = false; |
| @@ -385,14 +383,11 @@ bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values) | |||
| 385 | SSDATA (encoded), SBYTES (encoded), | 383 | SSDATA (encoded), SBYTES (encoded), |
| 386 | NULL); | 384 | NULL); |
| 387 | } | 385 | } |
| 388 | else if (EQ (type, Qinteger)) | 386 | else if (FIXNUMP (value)) |
| 389 | { | 387 | ret = sqlite3_bind_int64 (stmt, i + 1, XFIXNUM (value)); |
| 390 | if (BIGNUMP (value)) | 388 | else if (BIGNUMP (value)) |
| 391 | ret = sqlite3_bind_int64 (stmt, i + 1, bignum_to_intmax (value)); | 389 | ret = sqlite3_bind_int64 (stmt, i + 1, bignum_to_intmax (value)); |
| 392 | else | 390 | else if (FLOATP (value)) |
| 393 | ret = sqlite3_bind_int64 (stmt, i + 1, XFIXNUM (value)); | ||
| 394 | } | ||
| 395 | else if (EQ (type, Qfloat)) | ||
| 396 | ret = sqlite3_bind_double (stmt, i + 1, XFLOAT_DATA (value)); | 391 | ret = sqlite3_bind_double (stmt, i + 1, XFLOAT_DATA (value)); |
| 397 | else if (NILP (value)) | 392 | else if (NILP (value)) |
| 398 | ret = sqlite3_bind_null (stmt, i + 1); | 393 | ret = sqlite3_bind_null (stmt, i + 1); |
diff --git a/test/src/data-tests.el b/test/src/data-tests.el index ad3b2071254..daa49e671b5 100644 --- a/test/src/data-tests.el +++ b/test/src/data-tests.el | |||
| @@ -838,4 +838,39 @@ comparing the subr with a much slower Lisp implementation." | |||
| 838 | (dolist (sym (list nil t 'xyzzy (make-symbol ""))) | 838 | (dolist (sym (list nil t 'xyzzy (make-symbol ""))) |
| 839 | (should (eq sym (bare-symbol (position-symbol sym 0))))))) | 839 | (should (eq sym (bare-symbol (position-symbol sym 0))))))) |
| 840 | 840 | ||
| 841 | (require 'cl-extra) ;For `cl--class-children'. | ||
| 842 | |||
| 843 | (ert-deftest data-tests--cl-type-of () | ||
| 844 | ;; Make sure that `cl-type-of' returns the most precise type. | ||
| 845 | ;; Note: This doesn't work for list/vector structs since those types | ||
| 846 | ;; are too difficult/unreliable to detect (so `cl-type-of' only says | ||
| 847 | ;; it's a `cons' or a `vector'). | ||
| 848 | (dolist (val (list -2 10 (expt 2 128) nil t 'car | ||
| 849 | (symbol-function 'car) | ||
| 850 | (symbol-function 'progn) | ||
| 851 | (position-symbol 'car 7))) | ||
| 852 | (let* ((type (cl-type-of val)) | ||
| 853 | (class (cl-find-class type)) | ||
| 854 | (alltypes (cl--class-allparents class)) | ||
| 855 | ;; FIXME: Our type DAG is affected by `symbols-with-pos-enabled'. | ||
| 856 | ;; (e.g. `symbolp' returns nil on a sympos if that var is nil). | ||
| 857 | (symbols-with-pos-enabled t)) | ||
| 858 | (dolist (parent alltypes) | ||
| 859 | (should (cl-typep val parent)) | ||
| 860 | (dolist (subtype (cl--class-children (cl-find-class parent))) | ||
| 861 | (unless (memq subtype alltypes) | ||
| 862 | (unless (memq subtype | ||
| 863 | ;; FIXME: Some types don't have any associated | ||
| 864 | ;; predicate, | ||
| 865 | '( font-spec font-entity font-object | ||
| 866 | finalizer condvar terminal | ||
| 867 | native-comp-unit interpreted-function | ||
| 868 | tree-sitter-compiled-query | ||
| 869 | tree-sitter-node tree-sitter-parser | ||
| 870 | ;; `functionp' also matches things of type | ||
| 871 | ;; `symbol' and `cons'. | ||
| 872 | function)) | ||
| 873 | (should-not (cl-typep val subtype))))))))) | ||
| 874 | |||
| 875 | |||
| 841 | ;;; data-tests.el ends here | 876 | ;;; data-tests.el ends here |