diff options
| author | Ken Raeburn | 2000-03-29 22:14:34 +0000 |
|---|---|---|
| committer | Ken Raeburn | 2000-03-29 22:14:34 +0000 |
| commit | e0b8c689e2b1d80da6ed235ae400ad10d117b706 (patch) | |
| tree | f54bb195d821f61b0f7c3fbf4eae79b72978fdbe /src | |
| parent | 141384bdd2a332b79b36d118cd13becaf0b326b9 (diff) | |
| download | emacs-e0b8c689e2b1d80da6ed235ae400ad10d117b706.tar.gz emacs-e0b8c689e2b1d80da6ed235ae400ad10d117b706.zip | |
Stop assuming interval pointers and lisp objects can be distinguished by
inspection. Beginnings of support for expensive internal consistency checks.
* config.in (ENABLE_CHECKING): Undef.
* lisp.h (struct interval): Replace "parent" field with a union of interval
pointer and Lisp_Object; add new bitfield to use as discriminant. Change other
flag fields to bitfields.
(CHECK): New macro for consistency checking. If ENABLE_CHECKING is defined and
the supplied test fails, print a message and abort.
(eassert): New macro. Use CHECK to provide an assert-like facility.
* intervals.h (NULL_INTERVAL_P): Now applies only to real interval pointers;
abort if the value looks like a lisp object.
(NULL_INTERVAL_P, NULL_PARENT, HAS_PARENT, HAS_OBJECT, SET_PARENT, SET_OBJECT,
INTERVAL_PARENT, GET_INTERVAL_OBJECT, COPY_PARENT): Modify for new interval
parent definition.
* alloc.c (mark_interval_tree, MARK_INTERVAL_TREE, UNMARK_BALANCE_INTERVALS):
Update references that need an addressable lisp object in the interval
structure.
(die): New function.
(suppress_checking): New variable.
* intervals.c (interval_start_pos): Just return 0 if there's no parent object.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 28 | ||||
| -rw-r--r-- | src/alloc.c | 18 | ||||
| -rw-r--r-- | src/config.in | 3 | ||||
| -rw-r--r-- | src/intervals.c | 2 | ||||
| -rw-r--r-- | src/intervals.h | 19 | ||||
| -rw-r--r-- | src/lisp.h | 32 |
6 files changed, 85 insertions, 17 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2232594d3b2..cf1050bb1ea 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,31 @@ | |||
| 1 | 2000-03-29 Ken Raeburn <raeburn@gnu.org> | ||
| 2 | |||
| 3 | * config.in (ENABLE_CHECKING): Undef. | ||
| 4 | |||
| 5 | * lisp.h (struct interval): Replace "parent" field with a union of | ||
| 6 | interval pointer and Lisp_Object; add new bitfield to use as | ||
| 7 | discriminant. Change other flag fields to bitfields. | ||
| 8 | (CHECK): New macro for consistency checking. If ENABLE_CHECKING | ||
| 9 | is defined and the supplied test fails, print a message and | ||
| 10 | abort. | ||
| 11 | (eassert): New macro. Use CHECK to provide an assert-like | ||
| 12 | facility. | ||
| 13 | |||
| 14 | * intervals.h (NULL_INTERVAL_P): Now applies only to real interval | ||
| 15 | pointers; abort if the value looks like a lisp object. | ||
| 16 | (NULL_INTERVAL_P, NULL_PARENT, HAS_PARENT, HAS_OBJECT, SET_PARENT, | ||
| 17 | SET_OBJECT, INTERVAL_PARENT, GET_INTERVAL_OBJECT, COPY_PARENT): | ||
| 18 | Modify for new interval parent definition. | ||
| 19 | |||
| 20 | * alloc.c (mark_interval_tree, MARK_INTERVAL_TREE, | ||
| 21 | UNMARK_BALANCE_INTERVALS): Update references that need an | ||
| 22 | addressable lisp object in the interval structure. | ||
| 23 | (die): New function. | ||
| 24 | (suppress_checking): New variable. | ||
| 25 | |||
| 26 | * intervals.c (interval_start_pos): Just return 0 if there's no | ||
| 27 | parent object. | ||
| 28 | |||
| 1 | 2000-03-29 Gerd Moellmann <gerd@gnu.org> | 29 | 2000-03-29 Gerd Moellmann <gerd@gnu.org> |
| 2 | 30 | ||
| 3 | * lread.c (read1): Accept `.' (period) as symbol start like in CL | 31 | * lread.c (read1): Accept `.' (period) as symbol start like in CL |
diff --git a/src/alloc.c b/src/alloc.c index d7e4214c6c4..3b5d0e57ace 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -766,7 +766,7 @@ mark_interval_tree (tree) | |||
| 766 | 766 | ||
| 767 | /* XMARK expands to an assignment; the LHS of an assignment can't be | 767 | /* XMARK expands to an assignment; the LHS of an assignment can't be |
| 768 | a cast. */ | 768 | a cast. */ |
| 769 | XMARK (* (Lisp_Object *) &tree->parent); | 769 | XMARK (tree->up.obj); |
| 770 | 770 | ||
| 771 | traverse_intervals (tree, 1, 0, mark_interval, Qnil); | 771 | traverse_intervals (tree, 1, 0, mark_interval, Qnil); |
| 772 | } | 772 | } |
| @@ -777,7 +777,7 @@ mark_interval_tree (tree) | |||
| 777 | #define MARK_INTERVAL_TREE(i) \ | 777 | #define MARK_INTERVAL_TREE(i) \ |
| 778 | do { \ | 778 | do { \ |
| 779 | if (!NULL_INTERVAL_P (i) \ | 779 | if (!NULL_INTERVAL_P (i) \ |
| 780 | && ! XMARKBIT (*(Lisp_Object *) &i->parent)) \ | 780 | && ! XMARKBIT (i->up.obj)) \ |
| 781 | mark_interval_tree (i); \ | 781 | mark_interval_tree (i); \ |
| 782 | } while (0) | 782 | } while (0) |
| 783 | 783 | ||
| @@ -790,7 +790,7 @@ mark_interval_tree (tree) | |||
| 790 | do { \ | 790 | do { \ |
| 791 | if (! NULL_INTERVAL_P (i)) \ | 791 | if (! NULL_INTERVAL_P (i)) \ |
| 792 | { \ | 792 | { \ |
| 793 | XUNMARK (* (Lisp_Object *) (&(i)->parent)); \ | 793 | XUNMARK ((i)->up.obj); \ |
| 794 | (i) = balance_intervals (i); \ | 794 | (i) = balance_intervals (i); \ |
| 795 | } \ | 795 | } \ |
| 796 | } while (0) | 796 | } while (0) |
| @@ -4649,6 +4649,18 @@ Frames, windows, buffers, and subprocesses count as vectors\n\ | |||
| 4649 | 4649 | ||
| 4650 | return Flist (8, consed); | 4650 | return Flist (8, consed); |
| 4651 | } | 4651 | } |
| 4652 | |||
| 4653 | int suppress_checking; | ||
| 4654 | void | ||
| 4655 | die (msg, file, line) | ||
| 4656 | const char *msg; | ||
| 4657 | const char *file; | ||
| 4658 | int line; | ||
| 4659 | { | ||
| 4660 | fprintf (stderr, "\r\nEmacs fatal error: %s:%d: %s\r\n", | ||
| 4661 | file, line, msg); | ||
| 4662 | abort (); | ||
| 4663 | } | ||
| 4652 | 4664 | ||
| 4653 | /* Initialization */ | 4665 | /* Initialization */ |
| 4654 | 4666 | ||
diff --git a/src/config.in b/src/config.in index 9fb464e6f7b..511919aa3e8 100644 --- a/src/config.in +++ b/src/config.in | |||
| @@ -504,3 +504,6 @@ extern char *getenv (); | |||
| 504 | #if defined HAVE_X11R6 && !defined INHIBIT_X11R6_XIM | 504 | #if defined HAVE_X11R6 && !defined INHIBIT_X11R6_XIM |
| 505 | #define HAVE_X11R6_XIM | 505 | #define HAVE_X11R6_XIM |
| 506 | #endif | 506 | #endif |
| 507 | |||
| 508 | /* Should we enable expensive run-time checking of data types? */ | ||
| 509 | #undef ENABLE_CHECKING | ||
diff --git a/src/intervals.c b/src/intervals.c index 2a03abbb762..f925d222db2 100644 --- a/src/intervals.c +++ b/src/intervals.c | |||
| @@ -570,6 +570,8 @@ interval_start_pos (source) | |||
| 570 | if (NULL_INTERVAL_P (source)) | 570 | if (NULL_INTERVAL_P (source)) |
| 571 | return 0; | 571 | return 0; |
| 572 | 572 | ||
| 573 | if (! INTERVAL_HAS_OBJECT (source)) | ||
| 574 | return 0; | ||
| 573 | GET_INTERVAL_OBJECT (parent, source); | 575 | GET_INTERVAL_OBJECT (parent, source); |
| 574 | if (BUFFERP (parent)) | 576 | if (BUFFERP (parent)) |
| 575 | return BUF_BEG (XBUFFER (parent)); | 577 | return BUF_BEG (XBUFFER (parent)); |
diff --git a/src/intervals.h b/src/intervals.h index eb50d723784..5db02e78629 100644 --- a/src/intervals.h +++ b/src/intervals.h | |||
| @@ -43,7 +43,8 @@ Boston, MA 02111-1307, USA. */ | |||
| 43 | #define INT_LISPLIKE(i) (BUFFERP ((Lisp_Object){(EMACS_INT)(i)}) \ | 43 | #define INT_LISPLIKE(i) (BUFFERP ((Lisp_Object){(EMACS_INT)(i)}) \ |
| 44 | || STRINGP ((Lisp_Object){(EMACS_INT)(i)})) | 44 | || STRINGP ((Lisp_Object){(EMACS_INT)(i)})) |
| 45 | #endif | 45 | #endif |
| 46 | #define NULL_INTERVAL_P(i) ((i) == NULL_INTERVAL || INT_LISPLIKE (i)) | 46 | #define NULL_INTERVAL_P(i) (CHECK(!INT_LISPLIKE(i),"non-interval"),(i) == NULL_INTERVAL) |
| 47 | /* old #define NULL_INTERVAL_P(i) ((i) == NULL_INTERVAL || INT_LISPLIKE (i)) */ | ||
| 47 | 48 | ||
| 48 | /* True if this interval has no right child. */ | 49 | /* True if this interval has no right child. */ |
| 49 | #define NULL_RIGHT_CHILD(i) ((i)->right == NULL_INTERVAL) | 50 | #define NULL_RIGHT_CHILD(i) ((i)->right == NULL_INTERVAL) |
| @@ -52,7 +53,7 @@ Boston, MA 02111-1307, USA. */ | |||
| 52 | #define NULL_LEFT_CHILD(i) ((i)->left == NULL_INTERVAL) | 53 | #define NULL_LEFT_CHILD(i) ((i)->left == NULL_INTERVAL) |
| 53 | 54 | ||
| 54 | /* True if this interval has no parent. */ | 55 | /* True if this interval has no parent. */ |
| 55 | #define NULL_PARENT(i) (NULL_INTERVAL_P ((i)->parent)) | 56 | #define NULL_PARENT(i) ((i)->up_obj || (i)->up.interval == 0) |
| 56 | 57 | ||
| 57 | /* True if this interval is the left child of some other interval. */ | 58 | /* True if this interval is the left child of some other interval. */ |
| 58 | #define AM_LEFT_CHILD(i) (! NULL_PARENT (i) \ | 59 | #define AM_LEFT_CHILD(i) (! NULL_PARENT (i) \ |
| @@ -104,24 +105,24 @@ Boston, MA 02111-1307, USA. */ | |||
| 104 | 105 | ||
| 105 | /* Test what type of parent we have. Three possibilities: another | 106 | /* Test what type of parent we have. Three possibilities: another |
| 106 | interval, a buffer or string object, or NULL_INTERVAL. */ | 107 | interval, a buffer or string object, or NULL_INTERVAL. */ |
| 107 | #define INTERVAL_HAS_PARENT(i) ((i)->parent && ! INT_LISPLIKE ((i)->parent)) | 108 | #define INTERVAL_HAS_PARENT(i) ((i)->up_obj == 0 && (i)->up.interval != 0) |
| 108 | #define INTERVAL_HAS_OBJECT(i) ((i)->parent && INT_LISPLIKE ((i)->parent)) | 109 | #define INTERVAL_HAS_OBJECT(i) ((i)->up_obj) |
| 109 | 110 | ||
| 110 | /* Set/get parent of an interval. | 111 | /* Set/get parent of an interval. |
| 111 | 112 | ||
| 112 | The choice of macros is dependent on the type needed. Don't add | 113 | The choice of macros is dependent on the type needed. Don't add |
| 113 | casts to get around this, it will break some development work in | 114 | casts to get around this, it will break some development work in |
| 114 | progress. */ | 115 | progress. */ |
| 115 | #define SET_INTERVAL_PARENT(i,p) ((i)->parent = (p)) | 116 | #define SET_INTERVAL_PARENT(i,p) (eassert (!BUFFERP ((Lisp_Object)(p)) && !STRINGP ((Lisp_Object)(p))),(i)->up_obj = 0, (i)->up.interval = (p)) |
| 116 | #define SET_INTERVAL_OBJECT(i,o) ((i)->parent = (INTERVAL) XFASTINT (o)) | 117 | #define SET_INTERVAL_OBJECT(i,o) (eassert ((o) != 0), eassert (BUFFERP (o) || STRINGP (o)),(i)->up_obj = 1, (i)->up.obj = (o)) |
| 117 | #define INTERVAL_PARENT(i) ((i)->parent) | 118 | #define INTERVAL_PARENT(i) (eassert((i) != 0 && (i)->up_obj == 0),(i)->up.interval) |
| 118 | /* Because XSETFASTINT has to be used, this can't simply be | 119 | /* Because XSETFASTINT has to be used, this can't simply be |
| 119 | value-returning. */ | 120 | value-returning. */ |
| 120 | #define GET_INTERVAL_OBJECT(d,s) XSETFASTINT((d), (EMACS_INT) (s)->parent) | 121 | #define GET_INTERVAL_OBJECT(d,s) (eassert((s)->up_obj == 1),XSETFASTINT ((d), (s)->up.obj)) |
| 121 | 122 | ||
| 122 | /* Make the parent of D be whatever the parent of S is, regardless of | 123 | /* Make the parent of D be whatever the parent of S is, regardless of |
| 123 | type. This is used when balancing an interval tree. */ | 124 | type. This is used when balancing an interval tree. */ |
| 124 | #define COPY_INTERVAL_PARENT(d,s) ((d)->parent = (s)->parent) | 125 | #define COPY_INTERVAL_PARENT(d,s) ((d)->up = (s)->up, (d)->up_obj = (s)->up_obj) |
| 125 | 126 | ||
| 126 | /* Get the parent interval, if any, otherwise a null pointer. Useful | 127 | /* Get the parent interval, if any, otherwise a null pointer. Useful |
| 127 | for walking up to the root in a "for" loop; use this to get the | 128 | for walking up to the root in a "for" loop; use this to get the |
diff --git a/src/lisp.h b/src/lisp.h index af1ddb7a460..0e1cfff61ab 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -46,6 +46,23 @@ Boston, MA 02111-1307, USA. */ | |||
| 46 | #endif | 46 | #endif |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | /* Extra internal type checking? */ | ||
| 50 | extern int suppress_checking; | ||
| 51 | #ifdef ENABLE_CHECKING | ||
| 52 | extern void die P_((const char *, const char *, int)); | ||
| 53 | #define CHECK(check,msg) ((check || suppress_checking ? 0 : die (msg, __FILE__, __LINE__)), 0) | ||
| 54 | #else | ||
| 55 | /* Produce same side effects and result, but don't complain. */ | ||
| 56 | #define CHECK(check,msg) ((check),0) | ||
| 57 | #endif | ||
| 58 | /* Define an Emacs version of "assert", since some system ones are | ||
| 59 | flaky. */ | ||
| 60 | #if defined (__GNUC__) && __GNUC__ >= 2 && defined (__STDC__) | ||
| 61 | #define eassert(cond) CHECK(cond,"assertion failed: " #cond) | ||
| 62 | #else | ||
| 63 | #define eassert(cond) CHECK(cond,"assertion failed") | ||
| 64 | #endif | ||
| 65 | |||
| 49 | /* Define the fundamental Lisp data structures. */ | 66 | /* Define the fundamental Lisp data structures. */ |
| 50 | 67 | ||
| 51 | /* This is the set of Lisp data types. */ | 68 | /* This is the set of Lisp data types. */ |
| @@ -494,17 +511,22 @@ struct interval | |||
| 494 | You'd think we could store this information in the parent object | 511 | You'd think we could store this information in the parent object |
| 495 | somewhere (after all, that should be visited once and then | 512 | somewhere (after all, that should be visited once and then |
| 496 | ignored too, right?), but strings are GC'd strangely. */ | 513 | ignored too, right?), but strings are GC'd strangely. */ |
| 497 | struct interval *parent; | 514 | union |
| 515 | { | ||
| 516 | struct interval *interval; | ||
| 517 | Lisp_Object obj; | ||
| 518 | } up; | ||
| 519 | unsigned int up_obj : 1; | ||
| 498 | 520 | ||
| 499 | /* The remaining components are `properties' of the interval. | 521 | /* The remaining components are `properties' of the interval. |
| 500 | The first four are duplicates for things which can be on the list, | 522 | The first four are duplicates for things which can be on the list, |
| 501 | for purposes of speed. */ | 523 | for purposes of speed. */ |
| 502 | 524 | ||
| 503 | unsigned char write_protect; /* Non-zero means can't modify. */ | 525 | unsigned int write_protect : 1; /* Non-zero means can't modify. */ |
| 504 | unsigned char visible; /* Zero means don't display. */ | 526 | unsigned int visible : 1; /* Zero means don't display. */ |
| 505 | unsigned char front_sticky; /* Non-zero means text inserted just | 527 | unsigned int front_sticky : 1; /* Non-zero means text inserted just |
| 506 | before this interval goes into it. */ | 528 | before this interval goes into it. */ |
| 507 | unsigned char rear_sticky; /* Likewise for just after it. */ | 529 | unsigned int rear_sticky : 1; /* Likewise for just after it. */ |
| 508 | 530 | ||
| 509 | /* Properties of this interval. | 531 | /* Properties of this interval. |
| 510 | The mark bit on this field says whether this particular interval | 532 | The mark bit on this field says whether this particular interval |