diff options
| author | Paul Eggert | 2016-08-09 00:37:38 -0700 |
|---|---|---|
| committer | Paul Eggert | 2016-08-09 01:31:20 -0700 |
| commit | 4d07064a4374a2f74a256e64027ef80f355c7a7e (patch) | |
| tree | 3541303ac3482dda188b02fe4f5a2459516d164e /src/bytecode.c | |
| parent | 846e88eb99ddb66f0a949d17a0483a977d748305 (diff) | |
| download | emacs-4d07064a4374a2f74a256e64027ef80f355c7a7e.tar.gz emacs-4d07064a4374a2f74a256e64027ef80f355c7a7e.zip | |
Simplify BYTE_CODE_SAFE checking
* src/bytecode.c (BYTE_CODE_SAFE): Default to false, so that it
can be used outside #if. All uses of ‘defined BYTE_CODE_SAFE’
changed to ‘BYTE_CODE_SAFE’. Use BYTE_CODE_SAFE in plain
expressions instead of #if expressions when this is easy.
(struct byte_stack) [BYTE_CODE_SAFE]: Remove member ‘bottom’,
as it is no longer needed.
(exec_byte_code): Omit #if BYTE_CODE_SAFE when this is easy.
Simplify stack-overflow checking when BYTE_CODE_SAFE.
Diffstat (limited to 'src/bytecode.c')
| -rw-r--r-- | src/bytecode.c | 79 |
1 files changed, 21 insertions, 58 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index ff436533e4c..6be17e3fd3e 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -32,13 +32,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 32 | # pragma GCC diagnostic ignored "-Wclobbered" | 32 | # pragma GCC diagnostic ignored "-Wclobbered" |
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
| 35 | /* | 35 | /* Define BYTE_CODE_SAFE true to enable some minor sanity checking, |
| 36 | * define BYTE_CODE_SAFE to enable some minor sanity checking (useful for | 36 | useful for debugging the byte compiler. It defaults to false. */ |
| 37 | * debugging the byte compiler...) | 37 | |
| 38 | * | 38 | #ifndef BYTE_CODE_SAFE |
| 39 | * define BYTE_CODE_METER to enable generation of a byte-op usage histogram. | 39 | # define BYTE_CODE_SAFE false |
| 40 | */ | 40 | #endif |
| 41 | /* #define BYTE_CODE_SAFE */ | 41 | |
| 42 | /* Define BYTE_CODE_METER to generate a byte-op usage histogram. */ | ||
| 42 | /* #define BYTE_CODE_METER */ | 43 | /* #define BYTE_CODE_METER */ |
| 43 | 44 | ||
| 44 | /* If BYTE_CODE_THREADED is defined, then the interpreter will be | 45 | /* If BYTE_CODE_THREADED is defined, then the interpreter will be |
| @@ -46,7 +47,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 46 | as currently implemented, is incompatible with BYTE_CODE_SAFE and | 47 | as currently implemented, is incompatible with BYTE_CODE_SAFE and |
| 47 | BYTE_CODE_METER. */ | 48 | BYTE_CODE_METER. */ |
| 48 | #if (defined __GNUC__ && !defined __STRICT_ANSI__ \ | 49 | #if (defined __GNUC__ && !defined __STRICT_ANSI__ \ |
| 49 | && !defined BYTE_CODE_SAFE && !defined BYTE_CODE_METER) | 50 | && !BYTE_CODE_SAFE && !defined BYTE_CODE_METER) |
| 50 | #define BYTE_CODE_THREADED | 51 | #define BYTE_CODE_THREADED |
| 51 | #endif | 52 | #endif |
| 52 | 53 | ||
| @@ -274,7 +275,7 @@ enum byte_code_op | |||
| 274 | BYTE_CODES | 275 | BYTE_CODES |
| 275 | #undef DEFINE | 276 | #undef DEFINE |
| 276 | 277 | ||
| 277 | #ifdef BYTE_CODE_SAFE | 278 | #if BYTE_CODE_SAFE |
| 278 | Bscan_buffer = 0153, /* No longer generated as of v18. */ | 279 | Bscan_buffer = 0153, /* No longer generated as of v18. */ |
| 279 | Bset_mark = 0163, /* this loser is no longer generated as of v18 */ | 280 | Bset_mark = 0163, /* this loser is no longer generated as of v18 */ |
| 280 | #endif | 281 | #endif |
| @@ -289,12 +290,6 @@ struct byte_stack | |||
| 289 | and is relocated when that string is relocated. */ | 290 | and is relocated when that string is relocated. */ |
| 290 | const unsigned char *pc; | 291 | const unsigned char *pc; |
| 291 | 292 | ||
| 292 | /* bottom of stack. The bottom points to an area of memory | ||
| 293 | allocated with alloca in Fbyte_code. */ | ||
| 294 | #ifdef BYTE_CODE_SAFE | ||
| 295 | Lisp_Object *bottom; | ||
| 296 | #endif | ||
| 297 | |||
| 298 | /* The string containing the byte-code, and its current address. | 293 | /* The string containing the byte-code, and its current address. |
| 299 | Storing this here protects it from GC. */ | 294 | Storing this here protects it from GC. */ |
| 300 | Lisp_Object byte_string; | 295 | Lisp_Object byte_string; |
| @@ -334,7 +329,7 @@ relocate_byte_stack (void) | |||
| 334 | 329 | ||
| 335 | /* Fetch the next byte from the bytecode stream. */ | 330 | /* Fetch the next byte from the bytecode stream. */ |
| 336 | 331 | ||
| 337 | #ifdef BYTE_CODE_SAFE | 332 | #if BYTE_CODE_SAFE |
| 338 | #define FETCH (eassert (stack.byte_string_start == SDATA (stack.byte_string)), *stack.pc++) | 333 | #define FETCH (eassert (stack.byte_string_start == SDATA (stack.byte_string)), *stack.pc++) |
| 339 | #else | 334 | #else |
| 340 | #define FETCH *stack.pc++ | 335 | #define FETCH *stack.pc++ |
| @@ -365,16 +360,8 @@ relocate_byte_stack (void) | |||
| 365 | 360 | ||
| 366 | /* Check for jumping out of range. */ | 361 | /* Check for jumping out of range. */ |
| 367 | 362 | ||
| 368 | #ifdef BYTE_CODE_SAFE | ||
| 369 | |||
| 370 | #define CHECK_RANGE(ARG) \ | 363 | #define CHECK_RANGE(ARG) \ |
| 371 | if (ARG >= bytestr_length) emacs_abort () | 364 | (BYTE_CODE_SAFE && bytestr_length <= (ARG) ? emacs_abort () : (void) 0) |
| 372 | |||
| 373 | #else /* not BYTE_CODE_SAFE */ | ||
| 374 | |||
| 375 | #define CHECK_RANGE(ARG) | ||
| 376 | |||
| 377 | #endif /* not BYTE_CODE_SAFE */ | ||
| 378 | 365 | ||
| 379 | /* A version of the QUIT macro which makes sure that the stack top is | 366 | /* A version of the QUIT macro which makes sure that the stack top is |
| 380 | set before signaling `quit'. */ | 367 | set before signaling `quit'. */ |
| @@ -431,11 +418,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 431 | int op; | 418 | int op; |
| 432 | /* Lisp_Object v1, v2; */ | 419 | /* Lisp_Object v1, v2; */ |
| 433 | Lisp_Object *vectorp; | 420 | Lisp_Object *vectorp; |
| 434 | #ifdef BYTE_CODE_SAFE | ||
| 435 | ptrdiff_t const_length; | 421 | ptrdiff_t const_length; |
| 436 | Lisp_Object *stacke; | ||
| 437 | ptrdiff_t bytestr_length; | 422 | ptrdiff_t bytestr_length; |
| 438 | #endif | ||
| 439 | struct byte_stack stack; | 423 | struct byte_stack stack; |
| 440 | Lisp_Object *top; | 424 | Lisp_Object *top; |
| 441 | Lisp_Object result; | 425 | Lisp_Object result; |
| @@ -445,9 +429,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 445 | CHECK_VECTOR (vector); | 429 | CHECK_VECTOR (vector); |
| 446 | CHECK_NATNUM (maxdepth); | 430 | CHECK_NATNUM (maxdepth); |
| 447 | 431 | ||
| 448 | #ifdef BYTE_CODE_SAFE | ||
| 449 | const_length = ASIZE (vector); | 432 | const_length = ASIZE (vector); |
| 450 | #endif | ||
| 451 | 433 | ||
| 452 | if (STRING_MULTIBYTE (bytestr)) | 434 | if (STRING_MULTIBYTE (bytestr)) |
| 453 | /* BYTESTR must have been produced by Emacs 20.2 or the earlier | 435 | /* BYTESTR must have been produced by Emacs 20.2 or the earlier |
| @@ -457,26 +439,20 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 457 | convert them back to the originally intended unibyte form. */ | 439 | convert them back to the originally intended unibyte form. */ |
| 458 | bytestr = Fstring_as_unibyte (bytestr); | 440 | bytestr = Fstring_as_unibyte (bytestr); |
| 459 | 441 | ||
| 460 | #ifdef BYTE_CODE_SAFE | ||
| 461 | bytestr_length = SBYTES (bytestr); | 442 | bytestr_length = SBYTES (bytestr); |
| 462 | #endif | ||
| 463 | vectorp = XVECTOR (vector)->contents; | 443 | vectorp = XVECTOR (vector)->contents; |
| 464 | 444 | ||
| 465 | stack.byte_string = bytestr; | 445 | stack.byte_string = bytestr; |
| 466 | stack.pc = stack.byte_string_start = SDATA (bytestr); | 446 | stack.pc = stack.byte_string_start = SDATA (bytestr); |
| 467 | if (MAX_ALLOCA / word_size <= XFASTINT (maxdepth)) | 447 | if (MAX_ALLOCA / word_size <= XFASTINT (maxdepth)) |
| 468 | memory_full (SIZE_MAX); | 448 | memory_full (SIZE_MAX); |
| 469 | top = alloca ((XFASTINT (maxdepth) + 1) * sizeof *top); | 449 | int stack_items = XFASTINT (maxdepth) + 1; |
| 470 | #ifdef BYTE_CODE_SAFE | 450 | Lisp_Object *stack_base = alloca (stack_items * sizeof *top); |
| 471 | stack.bottom = top + 1; | 451 | Lisp_Object *stack_lim = stack_base + stack_items; |
| 472 | #endif | 452 | top = stack_base; |
| 473 | stack.next = byte_stack_list; | 453 | stack.next = byte_stack_list; |
| 474 | byte_stack_list = &stack; | 454 | byte_stack_list = &stack; |
| 475 | 455 | ||
| 476 | #ifdef BYTE_CODE_SAFE | ||
| 477 | stacke = stack.bottom - 1 + XFASTINT (maxdepth); | ||
| 478 | #endif | ||
| 479 | |||
| 480 | if (!NILP (args_template)) | 456 | if (!NILP (args_template)) |
| 481 | { | 457 | { |
| 482 | eassert (INTEGERP (args_template)); | 458 | eassert (INTEGERP (args_template)); |
| @@ -501,12 +477,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 501 | 477 | ||
| 502 | while (1) | 478 | while (1) |
| 503 | { | 479 | { |
| 504 | #ifdef BYTE_CODE_SAFE | 480 | if (BYTE_CODE_SAFE && ! (stack_base <= top && top < stack_lim)) |
| 505 | if (top > stacke) | ||
| 506 | emacs_abort (); | 481 | emacs_abort (); |
| 507 | else if (top < stack.bottom - 1) | ||
| 508 | emacs_abort (); | ||
| 509 | #endif | ||
| 510 | 482 | ||
| 511 | #ifdef BYTE_CODE_METER | 483 | #ifdef BYTE_CODE_METER |
| 512 | prev_op = this_op; | 484 | prev_op = this_op; |
| @@ -1643,7 +1615,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1643 | TOP = INTEGERP (TOP) ? Qt : Qnil; | 1615 | TOP = INTEGERP (TOP) ? Qt : Qnil; |
| 1644 | NEXT; | 1616 | NEXT; |
| 1645 | 1617 | ||
| 1646 | #ifdef BYTE_CODE_SAFE | 1618 | #if BYTE_CODE_SAFE |
| 1647 | /* These are intentionally written using 'case' syntax, | 1619 | /* These are intentionally written using 'case' syntax, |
| 1648 | because they are incompatible with the threaded | 1620 | because they are incompatible with the threaded |
| 1649 | interpreter. */ | 1621 | interpreter. */ |
| @@ -1713,19 +1685,10 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1713 | 1685 | ||
| 1714 | CASE_DEFAULT | 1686 | CASE_DEFAULT |
| 1715 | CASE (Bconstant): | 1687 | CASE (Bconstant): |
| 1716 | #ifdef BYTE_CODE_SAFE | 1688 | if (BYTE_CODE_SAFE |
| 1717 | if (op < Bconstant) | 1689 | && ! (Bconstant <= op && op < Bconstant + const_length)) |
| 1718 | { | 1690 | emacs_abort (); |
| 1719 | emacs_abort (); | ||
| 1720 | } | ||
| 1721 | if ((op -= Bconstant) >= const_length) | ||
| 1722 | { | ||
| 1723 | emacs_abort (); | ||
| 1724 | } | ||
| 1725 | PUSH (vectorp[op]); | ||
| 1726 | #else | ||
| 1727 | PUSH (vectorp[op - Bconstant]); | 1691 | PUSH (vectorp[op - Bconstant]); |
| 1728 | #endif | ||
| 1729 | NEXT; | 1692 | NEXT; |
| 1730 | } | 1693 | } |
| 1731 | } | 1694 | } |