aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias EngdegÄrd2022-02-02 16:51:43 +0100
committerMattias EngdegÄrd2022-02-12 18:18:58 +0100
commit297520852f4f0e11a34a8a867c13fdf03d83eafd (patch)
tree590f2992b2000c3c4945d8b908a3974848fce636 /src
parenta8245e122075175df2f124b20e9e5b1b583eff89 (diff)
downloademacs-297520852f4f0e11a34a8a867c13fdf03d83eafd.tar.gz
emacs-297520852f4f0e11a34a8a867c13fdf03d83eafd.zip
Turn specpdl_ref into a type of its own
Wrap the specpdl_ref contents in a struct, which gives us some very useful type checking to make sure that all code that assumed integral specpdl refs has been converted. We only do this on 64-bit platforms, since those tend to have modern ABIs where small structs are optimised as scalars. In other words, this change should not affect the compiled code. * src/lisp.h (specpdl_ref): Now a struct on 64-bit platforms. (wrap_specpdl_ref, unwrap_specpdl_ref): New. (specpdl_count_to_ref, specpdl_ref_to_count) (specpdl_ref_eq, specpdl_ref_lt) (specpdl_ref_valid_p, make_invalid_specpdl_ref): Use new wrappers.
Diffstat (limited to 'src')
-rw-r--r--src/lisp.h46
1 files changed, 40 insertions, 6 deletions
diff --git a/src/lisp.h b/src/lisp.h
index 3ff9dccc4ec..9b82307f675 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3350,45 +3350,79 @@ union specbinding
3350 } bt; 3350 } bt;
3351 }; 3351 };
3352 3352
3353/* We use 64-bit platforms as a proxy for ones with ABIs that treat
3354 small structs efficiently. */
3355#if SIZE_MAX > 0xffffffff
3356#define WRAP_SPECPDL_REF 1
3357#endif
3358
3353/* Abstract reference to to a specpdl entry. */ 3359/* Abstract reference to to a specpdl entry. */
3360#ifdef WRAP_SPECPDL_REF
3361/* Use a proper type for specpdl_ref if it does not make the code slower,
3362 since the type checking is quite useful. */
3363typedef struct { ptrdiff_t n; } specpdl_ref;
3364#else
3354typedef ptrdiff_t specpdl_ref; 3365typedef ptrdiff_t specpdl_ref;
3366#endif
3355 3367
3368/* Internal use only. */
3356INLINE specpdl_ref 3369INLINE specpdl_ref
3357specpdl_count_to_ref (ptrdiff_t count) 3370wrap_specpdl_ref (ptrdiff_t count)
3358{ 3371{
3372#ifdef WRAP_SPECPDL_REF
3373 return (specpdl_ref) {.n = count};
3374#else
3359 return count; 3375 return count;
3376#endif
3360} 3377}
3361 3378
3379/* Internal use only. */
3362INLINE ptrdiff_t 3380INLINE ptrdiff_t
3363specpdl_ref_to_count (specpdl_ref ref) 3381unwrap_specpdl_ref (specpdl_ref ref)
3364{ 3382{
3383#ifdef WRAP_SPECPDL_REF
3384 return ref.n;
3385#else
3365 return ref; 3386 return ref;
3387#endif
3388}
3389
3390INLINE specpdl_ref
3391specpdl_count_to_ref (ptrdiff_t count)
3392{
3393 return wrap_specpdl_ref (count);
3394}
3395
3396INLINE ptrdiff_t
3397specpdl_ref_to_count (specpdl_ref ref)
3398{
3399 return unwrap_specpdl_ref (ref);
3366} 3400}
3367 3401
3368/* Whether two `specpdl_ref' refer to the same entry. */ 3402/* Whether two `specpdl_ref' refer to the same entry. */
3369INLINE bool 3403INLINE bool
3370specpdl_ref_eq (specpdl_ref a, specpdl_ref b) 3404specpdl_ref_eq (specpdl_ref a, specpdl_ref b)
3371{ 3405{
3372 return a == b; 3406 return unwrap_specpdl_ref (a) == unwrap_specpdl_ref (b);
3373} 3407}
3374 3408
3375/* Whether `a' refers to an earlier entry than `b'. */ 3409/* Whether `a' refers to an earlier entry than `b'. */
3376INLINE bool 3410INLINE bool
3377specpdl_ref_lt (specpdl_ref a, specpdl_ref b) 3411specpdl_ref_lt (specpdl_ref a, specpdl_ref b)
3378{ 3412{
3379 return a < b; 3413 return unwrap_specpdl_ref (a) < unwrap_specpdl_ref (b);
3380} 3414}
3381 3415
3382INLINE bool 3416INLINE bool
3383specpdl_ref_valid_p (specpdl_ref ref) 3417specpdl_ref_valid_p (specpdl_ref ref)
3384{ 3418{
3385 return specpdl_ref_to_count (ref) >= 0; 3419 return unwrap_specpdl_ref (ref) >= 0;
3386} 3420}
3387 3421
3388INLINE specpdl_ref 3422INLINE specpdl_ref
3389make_invalid_specpdl_ref (void) 3423make_invalid_specpdl_ref (void)
3390{ 3424{
3391 return specpdl_count_to_ref (-1); 3425 return wrap_specpdl_ref (-1);
3392} 3426}
3393 3427
3394/* Return a reference that is `delta' steps more recent than `ref'. 3428/* Return a reference that is `delta' steps more recent than `ref'.