diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c
index c1345683ac904aebe9c0c1ae8a2e763b298d7720..e4f9db3cd4c62e2b73ed85ee0cc464e1d61226f6 100644
--- a/src/lib-sieve/ext-reject.c
+++ b/src/lib-sieve/ext-reject.c
@@ -193,8 +193,10 @@ static bool ext_reject_opcode_execute
 
 	t_push();
 	
-	if ( !sieve_interpreter_handle_optional_operands(renv, address, &slist) )
+	if ( !sieve_interpreter_handle_optional_operands(renv, address, &slist) ) {
+		t_pop();
 		return FALSE;
+	}
 
 	if ( !sieve_opr_string_read(renv->sbin, address, &reason) ) {
 		t_pop();
diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c
index 6e72de6bdea47b1f2039d35ebe4ff7d4bb8a3c8e..1bf2c80b51d39bee5c263a71a859d0f73eb054d1 100644
--- a/src/lib-sieve/sieve-address-parts.c
+++ b/src/lib-sieve/sieve-address-parts.c
@@ -345,30 +345,28 @@ bool sieve_address_match
 {
 	bool matched = FALSE;
 	const struct message_address *addr;
+
+	T_FRAME(
+		addr = message_address_parse
+			(pool_datastack_create(), (const unsigned char *) data, 
+				strlen(data), 256, FALSE);
 	
-	t_push();
-	
-	addr = message_address_parse
-		(pool_datastack_create(), (const unsigned char *) data, 
-			strlen(data), 256, FALSE);
-	
-	while (!matched && addr != NULL) {
-		if (addr->domain != NULL) {
-			/* mailbox@domain */
-			const char *part;
+		while (!matched && addr != NULL) {
+			if (addr->domain != NULL) {
+				/* mailbox@domain */
+				const char *part;
 			
-			i_assert(addr->mailbox != NULL);
+				i_assert(addr->mailbox != NULL);
 
-			part = addrp->extract_from(addr);
+				part = addrp->extract_from(addr);
 			
-			if ( part != NULL && sieve_match_value(mctx, part) )
-				matched = TRUE;				
-		} 
+				if ( part != NULL && sieve_match_value(mctx, part) )
+					matched = TRUE;				
+			} 
 
-		addr = addr->next;
-	}
-	
-	t_pop();
+			addr = addr->next;
+		}
+	);
 	
 	return matched;
 }
diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c
index 81609edb67e519f6b6ea181c7251bf10ec01238b..47af4aef00d3cd7ad47ee77b6f17a39e43bbf805 100644
--- a/src/lib-sieve/sieve-ast.c
+++ b/src/lib-sieve/sieve-ast.c
@@ -583,13 +583,13 @@ void sieve_ast_unparse(struct sieve_ast *ast) {
 
 	printf("Unparsing Abstract Syntax Tree:\n");
 
-	t_push();	
-	command = sieve_ast_command_first(sieve_ast_root(ast));
-	while ( command != NULL ) {	
-		sieve_ast_unparse_command(command, 0);
-		command = sieve_ast_command_next(command);
-	}		
-	t_pop();
+	T_FRAME(	
+		command = sieve_ast_command_first(sieve_ast_root(ast));
+		while ( command != NULL ) {	
+			sieve_ast_unparse_command(command, 0);
+			command = sieve_ast_command_next(command);
+		}		
+	);
 }
 
 
diff --git a/src/lib-sieve/sieve-commands.c b/src/lib-sieve/sieve-commands.c
index 37d5087116d7daf799768a33de08d5adea25a8fa..1a171b69469afb2a5831f989f098bd2bf15f9b9d 100644
--- a/src/lib-sieve/sieve-commands.c
+++ b/src/lib-sieve/sieve-commands.c
@@ -65,21 +65,19 @@ static void emit_string_list_operand
 	void *list_context;
 	const struct sieve_ast_argument *stritem;
   
-	t_push();
-  
-	sieve_opr_stringlist_emit_start
-		(sbin, sieve_ast_strlist_count(strlist), &list_context);
-
-	stritem = sieve_ast_strlist_first(strlist);
-	while ( stritem != NULL ) {
-		sieve_opr_stringlist_emit_item
-			(sbin, list_context, sieve_ast_strlist_str(stritem));
-		stritem = sieve_ast_strlist_next(stritem);
-	}
-
-	sieve_opr_stringlist_emit_end(sbin, list_context);
-
-	t_pop();
+	T_FRAME(
+ 		sieve_opr_stringlist_emit_start
+			(sbin, sieve_ast_strlist_count(strlist), &list_context);
+
+		stritem = sieve_ast_strlist_first(strlist);
+		while ( stritem != NULL ) {
+			sieve_opr_stringlist_emit_item
+				(sbin, list_context, sieve_ast_strlist_str(stritem));
+			stritem = sieve_ast_strlist_next(stritem);
+		}
+
+		sieve_opr_stringlist_emit_end(sbin, list_context);
+	);
 }
 
 static bool arg_string_list_generate
diff --git a/src/lib-sieve/sieve-error.c b/src/lib-sieve/sieve-error.c
index db75f133bde2a36cf72b30441a71243cdc314b5f..4cfec4fefa23c5d12f8a405b07d674bcf8b628a9 100644
--- a/src/lib-sieve/sieve-error.c
+++ b/src/lib-sieve/sieve-error.c
@@ -175,16 +175,14 @@ static void sieve_logfile_vprintf
 	
 	if ( ehandler->stream == NULL ) return;
 	
-	t_push();
+	T_FRAME(
+		outbuf = t_str_new(256);
+		str_printfa(outbuf, "%s: %s: ", location, prefix);	
+		str_vprintfa(outbuf, fmt, args);
+		str_append(outbuf, ".\n");
 	
-	outbuf = t_str_new(256);
-	str_printfa(outbuf, "%s: %s: ", location, prefix);	
-	str_vprintfa(outbuf, fmt, args);
-	str_append(outbuf, ".\n");
-	
-	o_stream_send(ehandler->stream, str_data(outbuf), str_len(outbuf));
-	
-	t_pop();
+		o_stream_send(ehandler->stream, str_data(outbuf), str_len(outbuf));
+	);
 }
 
 inline static void sieve_logfile_printf
diff --git a/src/lib-sieve/sieve-error.h b/src/lib-sieve/sieve-error.h
index dc2c9add33d920802796012b124683c51da541d3..2a095abcf26f84df2d169200bfdb5c2fc4a26479 100644
--- a/src/lib-sieve/sieve-error.h
+++ b/src/lib-sieve/sieve-error.h
@@ -8,6 +8,9 @@
 
 struct sieve_error_handler;
 
+/* For these functions it is the responsibility of the caller to
+ * manage the datastack.
+ */
 void sieve_verror
 	(struct sieve_error_handler *ehandler, const char *location, 
 		const char *fmt, va_list args);
@@ -35,7 +38,7 @@ inline static void sieve_error
 	va_list args;
 	va_start(args, fmt);
 	
-	sieve_verror(ehandler, location, fmt, args);
+	T_FRAME(sieve_verror(ehandler, location, fmt, args));
 	
 	va_end(args);
 }
@@ -47,7 +50,7 @@ inline static void sieve_warning
 	va_list args;
 	va_start(args, fmt);
 	
-	sieve_vwarning(ehandler, location, fmt, args);
+	T_FRAME(sieve_vwarning(ehandler, location, fmt, args));
 	
 	va_end(args);
 }
@@ -59,7 +62,7 @@ inline static void sieve_info
 	va_list args;
 	va_start(args, fmt);
 	
-	sieve_vinfo(ehandler, location, fmt, args);
+	T_FRAME(sieve_vinfo(ehandler, location, fmt, args));
 	
 	va_end(args);
 }
diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c
index 24e79bd435ab67cf7f6a6b2f1ef1aaf6173a9833..a4e1f08ecc80532e8fb6e6ba30fdb1067d2e9e91 100644
--- a/src/lib-sieve/sieve-generator.c
+++ b/src/lib-sieve/sieve-generator.c
@@ -203,13 +203,13 @@ bool sieve_generate_block
 {
 	struct sieve_ast_node *command;
 
-	t_push();	
-	command = sieve_ast_command_first(block);
-	while ( command != NULL ) {	
-		sieve_generate_command(generator, command);	
-		command = sieve_ast_command_next(command);
-	}		
-	t_pop();
+	T_FRAME(	
+		command = sieve_ast_command_first(block);
+		while ( command != NULL ) {	
+			sieve_generate_command(generator, command);	
+			command = sieve_ast_command_next(command);
+		}		
+	);
 	
 	return TRUE;
 }
diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c
index 7978d8e5fbdb94d20e074cd55c6f31c63f2689dc..d75b7db05ec6d50add2a3188c40fb51bdde1643a 100644
--- a/src/lib-sieve/sieve-interpreter.c
+++ b/src/lib-sieve/sieve-interpreter.c
@@ -109,7 +109,9 @@ void sieve_runtime_error
 	va_list args;
 	
 	va_start(args, fmt);
-	sieve_verror(runenv->interp->ehandler, _get_location(runenv), fmt, args); 
+	T_FRAME(
+		sieve_verror(runenv->interp->ehandler, _get_location(runenv), fmt, args); 
+	);
 	va_end(args);
 }
 
@@ -119,7 +121,9 @@ void sieve_runtime_warning
 	va_list args;
 	
 	va_start(args, fmt);
-	sieve_vwarning(runenv->interp->ehandler, _get_location(runenv), fmt, args); 
+	T_FRAME(
+		sieve_vwarning(runenv->interp->ehandler, _get_location(runenv), fmt, args);
+	); 
 	va_end(args);
 }
 
@@ -129,7 +133,9 @@ void sieve_runtime_log
 	va_list args;
 	
 	va_start(args, fmt);
-	sieve_vinfo(runenv->interp->ehandler, _get_location(runenv), fmt, args); 
+	T_FRAME(
+		sieve_vinfo(runenv->interp->ehandler, _get_location(runenv), fmt, args); 
+	);
 	va_end(args);
 }
 
diff --git a/src/lib-sieve/sieve-lexer.c b/src/lib-sieve/sieve-lexer.c
index 9f15d64b87a2a724d59df01fa7ec7433a3f99e87..c0e1e66144fdbfb3dc56906c199153333ab844bc 100644
--- a/src/lib-sieve/sieve-lexer.c
+++ b/src/lib-sieve/sieve-lexer.c
@@ -49,9 +49,9 @@ inline static void sieve_lexer_error
 	va_list args;
 	va_start(args, fmt);
 
-	sieve_verror(lexer->ehandler, 
+	T_FRAME(sieve_verror(lexer->ehandler, 
 		t_strdup_printf("%s:%d", lexer->scriptname, lexer->current_line),
-		fmt, args);
+		fmt, args));
 		
 	va_end(args);
 }
@@ -62,9 +62,9 @@ inline static void sieve_lexer_warning
 	va_list args;
 	va_start(args, fmt);
 
-	sieve_vwarning(lexer->ehandler, 
+	T_FRAME(sieve_vwarning(lexer->ehandler, 
 		t_strdup_printf("%s:%d", lexer->scriptname, lexer->current_line),
-		fmt, args);
+		fmt, args));
 		
 	va_end(args);
 }
diff --git a/src/lib-sieve/sieve-parser.c b/src/lib-sieve/sieve-parser.c
index 9eb436731747447d8170251c6836b801229c3467..f7df7a480ad604b6afb23511f27474ef70ad2576 100644
--- a/src/lib-sieve/sieve-parser.c
+++ b/src/lib-sieve/sieve-parser.c
@@ -41,10 +41,10 @@ inline static void sieve_parser_error
 	/* Don't report a parse error if the lexer complained already */ 
 	if ( sieve_lexer_current_token(parser->lexer) != STT_ERROR )  
 	{
-		sieve_verror(parser->ehandler, 
+		T_FRAME(sieve_verror(parser->ehandler, 
 			t_strdup_printf("%s:%d", parser->scriptname,
 			sieve_lexer_current_line(parser->lexer)),
-			fmt, args); 
+			fmt, args)); 
 	}
 	
 	va_end(args);
@@ -56,10 +56,10 @@ inline static void sieve_parser_warning
 	va_list args;
 	va_start(args, fmt);
 
-	sieve_vwarning(parser->ehandler, 
+	T_FRAME(sieve_vwarning(parser->ehandler, 
 		t_strdup_printf("%s:%d", parser->scriptname,
 		sieve_lexer_current_line(parser->lexer)),
-		fmt, args);
+		fmt, args));
 		
 	va_end(args);
 } 
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index aecb05bfe8c30a30339023265a82c5d89da09d3a..370cdfb490bf7cd240dcd48e7a191c14ad0fb25a 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -40,9 +40,9 @@ void sieve_validator_warning
 	va_list args;
 	va_start(args, fmt);
 	
-	sieve_vwarning(validator->ehandler, 
+	T_FRAME(sieve_vwarning(validator->ehandler, 
 		t_strdup_printf("%s:%d", sieve_ast_scriptname(validator->ast),
-			sieve_ast_node_line(node)), fmt, args); 
+			sieve_ast_node_line(node)), fmt, args)); 
 	
 	va_end(args);
 }
@@ -54,9 +54,9 @@ void sieve_validator_error
 	va_list args;
 	va_start(args, fmt);
 	
-	sieve_verror(validator->ehandler, 
+	T_FRAME(sieve_verror(validator->ehandler, 
 		t_strdup_printf("%s:%d", sieve_ast_scriptname(validator->ast),
-		sieve_ast_node_line(node)), fmt, args); 
+		sieve_ast_node_line(node)), fmt, args)); 
 	
 	va_end(args);
 }
@@ -751,13 +751,13 @@ static bool sieve_validate_block(struct sieve_validator *validator, struct sieve
 	bool result = TRUE;
 	struct sieve_ast_node *command;
 
-	t_push();	
-	command = sieve_ast_command_first(block);
-	while ( command != NULL ) {	
-		result = sieve_validate_command(validator, command) && result;	
-		command = sieve_ast_command_next(command);
-	}		
-	t_pop();
+	T_FRAME(	
+		command = sieve_ast_command_first(block);
+		while ( command != NULL ) {	
+			result = sieve_validate_command(validator, command) && result;	
+			command = sieve_ast_command_next(command);
+		}		
+	);
 	
 	return result;
 }