diff options
Diffstat (limited to 'src/bytecode.c')
| -rw-r--r-- | src/bytecode.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index 37da0858ab4..0d0a28cd0bb 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -331,6 +331,7 @@ If the third argument is incorrect, Emacs may crash. */) | |||
| 331 | the original unibyte form. */ | 331 | the original unibyte form. */ |
| 332 | bytestr = Fstring_as_unibyte (bytestr); | 332 | bytestr = Fstring_as_unibyte (bytestr); |
| 333 | } | 333 | } |
| 334 | pin_string (bytestr); // Bytecode must be immovable. | ||
| 334 | 335 | ||
| 335 | return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL); | 336 | return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL); |
| 336 | } | 337 | } |
| @@ -358,22 +359,28 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 358 | #endif | 359 | #endif |
| 359 | 360 | ||
| 360 | eassert (!STRING_MULTIBYTE (bytestr)); | 361 | eassert (!STRING_MULTIBYTE (bytestr)); |
| 362 | eassert (string_immovable_p (bytestr)); | ||
| 361 | 363 | ||
| 362 | ptrdiff_t const_length = ASIZE (vector); | 364 | ptrdiff_t const_length = ASIZE (vector); |
| 363 | ptrdiff_t bytestr_length = SCHARS (bytestr); | 365 | ptrdiff_t bytestr_length = SCHARS (bytestr); |
| 364 | Lisp_Object *vectorp = XVECTOR (vector)->contents; | 366 | Lisp_Object *vectorp = XVECTOR (vector)->contents; |
| 365 | 367 | ||
| 366 | unsigned char quitcounter = 1; | 368 | unsigned char quitcounter = 1; |
| 367 | EMACS_INT stack_items = XFIXNAT (maxdepth) + 1; | 369 | /* Allocate two more slots than required, because... */ |
| 370 | EMACS_INT stack_items = XFIXNAT (maxdepth) + 2; | ||
| 368 | USE_SAFE_ALLOCA; | 371 | USE_SAFE_ALLOCA; |
| 369 | void *alloc; | 372 | void *alloc; |
| 370 | SAFE_ALLOCA_LISP_EXTRA (alloc, stack_items, bytestr_length); | 373 | SAFE_ALLOCA_LISP (alloc, stack_items); |
| 371 | Lisp_Object *stack_base = alloc; | 374 | Lisp_Object *stack_base = alloc; |
| 372 | Lisp_Object *top = stack_base; | 375 | /* ... we plonk BYTESTR and VECTOR there to ensure that they survive |
| 373 | *top = vector; /* Ensure VECTOR survives GC (Bug#33014). */ | 376 | GC (bug#33014), since these variables aren't used directly beyond |
| 374 | Lisp_Object *stack_lim = stack_base + stack_items; | 377 | the interpreter prologue and wouldn't be found in the stack frame |
| 375 | unsigned char const *bytestr_data = memcpy (stack_lim, | 378 | otherwise. */ |
| 376 | SDATA (bytestr), bytestr_length); | 379 | stack_base[0] = bytestr; |
| 380 | stack_base[1] = vector; | ||
| 381 | Lisp_Object *top = stack_base + 1; | ||
| 382 | Lisp_Object *stack_lim = top + stack_items; | ||
| 383 | unsigned char const *bytestr_data = SDATA (bytestr); | ||
| 377 | unsigned char const *pc = bytestr_data; | 384 | unsigned char const *pc = bytestr_data; |
| 378 | ptrdiff_t count = SPECPDL_INDEX (); | 385 | ptrdiff_t count = SPECPDL_INDEX (); |
| 379 | 386 | ||
| @@ -1564,6 +1571,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1564 | 1571 | ||
| 1565 | exit: | 1572 | exit: |
| 1566 | 1573 | ||
| 1574 | eassert (SDATA (bytestr) == bytestr_data); | ||
| 1575 | |||
| 1567 | /* Binds and unbinds are supposed to be compiled balanced. */ | 1576 | /* Binds and unbinds are supposed to be compiled balanced. */ |
| 1568 | if (SPECPDL_INDEX () != count) | 1577 | if (SPECPDL_INDEX () != count) |
| 1569 | { | 1578 | { |