changeset 6939:c7b42fea5fcc HEAD

Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop pairing. These new macros make it a lot more difficult.
author Timo Sirainen <tss@iki.fi>
date Wed, 05 Dec 2007 17:47:19 +0200
parents 8aaec038767c
children 414c9d631a81
files src/lib/data-stack.c src/lib/data-stack.h
diffstat 2 files changed, 23 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/data-stack.c	Wed Dec 05 17:45:16 2007 +0200
+++ b/src/lib/data-stack.c	Wed Dec 05 17:47:19 2007 +0200
@@ -192,6 +192,13 @@
         return --data_stack_frame;
 }
 
+void t_pop_check(unsigned int *id)
+{
+	if (unlikely(t_pop() != *id))
+		i_panic("Leaked t_pop() call");
+	*id = 0;
+}
+
 static struct stack_block *mem_block_alloc(size_t min_size)
 {
 	struct stack_block *block;
--- a/src/lib/data-stack.h	Wed Dec 05 17:45:16 2007 +0200
+++ b/src/lib/data-stack.h	Wed Dec 05 17:47:19 2007 +0200
@@ -42,6 +42,22 @@
 */
 unsigned int t_push(void);
 unsigned int t_pop(void);
+/* Simplifies the if (t_pop() != x) check by comparing it internally and
+   panicking if it doesn't match. */
+void t_pop_check(unsigned int *id);
+
+/* Usage: T_FRAME_BEGIN { code } T_FRAME_END */
+#define T_FRAME_BEGIN \
+	STMT_START { unsigned int _data_stack_cur_id = t_push();
+#define T_FRAME_END \
+	t_pop_check(&_data_stack_cur_id); } STMT_END
+
+/* Usage: T_FRAME(code). This doesn't work if there are commas within the code
+   outside function parameters. */
+#define T_FRAME(_data_stack_code) \
+	T_FRAME_BEGIN { \
+		_data_stack_code; \
+	} T_FRAME_END
 
 /* WARNING: Be careful when using these functions, it's too easy to
    accidentally save the returned value somewhere permanently.