aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHelmut Eller2026-02-27 18:32:12 +0100
committerHelmut Eller2026-03-21 18:42:00 +0100
commit32f9e2109858565166e65da0dabaf48c4baca20c (patch)
treefed9160ab6d8af888e32221ec459cdf3abd0569c /src
parentbbb4fc26e725dc4b433fedb9422095518ebc8691 (diff)
downloademacs-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.c94
-rw-r--r--src/charset.h30
-rw-r--r--src/pdumper.c12
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. */
61Lisp_Object Vcharset_hash_table; 61Lisp_Object Vcharset_hash_table;
62 62
63/* Table of struct charset. */ 63/* The table of all charsets. */
64struct charset *charset_table; 64struct charset_table charset_table;
65int charset_table_size;
66int 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. */
72Lisp_Object charset_attributes_table;
73 65
74/* Special charsets corresponding to symbols. */ 66/* Special charsets corresponding to symbols. */
75int charset_ascii; 67int 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. */
2121static void 2113static void
2122shrink_charset_table (void) 2114shrink_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
2144DEFUN ("clear-charset-maps", Fclear_charset_maps, Sclear_charset_maps, 2137DEFUN ("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. */
244extern Lisp_Object Vcharset_hash_table; 244extern 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
247extern struct charset *charset_table; 247 Lisp_Vector of charset attributes.
248extern int charset_table_size;
249extern int charset_table_used;
250 248
251extern 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.) */
258struct charset_table
259{
260 struct charset *start;
261 unsigned size, used;
262 Lisp_Object attributes_table;
263};
264
265extern struct charset_table charset_table;
266
267#define CHARSET_FROM_ID(id) (charset_table.start + (id))
254 268
255extern Lisp_Object Vcharset_ordered_list; 269extern Lisp_Object Vcharset_ordered_list;
256extern Lisp_Object Vcharset_non_preferred_head; 270extern Lisp_Object Vcharset_non_preferred_head;
@@ -290,8 +304,8 @@ extern int emacs_mule_charset[256];
290INLINE Lisp_Object 304INLINE Lisp_Object
291charset_attributes_getter (struct charset *charset) 305charset_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