diff options
| author | Paul Eggert | 2013-10-02 23:31:06 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-10-02 23:31:06 -0700 |
| commit | b52f569dcfc5c2e1b764c89d27ea8699a44228e6 (patch) | |
| tree | 0996ab30a12176895bc5f29aa704623d117a1f93 /src | |
| parent | adf2aa61404305e58e71cde0193bb650aff2c4b3 (diff) | |
| download | emacs-b52f569dcfc5c2e1b764c89d27ea8699a44228e6.tar.gz emacs-b52f569dcfc5c2e1b764c89d27ea8699a44228e6.zip | |
* eval.c (clobbered_eassert): New macro.
(internal_catch, internal_condition_case)
(internal_condition_case_1, internal_condition_case_2)
(internal_condition_case_n): Use it instead of eassert
when the argument contains locals clobbered by longjmp.
Don't use clobbered locals outside of clobbered_eassert.
(internal_lisp_condition_case): Use a volatile variable
to work around a local variable's getting clobbered.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 11 | ||||
| -rw-r--r-- | src/eval.c | 39 |
2 files changed, 34 insertions, 16 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 4b1bfc75187..8a0d8863548 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2013-10-03 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * eval.c (clobbered_eassert): New macro. | ||
| 4 | (internal_catch, internal_condition_case) | ||
| 5 | (internal_condition_case_1, internal_condition_case_2) | ||
| 6 | (internal_condition_case_n): Use it instead of eassert | ||
| 7 | when the argument contains locals clobbered by longjmp. | ||
| 8 | Don't use clobbered locals outside of clobbered_eassert. | ||
| 9 | (internal_lisp_condition_case): Use a volatile variable | ||
| 10 | to work around a local variable's getting clobbered. | ||
| 11 | |||
| 1 | 2013-10-03 Stefan Monnier <monnier@iro.umontreal.ca> | 12 | 2013-10-03 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 13 | ||
| 3 | * lisp.h (struct handler): Merge struct handler and struct catchtag. | 14 | * lisp.h (struct handler): Merge struct handler and struct catchtag. |
diff --git a/src/eval.c b/src/eval.c index 5526b28b2e0..3b4dc9a88d1 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1072,6 +1072,12 @@ usage: (catch TAG BODY...) */) | |||
| 1072 | return internal_catch (tag, Fprogn, XCDR (args)); | 1072 | return internal_catch (tag, Fprogn, XCDR (args)); |
| 1073 | } | 1073 | } |
| 1074 | 1074 | ||
| 1075 | /* Assert that E is true, as a comment only. Use this instead of | ||
| 1076 | eassert (E) when E contains variables that might be clobbered by a | ||
| 1077 | longjmp. */ | ||
| 1078 | |||
| 1079 | #define clobbered_eassert(E) ((void) 0) | ||
| 1080 | |||
| 1075 | /* Set up a catch, then call C function FUNC on argument ARG. | 1081 | /* Set up a catch, then call C function FUNC on argument ARG. |
| 1076 | FUNC should return a Lisp_Object. | 1082 | FUNC should return a Lisp_Object. |
| 1077 | This is how catches are done from within C code. */ | 1083 | This is how catches are done from within C code. */ |
| @@ -1089,14 +1095,14 @@ internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object | |||
| 1089 | if (! sys_setjmp (c->jmp)) | 1095 | if (! sys_setjmp (c->jmp)) |
| 1090 | { | 1096 | { |
| 1091 | Lisp_Object val = (*func) (arg); | 1097 | Lisp_Object val = (*func) (arg); |
| 1092 | eassert (handlerlist == c); | 1098 | clobbered_eassert (handlerlist == c); |
| 1093 | handlerlist = c->next; | 1099 | handlerlist = handlerlist->next; |
| 1094 | return val; | 1100 | return val; |
| 1095 | } | 1101 | } |
| 1096 | else | 1102 | else |
| 1097 | { /* Throw works by a longjmp that comes right here. */ | 1103 | { /* Throw works by a longjmp that comes right here. */ |
| 1098 | Lisp_Object val = handlerlist->val; | 1104 | Lisp_Object val = handlerlist->val; |
| 1099 | eassert (handlerlist == c); | 1105 | clobbered_eassert (handlerlist == c); |
| 1100 | handlerlist = handlerlist->next; | 1106 | handlerlist = handlerlist->next; |
| 1101 | return val; | 1107 | return val; |
| 1102 | } | 1108 | } |
| @@ -1252,6 +1258,7 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform, | |||
| 1252 | be added to handlerlist last. So we build in `clauses' a table that | 1258 | be added to handlerlist last. So we build in `clauses' a table that |
| 1253 | contains `handlers' but in reverse order. */ | 1259 | contains `handlers' but in reverse order. */ |
| 1254 | Lisp_Object *clauses = alloca (clausenb * sizeof (Lisp_Object *)); | 1260 | Lisp_Object *clauses = alloca (clausenb * sizeof (Lisp_Object *)); |
| 1261 | Lisp_Object *volatile clauses_volatile = clauses; | ||
| 1255 | int i = clausenb; | 1262 | int i = clausenb; |
| 1256 | for (val = handlers; CONSP (val); val = XCDR (val)) | 1263 | for (val = handlers; CONSP (val); val = XCDR (val)) |
| 1257 | clauses[--i] = XCAR (val); | 1264 | clauses[--i] = XCAR (val); |
| @@ -1266,7 +1273,7 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform, | |||
| 1266 | { | 1273 | { |
| 1267 | ptrdiff_t count = SPECPDL_INDEX (); | 1274 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1268 | Lisp_Object val = handlerlist->val; | 1275 | Lisp_Object val = handlerlist->val; |
| 1269 | Lisp_Object *chosen_clause = clauses; | 1276 | Lisp_Object *chosen_clause = clauses_volatile; |
| 1270 | for (c = handlerlist->next; c != oldhandlerlist; c = c->next) | 1277 | for (c = handlerlist->next; c != oldhandlerlist; c = c->next) |
| 1271 | chosen_clause++; | 1278 | chosen_clause++; |
| 1272 | handlerlist = oldhandlerlist; | 1279 | handlerlist = oldhandlerlist; |
| @@ -1316,14 +1323,14 @@ internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers, | |||
| 1316 | if (sys_setjmp (c->jmp)) | 1323 | if (sys_setjmp (c->jmp)) |
| 1317 | { | 1324 | { |
| 1318 | Lisp_Object val = handlerlist->val; | 1325 | Lisp_Object val = handlerlist->val; |
| 1319 | eassert (handlerlist == c); | 1326 | clobbered_eassert (handlerlist == c); |
| 1320 | handlerlist = handlerlist->next; | 1327 | handlerlist = handlerlist->next; |
| 1321 | return (*hfun) (val); | 1328 | return (*hfun) (val); |
| 1322 | } | 1329 | } |
| 1323 | 1330 | ||
| 1324 | val = (*bfun) (); | 1331 | val = (*bfun) (); |
| 1325 | eassert (handlerlist == c); | 1332 | clobbered_eassert (handlerlist == c); |
| 1326 | handlerlist = c->next; | 1333 | handlerlist = handlerlist->next; |
| 1327 | return val; | 1334 | return val; |
| 1328 | } | 1335 | } |
| 1329 | 1336 | ||
| @@ -1340,14 +1347,14 @@ internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg, | |||
| 1340 | if (sys_setjmp (c->jmp)) | 1347 | if (sys_setjmp (c->jmp)) |
| 1341 | { | 1348 | { |
| 1342 | Lisp_Object val = handlerlist->val; | 1349 | Lisp_Object val = handlerlist->val; |
| 1343 | eassert (handlerlist == c); | 1350 | clobbered_eassert (handlerlist == c); |
| 1344 | handlerlist = handlerlist->next; | 1351 | handlerlist = handlerlist->next; |
| 1345 | return (*hfun) (val); | 1352 | return (*hfun) (val); |
| 1346 | } | 1353 | } |
| 1347 | 1354 | ||
| 1348 | val = (*bfun) (arg); | 1355 | val = (*bfun) (arg); |
| 1349 | eassert (handlerlist == c); | 1356 | clobbered_eassert (handlerlist == c); |
| 1350 | handlerlist = c->next; | 1357 | handlerlist = handlerlist->next; |
| 1351 | return val; | 1358 | return val; |
| 1352 | } | 1359 | } |
| 1353 | 1360 | ||
| @@ -1368,14 +1375,14 @@ internal_condition_case_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object), | |||
| 1368 | if (sys_setjmp (c->jmp)) | 1375 | if (sys_setjmp (c->jmp)) |
| 1369 | { | 1376 | { |
| 1370 | Lisp_Object val = handlerlist->val; | 1377 | Lisp_Object val = handlerlist->val; |
| 1371 | eassert (handlerlist == c); | 1378 | clobbered_eassert (handlerlist == c); |
| 1372 | handlerlist = handlerlist->next; | 1379 | handlerlist = handlerlist->next; |
| 1373 | return (*hfun) (val); | 1380 | return (*hfun) (val); |
| 1374 | } | 1381 | } |
| 1375 | 1382 | ||
| 1376 | val = (*bfun) (arg1, arg2); | 1383 | val = (*bfun) (arg1, arg2); |
| 1377 | eassert (handlerlist == c); | 1384 | clobbered_eassert (handlerlist == c); |
| 1378 | handlerlist = c->next; | 1385 | handlerlist = handlerlist->next; |
| 1379 | return val; | 1386 | return val; |
| 1380 | } | 1387 | } |
| 1381 | 1388 | ||
| @@ -1398,14 +1405,14 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *), | |||
| 1398 | if (sys_setjmp (c->jmp)) | 1405 | if (sys_setjmp (c->jmp)) |
| 1399 | { | 1406 | { |
| 1400 | Lisp_Object val = handlerlist->val; | 1407 | Lisp_Object val = handlerlist->val; |
| 1401 | eassert (handlerlist == c); | 1408 | clobbered_eassert (handlerlist == c); |
| 1402 | handlerlist = handlerlist->next; | 1409 | handlerlist = handlerlist->next; |
| 1403 | return (*hfun) (val, nargs, args); | 1410 | return (*hfun) (val, nargs, args); |
| 1404 | } | 1411 | } |
| 1405 | 1412 | ||
| 1406 | val = (*bfun) (nargs, args); | 1413 | val = (*bfun) (nargs, args); |
| 1407 | eassert (handlerlist == c); | 1414 | clobbered_eassert (handlerlist == c); |
| 1408 | handlerlist = c->next; | 1415 | handlerlist = handlerlist->next; |
| 1409 | return val; | 1416 | return val; |
| 1410 | } | 1417 | } |
| 1411 | 1418 | ||