diff options
| author | Eli Zaretskii | 2020-11-28 09:21:33 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2020-11-28 09:21:33 +0200 |
| commit | f31cacd1ff4e020c0a10fa3da6598b21a6b04988 (patch) | |
| tree | b3158dcfbff0129217794266ece0e86f5a73e5d6 /src | |
| parent | cdc632fbe6e149318147a98cccf1b7af191f2ce8 (diff) | |
| download | emacs-f31cacd1ff4e020c0a10fa3da6598b21a6b04988.tar.gz emacs-f31cacd1ff4e020c0a10fa3da6598b21a6b04988.zip | |
Revert "Fix incorrect handling of module runtime and environment pointers."
This reverts commit cdc632fbe6e149318147a98cccf1b7af191f2ce8.
Those changes are too significant and non-trivial to be
suitable for a release branch at this time.
Diffstat (limited to 'src')
| -rw-r--r-- | src/emacs-module.c | 131 |
1 files changed, 22 insertions, 109 deletions
diff --git a/src/emacs-module.c b/src/emacs-module.c index 89d96839d2f..a90a9765dbf 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c | |||
| @@ -217,9 +217,6 @@ static void module_out_of_memory (emacs_env *); | |||
| 217 | static void module_reset_handlerlist (struct handler **); | 217 | static void module_reset_handlerlist (struct handler **); |
| 218 | static bool value_storage_contains_p (const struct emacs_value_storage *, | 218 | static bool value_storage_contains_p (const struct emacs_value_storage *, |
| 219 | emacs_value, ptrdiff_t *); | 219 | emacs_value, ptrdiff_t *); |
| 220 | static Lisp_Object module_objects (Lisp_Object); | ||
| 221 | static void module_push_pointer (Lisp_Object, void *); | ||
| 222 | static void module_pop_pointer (Lisp_Object, void *); | ||
| 223 | 220 | ||
| 224 | static bool module_assertions = false; | 221 | static bool module_assertions = false; |
| 225 | 222 | ||
| @@ -1008,8 +1005,7 @@ module_signal_or_throw (struct emacs_env_private *env) | |||
| 1008 | } | 1005 | } |
| 1009 | } | 1006 | } |
| 1010 | 1007 | ||
| 1011 | /* Live runtime and environment objects, for assertions. These are hashtables | 1008 | /* Live runtime and environment objects, for assertions. */ |
| 1012 | keyed by the thread objects. */ | ||
| 1013 | static Lisp_Object Vmodule_runtimes; | 1009 | static Lisp_Object Vmodule_runtimes; |
| 1014 | static Lisp_Object Vmodule_environments; | 1010 | static Lisp_Object Vmodule_environments; |
| 1015 | 1011 | ||
| @@ -1050,7 +1046,7 @@ DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0, | |||
| 1050 | rt->private_members = &rt_priv; | 1046 | rt->private_members = &rt_priv; |
| 1051 | rt->get_environment = module_get_environment; | 1047 | rt->get_environment = module_get_environment; |
| 1052 | 1048 | ||
| 1053 | module_push_pointer (Vmodule_runtimes, rt); | 1049 | Vmodule_runtimes = Fcons (make_mint_ptr (rt), Vmodule_runtimes); |
| 1054 | ptrdiff_t count = SPECPDL_INDEX (); | 1050 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1055 | record_unwind_protect_ptr (finalize_runtime_unwind, rt); | 1051 | record_unwind_protect_ptr (finalize_runtime_unwind, rt); |
| 1056 | 1052 | ||
| @@ -1150,8 +1146,7 @@ module_assert_runtime (struct emacs_runtime *ert) | |||
| 1150 | if (! module_assertions) | 1146 | if (! module_assertions) |
| 1151 | return; | 1147 | return; |
| 1152 | ptrdiff_t count = 0; | 1148 | ptrdiff_t count = 0; |
| 1153 | for (Lisp_Object tail = module_objects (Vmodule_runtimes); CONSP (tail); | 1149 | for (Lisp_Object tail = Vmodule_runtimes; CONSP (tail); tail = XCDR (tail)) |
| 1154 | tail = XCDR (tail)) | ||
| 1155 | { | 1150 | { |
| 1156 | if (xmint_pointer (XCAR (tail)) == ert) | 1151 | if (xmint_pointer (XCAR (tail)) == ert) |
| 1157 | return; | 1152 | return; |
| @@ -1167,7 +1162,7 @@ module_assert_env (emacs_env *env) | |||
| 1167 | if (! module_assertions) | 1162 | if (! module_assertions) |
| 1168 | return; | 1163 | return; |
| 1169 | ptrdiff_t count = 0; | 1164 | ptrdiff_t count = 0; |
| 1170 | for (Lisp_Object tail = module_objects (Vmodule_environments); CONSP (tail); | 1165 | for (Lisp_Object tail = Vmodule_environments; CONSP (tail); |
| 1171 | tail = XCDR (tail)) | 1166 | tail = XCDR (tail)) |
| 1172 | { | 1167 | { |
| 1173 | if (xmint_pointer (XCAR (tail)) == env) | 1168 | if (xmint_pointer (XCAR (tail)) == env) |
| @@ -1215,83 +1210,6 @@ module_out_of_memory (emacs_env *env) | |||
| 1215 | } | 1210 | } |
| 1216 | 1211 | ||
| 1217 | 1212 | ||
| 1218 | /* Hash table helper functions. */ | ||
| 1219 | |||
| 1220 | /* Like HASH_TABLE_SIZE, but also works during garbage collection. */ | ||
| 1221 | |||
| 1222 | static ptrdiff_t | ||
| 1223 | module_gc_hash_table_size (const struct Lisp_Hash_Table *h) | ||
| 1224 | { | ||
| 1225 | ptrdiff_t size = gc_asize (h->next); | ||
| 1226 | eassert (0 <= size); | ||
| 1227 | return size; | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | /* Like (push NEWELT (gethash KEY TABLE)). */ | ||
| 1231 | |||
| 1232 | static void | ||
| 1233 | module_hash_push (Lisp_Object table, Lisp_Object key, Lisp_Object newelt) | ||
| 1234 | { | ||
| 1235 | /* Inline calls to Fgethash/Fputhash to avoid duplicate hash lookup. */ | ||
| 1236 | struct Lisp_Hash_Table *h = XHASH_TABLE (table); | ||
| 1237 | Lisp_Object hash; | ||
| 1238 | ptrdiff_t i = hash_lookup (h, key, &hash); | ||
| 1239 | if (i >= 0) | ||
| 1240 | set_hash_value_slot (h, i, Fcons (newelt, HASH_VALUE (h, i))); | ||
| 1241 | else | ||
| 1242 | hash_put (h, key, list1 (newelt), hash); | ||
| 1243 | } | ||
| 1244 | |||
| 1245 | /* Like (pop (gethash KEY TABLE)), but removes KEY from TABLE if the new value | ||
| 1246 | is nil. */ | ||
| 1247 | |||
| 1248 | static Lisp_Object | ||
| 1249 | module_hash_pop (Lisp_Object table, Lisp_Object key) | ||
| 1250 | { | ||
| 1251 | /* Inline calls to Fgethash/Fputhash to avoid duplicate hash lookup. */ | ||
| 1252 | struct Lisp_Hash_Table *h = XHASH_TABLE (table); | ||
| 1253 | Lisp_Object hash; | ||
| 1254 | ptrdiff_t i = hash_lookup (h, key, &hash); | ||
| 1255 | eassert (i >= 0); | ||
| 1256 | Lisp_Object value = HASH_VALUE (h, i); | ||
| 1257 | Lisp_Object rest = XCDR (value); | ||
| 1258 | if (NILP (rest)) | ||
| 1259 | hash_remove_from_table(h, key); | ||
| 1260 | else | ||
| 1261 | set_hash_value_slot (h, i, rest); | ||
| 1262 | return XCAR (value); | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | /* Returns the list of objects for the current thread in TABLE. The keys of | ||
| 1266 | TABLE are thread objects. */ | ||
| 1267 | |||
| 1268 | static Lisp_Object | ||
| 1269 | module_objects (Lisp_Object table) | ||
| 1270 | { | ||
| 1271 | return Fgethash (Fcurrent_thread (), table, Qnil); | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | /* Adds PTR to the front of the list of objects for the current thread in TABLE. | ||
| 1275 | The keys of TABLE are thread objects. */ | ||
| 1276 | |||
| 1277 | static void | ||
| 1278 | module_push_pointer (Lisp_Object table, void *ptr) | ||
| 1279 | { | ||
| 1280 | module_hash_push (table, Fcurrent_thread (), make_mint_ptr (ptr)); | ||
| 1281 | } | ||
| 1282 | |||
| 1283 | /* Removes the first object from the list of objects for the current thread in | ||
| 1284 | TABLE. The keys of TABLE are thread objects. Checks that the first object | ||
| 1285 | is a pointer with value PTR. */ | ||
| 1286 | |||
| 1287 | static void | ||
| 1288 | module_pop_pointer (Lisp_Object table, void *ptr) | ||
| 1289 | { | ||
| 1290 | Lisp_Object value = module_hash_pop (table, Fcurrent_thread ()); | ||
| 1291 | eassert (xmint_pointer (value) == ptr); | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | |||
| 1295 | /* Value conversion. */ | 1213 | /* Value conversion. */ |
| 1296 | 1214 | ||
| 1297 | /* Convert an `emacs_value' to the corresponding internal object. | 1215 | /* Convert an `emacs_value' to the corresponding internal object. |
| @@ -1308,7 +1226,7 @@ value_to_lisp (emacs_value v) | |||
| 1308 | environments. */ | 1226 | environments. */ |
| 1309 | ptrdiff_t num_environments = 0; | 1227 | ptrdiff_t num_environments = 0; |
| 1310 | ptrdiff_t num_values = 0; | 1228 | ptrdiff_t num_values = 0; |
| 1311 | for (Lisp_Object environments = module_objects (Vmodule_environments); | 1229 | for (Lisp_Object environments = Vmodule_environments; |
| 1312 | CONSP (environments); environments = XCDR (environments)) | 1230 | CONSP (environments); environments = XCDR (environments)) |
| 1313 | { | 1231 | { |
| 1314 | emacs_env *env = xmint_pointer (XCAR (environments)); | 1232 | emacs_env *env = xmint_pointer (XCAR (environments)); |
| @@ -1408,19 +1326,16 @@ allocate_emacs_value (emacs_env *env, struct emacs_value_storage *storage, | |||
| 1408 | void | 1326 | void |
| 1409 | mark_modules (void) | 1327 | mark_modules (void) |
| 1410 | { | 1328 | { |
| 1411 | const struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_environments); | 1329 | for (Lisp_Object tem = Vmodule_environments; CONSP (tem); tem = XCDR (tem)) |
| 1412 | /* Can't use HASH_TABLE_SIZE because we are in the mark phase of the GC. */ | 1330 | { |
| 1413 | for (ptrdiff_t i = 0; i < module_gc_hash_table_size (h); ++i) | 1331 | emacs_env *env = xmint_pointer (XCAR (tem)); |
| 1414 | if (!EQ (HASH_KEY (h, i), Qunbound)) | 1332 | struct emacs_env_private *priv = env->private_members; |
| 1415 | for (Lisp_Object tem = HASH_VALUE (h, i); CONSP (tem); tem = XCDR (tem)) | 1333 | for (struct emacs_value_frame *frame = &priv->storage.initial; |
| 1416 | { | 1334 | frame != NULL; |
| 1417 | emacs_env *env = xmint_pointer (XCAR (tem)); | 1335 | frame = frame->next) |
| 1418 | struct emacs_env_private *priv = env->private_members; | 1336 | for (int i = 0; i < frame->offset; ++i) |
| 1419 | for (struct emacs_value_frame *frame = &priv->storage.initial; | 1337 | mark_object (frame->objects[i].v); |
| 1420 | frame != NULL; frame = frame->next) | 1338 | } |
| 1421 | for (int i = 0; i < frame->offset; ++i) | ||
| 1422 | mark_object (frame->objects[i].v); | ||
| 1423 | } | ||
| 1424 | } | 1339 | } |
| 1425 | 1340 | ||
| 1426 | 1341 | ||
| @@ -1475,7 +1390,7 @@ initialize_environment (emacs_env *env, struct emacs_env_private *priv) | |||
| 1475 | env->make_time = module_make_time; | 1390 | env->make_time = module_make_time; |
| 1476 | env->extract_big_integer = module_extract_big_integer; | 1391 | env->extract_big_integer = module_extract_big_integer; |
| 1477 | env->make_big_integer = module_make_big_integer; | 1392 | env->make_big_integer = module_make_big_integer; |
| 1478 | module_push_pointer (Vmodule_environments, env); | 1393 | Vmodule_environments = Fcons (make_mint_ptr (env), Vmodule_environments); |
| 1479 | return env; | 1394 | return env; |
| 1480 | } | 1395 | } |
| 1481 | 1396 | ||
| @@ -1485,7 +1400,8 @@ static void | |||
| 1485 | finalize_environment (emacs_env *env) | 1400 | finalize_environment (emacs_env *env) |
| 1486 | { | 1401 | { |
| 1487 | finalize_storage (&env->private_members->storage); | 1402 | finalize_storage (&env->private_members->storage); |
| 1488 | module_pop_pointer (Vmodule_environments, env); | 1403 | eassert (xmint_pointer (XCAR (Vmodule_environments)) == env); |
| 1404 | Vmodule_environments = XCDR (Vmodule_environments); | ||
| 1489 | } | 1405 | } |
| 1490 | 1406 | ||
| 1491 | static void | 1407 | static void |
| @@ -1498,8 +1414,9 @@ static void | |||
| 1498 | finalize_runtime_unwind (void *raw_ert) | 1414 | finalize_runtime_unwind (void *raw_ert) |
| 1499 | { | 1415 | { |
| 1500 | struct emacs_runtime *ert = raw_ert; | 1416 | struct emacs_runtime *ert = raw_ert; |
| 1417 | eassert (xmint_pointer (XCAR (Vmodule_runtimes)) == ert); | ||
| 1418 | Vmodule_runtimes = XCDR (Vmodule_runtimes); | ||
| 1501 | finalize_environment (ert->private_members->env); | 1419 | finalize_environment (ert->private_members->env); |
| 1502 | module_pop_pointer (Vmodule_runtimes, ert); | ||
| 1503 | } | 1420 | } |
| 1504 | 1421 | ||
| 1505 | 1422 | ||
| @@ -1589,14 +1506,10 @@ syms_of_module (void) | |||
| 1589 | Qnil, false); | 1506 | Qnil, false); |
| 1590 | 1507 | ||
| 1591 | staticpro (&Vmodule_runtimes); | 1508 | staticpro (&Vmodule_runtimes); |
| 1592 | Vmodule_runtimes | 1509 | Vmodule_runtimes = Qnil; |
| 1593 | = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE, | ||
| 1594 | DEFAULT_REHASH_THRESHOLD, Qnil, false); | ||
| 1595 | 1510 | ||
| 1596 | staticpro (&Vmodule_environments); | 1511 | staticpro (&Vmodule_environments); |
| 1597 | Vmodule_environments | 1512 | Vmodule_environments = Qnil; |
| 1598 | = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE, | ||
| 1599 | DEFAULT_REHASH_THRESHOLD, Qnil, false); | ||
| 1600 | 1513 | ||
| 1601 | DEFSYM (Qmodule_load_failed, "module-load-failed"); | 1514 | DEFSYM (Qmodule_load_failed, "module-load-failed"); |
| 1602 | Fput (Qmodule_load_failed, Qerror_conditions, | 1515 | Fput (Qmodule_load_failed, Qerror_conditions, |