diff options
| author | Helmut Eller | 2026-02-27 18:32:12 +0100 |
|---|---|---|
| committer | Helmut Eller | 2026-03-21 18:42:00 +0100 |
| commit | 32f9e2109858565166e65da0dabaf48c4baca20c (patch) | |
| tree | fed9160ab6d8af888e32221ec459cdf3abd0569c /src | |
| parent | bbb4fc26e725dc4b433fedb9422095518ebc8691 (diff) | |
| download | emacs-32f9e2109858565166e65da0dabaf48c4baca20c.tar.gz emacs-32f9e2109858565166e65da0dabaf48c4baca20c.zip | |
Introduce a struct charset_table
The fields of the new struct are what the global variables
charset_table, charset_table_size, charset_table_used, and
charset_attributes_table used to be. The struct should make it clearer
that those fields must be kept in sync.
* src/charset.h (struct charset_table): New struct.
(charset_attributes_getter): Adjust accordingly.
* src/charset.c (charset_table): Change type to struct charset_table.
(charset_table_size, charset_table_used, charset_attributes_table):
Moved to the struct.
(Fdefine_charset_internal, Ffind_charset_region, Ffind_charset_string)
(shrink_charset_table, syms_of_charset): Adjust to struct charset_table.
* src/pdumper.c (dump_charset, dump_charset_table): Adjust to struct
charset_table.
Diffstat (limited to 'src')
| -rw-r--r-- | src/charset.c | 94 | ||||
| -rw-r--r-- | src/charset.h | 30 | ||||
| -rw-r--r-- | src/pdumper.c | 12 |
3 files changed, 72 insertions, 64 deletions
diff --git a/src/charset.c b/src/charset.c index ff501022af9..eae81d689b7 100644 --- a/src/charset.c +++ b/src/charset.c | |||
| @@ -60,16 +60,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 60 | charset symbols, and values are vectors of charset attributes. */ | 60 | charset symbols, and values are vectors of charset attributes. */ |
| 61 | Lisp_Object Vcharset_hash_table; | 61 | Lisp_Object Vcharset_hash_table; |
| 62 | 62 | ||
| 63 | /* Table of struct charset. */ | 63 | /* The table of all charsets. */ |
| 64 | struct charset *charset_table; | 64 | struct charset_table charset_table; |
| 65 | int charset_table_size; | ||
| 66 | int charset_table_used; | ||
| 67 | |||
| 68 | /* Table of attribute vectors. charset_attributes_table[id] contains | ||
| 69 | the attribute vector for the charset at charset_table[id]. | ||
| 70 | |||
| 71 | This is a separate vector to simplify GC. */ | ||
| 72 | Lisp_Object charset_attributes_table; | ||
| 73 | 65 | ||
| 74 | /* Special charsets corresponding to symbols. */ | 66 | /* Special charsets corresponding to symbols. */ |
| 75 | int charset_ascii; | 67 | int charset_ascii; |
| @@ -1128,28 +1120,28 @@ usage: (define-charset-internal ...) */) | |||
| 1128 | else | 1120 | else |
| 1129 | { | 1121 | { |
| 1130 | hash_put (hash_table, args[charset_arg_name], attrs, hash_code); | 1122 | hash_put (hash_table, args[charset_arg_name], attrs, hash_code); |
| 1131 | if (charset_table_used == charset_table_size) | 1123 | if (charset_table.used == charset_table.size) |
| 1132 | { | 1124 | { |
| 1133 | /* Ensure that charset IDs fit into 'int' as well as into the | 1125 | /* Ensure that charset IDs fit into 'int' as well as into the |
| 1134 | restriction imposed by fixnums. Although the 'int' restriction | 1126 | restriction imposed by fixnums. Although the 'int' restriction |
| 1135 | could be removed, too much other code would need altering; for | 1127 | could be removed, too much other code would need altering; for |
| 1136 | example, the IDs are stuffed into struct | 1128 | example, the IDs are stuffed into struct |
| 1137 | coding_system.charbuf[i] entries, which are 'int'. */ | 1129 | coding_system.charbuf[i] entries, which are 'int'. */ |
| 1138 | int old_size = charset_table_size; | 1130 | int old_size = charset_table.size; |
| 1139 | ptrdiff_t new_size = old_size; | 1131 | ptrdiff_t new_size = old_size; |
| 1140 | struct charset *new_table | 1132 | struct charset *new_table |
| 1141 | = xpalloc (0, &new_size, 1, | 1133 | = xpalloc (0, &new_size, 1, |
| 1142 | min (INT_MAX, MOST_POSITIVE_FIXNUM), | 1134 | min (INT_MAX, MOST_POSITIVE_FIXNUM), |
| 1143 | sizeof *charset_table); | 1135 | sizeof *charset_table.start); |
| 1144 | memcpy (new_table, charset_table, | 1136 | memcpy (new_table, charset_table.start, |
| 1145 | old_size * sizeof *new_table); | 1137 | old_size * sizeof *new_table); |
| 1146 | charset_table = new_table; | 1138 | charset_table.start = new_table; |
| 1147 | charset_table_size = new_size; | 1139 | charset_table.size = new_size; |
| 1148 | Lisp_Object new_attr_table = make_vector (new_size, Qnil); | 1140 | Lisp_Object new_attr_table = make_vector (new_size, Qnil); |
| 1149 | for (size_t i = 0; i < old_size; i++) | 1141 | for (size_t i = 0; i < old_size; i++) |
| 1150 | ASET (new_attr_table, i, | 1142 | ASET (new_attr_table, i, |
| 1151 | AREF (charset_attributes_table, i)); | 1143 | AREF (charset_table.attributes_table, i)); |
| 1152 | charset_attributes_table = new_attr_table; | 1144 | charset_table.attributes_table = new_attr_table; |
| 1153 | /* FIXME: This leaks memory, as the old charset_table becomes | 1145 | /* FIXME: This leaks memory, as the old charset_table becomes |
| 1154 | unreachable. If the old charset table is charset_table_init | 1146 | unreachable. If the old charset table is charset_table_init |
| 1155 | then this leak is intentional; otherwise, it's unclear. | 1147 | then this leak is intentional; otherwise, it's unclear. |
| @@ -1158,20 +1150,20 @@ usage: (define-charset-internal ...) */) | |||
| 1158 | charset_table should be freed, by passing it as the 1st argument | 1150 | charset_table should be freed, by passing it as the 1st argument |
| 1159 | to xpalloc and removing the memcpy. */ | 1151 | to xpalloc and removing the memcpy. */ |
| 1160 | } | 1152 | } |
| 1161 | id = charset_table_used++; | 1153 | id = charset_table.used++; |
| 1162 | new_definition_p = 1; | 1154 | new_definition_p = 1; |
| 1163 | } | 1155 | } |
| 1164 | 1156 | ||
| 1165 | ASET (attrs, charset_id, make_fixnum (id)); | 1157 | ASET (attrs, charset_id, make_fixnum (id)); |
| 1166 | charset.id = id; | 1158 | charset.id = id; |
| 1167 | charset_table[id] = charset; | 1159 | charset_table.start[id] = charset; |
| 1168 | ASET (charset_attributes_table, id, attrs); | 1160 | ASET (charset_table.attributes_table, id, attrs); |
| 1169 | eassert (ASIZE (charset_attributes_table) == charset_table_size); | 1161 | eassert (ASIZE (charset_table.attributes_table) == charset_table.size); |
| 1170 | 1162 | ||
| 1171 | if (charset.method == CHARSET_METHOD_MAP) | 1163 | if (charset.method == CHARSET_METHOD_MAP) |
| 1172 | { | 1164 | { |
| 1173 | load_charset (&charset, 0); | 1165 | load_charset (&charset, 0); |
| 1174 | charset_table[id] = charset; | 1166 | charset_table.start[id] = charset; |
| 1175 | } | 1167 | } |
| 1176 | 1168 | ||
| 1177 | if (charset.iso_final >= 0) | 1169 | if (charset.iso_final >= 0) |
| @@ -1566,7 +1558,7 @@ only `ascii', `eight-bit-control', and `eight-bit-graphic'. */) | |||
| 1566 | 1558 | ||
| 1567 | from_byte = CHAR_TO_BYTE (from); | 1559 | from_byte = CHAR_TO_BYTE (from); |
| 1568 | 1560 | ||
| 1569 | charsets = make_nil_vector (charset_table_used); | 1561 | charsets = make_nil_vector (charset_table.used); |
| 1570 | while (1) | 1562 | while (1) |
| 1571 | { | 1563 | { |
| 1572 | find_charsets_in_text (BYTE_POS_ADDR (from_byte), stop - from, | 1564 | find_charsets_in_text (BYTE_POS_ADDR (from_byte), stop - from, |
| @@ -1582,9 +1574,9 @@ only `ascii', `eight-bit-control', and `eight-bit-graphic'. */) | |||
| 1582 | } | 1574 | } |
| 1583 | 1575 | ||
| 1584 | val = Qnil; | 1576 | val = Qnil; |
| 1585 | for (i = charset_table_used - 1; i >= 0; i--) | 1577 | for (i = charset_table.used - 1; i >= 0; i--) |
| 1586 | if (!NILP (AREF (charsets, i))) | 1578 | if (!NILP (AREF (charsets, i))) |
| 1587 | val = Fcons (CHARSET_NAME (charset_table + i), val); | 1579 | val = Fcons (CHARSET_NAME (charset_table.start + i), val); |
| 1588 | return val; | 1580 | return val; |
| 1589 | } | 1581 | } |
| 1590 | 1582 | ||
| @@ -1599,14 +1591,14 @@ only `ascii', `eight-bit-control', and `eight-bit-graphic'. */) | |||
| 1599 | { | 1591 | { |
| 1600 | CHECK_STRING (str); | 1592 | CHECK_STRING (str); |
| 1601 | 1593 | ||
| 1602 | Lisp_Object charsets = make_nil_vector (charset_table_used); | 1594 | Lisp_Object charsets = make_nil_vector (charset_table.used); |
| 1603 | find_charsets_in_text (SDATA (str), SCHARS (str), SBYTES (str), | 1595 | find_charsets_in_text (SDATA (str), SCHARS (str), SBYTES (str), |
| 1604 | charsets, table, | 1596 | charsets, table, |
| 1605 | STRING_MULTIBYTE (str)); | 1597 | STRING_MULTIBYTE (str)); |
| 1606 | Lisp_Object val = Qnil; | 1598 | Lisp_Object val = Qnil; |
| 1607 | for (int i = charset_table_used - 1; i >= 0; i--) | 1599 | for (int i = charset_table.used - 1; i >= 0; i--) |
| 1608 | if (!NILP (AREF (charsets, i))) | 1600 | if (!NILP (AREF (charsets, i))) |
| 1609 | val = Fcons (CHARSET_NAME (charset_table + i), val); | 1601 | val = Fcons (CHARSET_NAME (charset_table.start + i), val); |
| 1610 | return val; | 1602 | return val; |
| 1611 | } | 1603 | } |
| 1612 | 1604 | ||
| @@ -2117,28 +2109,29 @@ DIMENSION, CHARS, and FINAL-CHAR. */) | |||
| 2117 | return (id >= 0 ? CHARSET_NAME (CHARSET_FROM_ID (id)) : Qnil); | 2109 | return (id >= 0 ? CHARSET_NAME (CHARSET_FROM_ID (id)) : Qnil); |
| 2118 | } | 2110 | } |
| 2119 | 2111 | ||
| 2120 | /* Shrink charset_table to charset_table_used. */ | 2112 | /* Shrink charset_table to charset_table.used. */ |
| 2121 | static void | 2113 | static void |
| 2122 | shrink_charset_table (void) | 2114 | shrink_charset_table (void) |
| 2123 | { | 2115 | { |
| 2124 | eassert (charset_table_size >= charset_table_used); | 2116 | eassert (charset_table.size >= charset_table.used); |
| 2125 | eassert (ASIZE (charset_attributes_table) == charset_table_size); | 2117 | eassert (ASIZE (charset_table.attributes_table) |
| 2118 | == charset_table.size); | ||
| 2126 | 2119 | ||
| 2127 | struct charset *old = charset_table; | 2120 | struct charset *old = charset_table.start; |
| 2128 | size_t nbytes = charset_table_used * sizeof *old; | 2121 | size_t nbytes = charset_table.used * sizeof *old; |
| 2129 | struct charset *new = xmalloc (nbytes); | 2122 | struct charset *new = xmalloc (nbytes); |
| 2130 | memcpy (new, old, nbytes); | 2123 | memcpy (new, old, nbytes); |
| 2131 | charset_table = new; | 2124 | charset_table.start = new; |
| 2132 | xfree (old); | 2125 | xfree (old); |
| 2133 | 2126 | ||
| 2134 | Lisp_Object new_attr_table = make_vector (charset_table_used, Qnil); | 2127 | Lisp_Object new_attr_table = make_vector (charset_table.used, Qnil); |
| 2135 | for (size_t i = 0; i < charset_table_used; i++) | 2128 | for (size_t i = 0; i < charset_table.used; i++) |
| 2136 | ASET (new_attr_table, i, AREF (charset_attributes_table, i)); | 2129 | ASET (new_attr_table, i, |
| 2137 | charset_attributes_table = new_attr_table; | 2130 | AREF (charset_table.attributes_table, i)); |
| 2138 | 2131 | charset_table.attributes_table = new_attr_table; | |
| 2139 | charset_table_size = charset_table_used; | ||
| 2140 | 2132 | ||
| 2141 | eassert (ASIZE (charset_attributes_table) == charset_table_size); | 2133 | charset_table.size = charset_table.used; |
| 2134 | eassert (ASIZE (charset_table.attributes_table) == charset_table.size); | ||
| 2142 | } | 2135 | } |
| 2143 | 2136 | ||
| 2144 | DEFUN ("clear-charset-maps", Fclear_charset_maps, Sclear_charset_maps, | 2137 | DEFUN ("clear-charset-maps", Fclear_charset_maps, Sclear_charset_maps, |
| @@ -2400,16 +2393,17 @@ syms_of_charset (void) | |||
| 2400 | staticpro (&Vcharset_hash_table); | 2393 | staticpro (&Vcharset_hash_table); |
| 2401 | Vcharset_hash_table = CALLN (Fmake_hash_table, QCtest, Qeq); | 2394 | Vcharset_hash_table = CALLN (Fmake_hash_table, QCtest, Qeq); |
| 2402 | 2395 | ||
| 2403 | charset_table_size = CHARSET_TABLE_INIT_SIZE; | 2396 | charset_table.size = CHARSET_TABLE_INIT_SIZE; |
| 2404 | PDUMPER_REMEMBER_SCALAR (charset_table_size); | 2397 | PDUMPER_REMEMBER_SCALAR (charset_table.size); |
| 2405 | charset_table | 2398 | charset_table.start |
| 2406 | = xmalloc (charset_table_size * sizeof *charset_table); | 2399 | = xmalloc (charset_table.size * sizeof *charset_table.start); |
| 2407 | charset_table_used = 0; | 2400 | charset_table.used = 0; |
| 2408 | PDUMPER_REMEMBER_SCALAR (charset_table_used); | 2401 | PDUMPER_REMEMBER_SCALAR (charset_table.used); |
| 2409 | 2402 | ||
| 2410 | charset_attributes_table = make_vector (charset_table_size, Qnil); | 2403 | charset_table.attributes_table |
| 2411 | staticpro (&charset_attributes_table); | 2404 | = make_vector (charset_table.size, Qnil); |
| 2412 | 2405 | ||
| 2406 | staticpro (&charset_table.attributes_table); | ||
| 2413 | defsubr (&Scharsetp); | 2407 | defsubr (&Scharsetp); |
| 2414 | defsubr (&Smap_charset_chars); | 2408 | defsubr (&Smap_charset_chars); |
| 2415 | defsubr (&Sdefine_charset_internal); | 2409 | defsubr (&Sdefine_charset_internal); |
diff --git a/src/charset.h b/src/charset.h index 7cd2f8b70cd..f7cd08e3a88 100644 --- a/src/charset.h +++ b/src/charset.h | |||
| @@ -243,14 +243,28 @@ struct charset | |||
| 243 | vectors. */ | 243 | vectors. */ |
| 244 | extern Lisp_Object Vcharset_hash_table; | 244 | extern Lisp_Object Vcharset_hash_table; |
| 245 | 245 | ||
| 246 | /* Table of struct charset. */ | 246 | /* A charset_table is an array of struct charset along with a |
| 247 | extern struct charset *charset_table; | 247 | Lisp_Vector of charset attributes. |
| 248 | extern int charset_table_size; | ||
| 249 | extern int charset_table_used; | ||
| 250 | 248 | ||
| 251 | extern Lisp_Object charset_attributes_table; | 249 | The charset_table.start field either points to xmalloced memory or to |
| 250 | the dump (i.e. pdumper_object_p (charset_table.start) can be true). | ||
| 252 | 251 | ||
| 253 | #define CHARSET_FROM_ID(id) (charset_table + (id)) | 252 | charset_table.attributes_table[id] contains the attribute vector for |
| 253 | the charset at charset_table.start[id]. | ||
| 254 | |||
| 255 | We keep the attributes in a separate vector because that is | ||
| 256 | convenient for the GC. (We probably need to revise this decision, if | ||
| 257 | we ever expose struct charset as a Lisp level type.) */ | ||
| 258 | struct charset_table | ||
| 259 | { | ||
| 260 | struct charset *start; | ||
| 261 | unsigned size, used; | ||
| 262 | Lisp_Object attributes_table; | ||
| 263 | }; | ||
| 264 | |||
| 265 | extern struct charset_table charset_table; | ||
| 266 | |||
| 267 | #define CHARSET_FROM_ID(id) (charset_table.start + (id)) | ||
| 254 | 268 | ||
| 255 | extern Lisp_Object Vcharset_ordered_list; | 269 | extern Lisp_Object Vcharset_ordered_list; |
| 256 | extern Lisp_Object Vcharset_non_preferred_head; | 270 | extern Lisp_Object Vcharset_non_preferred_head; |
| @@ -290,8 +304,8 @@ extern int emacs_mule_charset[256]; | |||
| 290 | INLINE Lisp_Object | 304 | INLINE Lisp_Object |
| 291 | charset_attributes_getter (struct charset *charset) | 305 | charset_attributes_getter (struct charset *charset) |
| 292 | { | 306 | { |
| 293 | eassert (ASIZE (charset_attributes_table) == charset_table_size); | 307 | eassert (ASIZE (charset_table.attributes_table) == charset_table.size); |
| 294 | Lisp_Object attrs = AREF (charset_attributes_table, charset->id); | 308 | Lisp_Object attrs = AREF (charset_table.attributes_table, charset->id); |
| 295 | eassert (XFIXNUM (CHARSET_ATTR_ID (attrs)) == charset->id); | 309 | eassert (XFIXNUM (CHARSET_ATTR_ID (attrs)) == charset->id); |
| 296 | return attrs; | 310 | return attrs; |
| 297 | } | 311 | } |
diff --git a/src/pdumper.c b/src/pdumper.c index 6461ec170d0..b0f40c6e3ce 100644 --- a/src/pdumper.c +++ b/src/pdumper.c | |||
| @@ -3214,10 +3214,10 @@ dump_charset (struct dump_context *ctx, int cs_i) | |||
| 3214 | /* We can't change the alignment here, because ctx->offset is what | 3214 | /* We can't change the alignment here, because ctx->offset is what |
| 3215 | will be used for the whole array. */ | 3215 | will be used for the whole array. */ |
| 3216 | eassert (ctx->offset % alignof (struct charset) == 0); | 3216 | eassert (ctx->offset % alignof (struct charset) == 0); |
| 3217 | const struct charset *cs = charset_table + cs_i; | 3217 | const struct charset *cs = charset_table.start + cs_i; |
| 3218 | struct charset out; | 3218 | struct charset out; |
| 3219 | dump_object_start (ctx, &out, sizeof (out)); | 3219 | dump_object_start (ctx, &out, sizeof (out)); |
| 3220 | if (cs_i < charset_table_used) /* Don't look at uninitialized data. */ | 3220 | if (cs_i < charset_table.used) /* Don't look at uninitialized data. */ |
| 3221 | { | 3221 | { |
| 3222 | DUMP_FIELD_COPY (&out, cs, id); | 3222 | DUMP_FIELD_COPY (&out, cs, id); |
| 3223 | DUMP_FIELD_COPY (&out, cs, dimension); | 3223 | DUMP_FIELD_COPY (&out, cs, dimension); |
| @@ -3244,7 +3244,7 @@ dump_charset (struct dump_context *ctx, int cs_i) | |||
| 3244 | DUMP_FIELD_COPY (&out, cs, code_offset); | 3244 | DUMP_FIELD_COPY (&out, cs, code_offset); |
| 3245 | } | 3245 | } |
| 3246 | dump_off offset = dump_object_finish (ctx, &out, sizeof (out)); | 3246 | dump_off offset = dump_object_finish (ctx, &out, sizeof (out)); |
| 3247 | if (cs_i < charset_table_used && cs->code_space_mask) | 3247 | if (cs_i < charset_table.used && cs->code_space_mask) |
| 3248 | dump_remember_cold_op (ctx, COLD_OP_CHARSET, | 3248 | dump_remember_cold_op (ctx, COLD_OP_CHARSET, |
| 3249 | Fcons (dump_off_to_lisp (cs_i), | 3249 | Fcons (dump_off_to_lisp (cs_i), |
| 3250 | dump_off_to_lisp (offset))); | 3250 | dump_off_to_lisp (offset))); |
| @@ -3260,8 +3260,8 @@ dump_charset_table (struct dump_context *ctx) | |||
| 3260 | dump_off offset = ctx->offset; | 3260 | dump_off offset = ctx->offset; |
| 3261 | if (dump_set_referrer (ctx)) | 3261 | if (dump_set_referrer (ctx)) |
| 3262 | ctx->current_referrer = build_string ("charset_table"); | 3262 | ctx->current_referrer = build_string ("charset_table"); |
| 3263 | eassert (charset_table_size == charset_table_used); | 3263 | eassert (charset_table.size == charset_table.used); |
| 3264 | for (int i = 0; i < charset_table_size; ++i) | 3264 | for (int i = 0; i < charset_table.size; ++i) |
| 3265 | dump_charset (ctx, i); | 3265 | dump_charset (ctx, i); |
| 3266 | dump_clear_referrer (ctx); | 3266 | dump_clear_referrer (ctx); |
| 3267 | dump_emacs_reloc_to_dump_ptr_raw (ctx, &charset_table, offset); | 3267 | dump_emacs_reloc_to_dump_ptr_raw (ctx, &charset_table, offset); |
| @@ -3411,7 +3411,7 @@ dump_cold_charset (struct dump_context *ctx, Lisp_Object data) | |||
| 3411 | (ctx, | 3411 | (ctx, |
| 3412 | cs_dump_offset + dump_offsetof (struct charset, code_space_mask), | 3412 | cs_dump_offset + dump_offsetof (struct charset, code_space_mask), |
| 3413 | ctx->offset); | 3413 | ctx->offset); |
| 3414 | struct charset *cs = charset_table + cs_i; | 3414 | struct charset *cs = charset_table.start + cs_i; |
| 3415 | dump_write (ctx, cs->code_space_mask, 256); | 3415 | dump_write (ctx, cs->code_space_mask, 256); |
| 3416 | } | 3416 | } |
| 3417 | 3417 | ||