aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKen Raeburn2000-03-29 22:14:34 +0000
committerKen Raeburn2000-03-29 22:14:34 +0000
commite0b8c689e2b1d80da6ed235ae400ad10d117b706 (patch)
treef54bb195d821f61b0f7c3fbf4eae79b72978fdbe /src
parent141384bdd2a332b79b36d118cd13becaf0b326b9 (diff)
downloademacs-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/ChangeLog28
-rw-r--r--src/alloc.c18
-rw-r--r--src/config.in3
-rw-r--r--src/intervals.c2
-rw-r--r--src/intervals.h19
-rw-r--r--src/lisp.h32
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 @@
12000-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
12000-03-29 Gerd Moellmann <gerd@gnu.org> 292000-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
4653int suppress_checking;
4654void
4655die (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? */
50extern int suppress_checking;
51#ifdef ENABLE_CHECKING
52extern 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