dovecot-2.2-pigeonhole: lib-sieve: Implemented running code loop...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Sun Nov 29 10:53:29 UTC 2015


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/7c516d25ad50
changeset: 2139:7c516d25ad50
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sun Nov 29 11:50:44 2015 +0100
description:
lib-sieve: Implemented running code loops in the interpreter.

diffstat:

 src/lib-sieve/sieve-interpreter.c |  192 +++++++++++++++++++++++++++++++++++++-
 src/lib-sieve/sieve-interpreter.h |   32 ++++++
 2 files changed, 221 insertions(+), 3 deletions(-)

diffs (270 lines):

diff -r be0971931cfe -r 7c516d25ad50 src/lib-sieve/sieve-interpreter.c
--- a/src/lib-sieve/sieve-interpreter.c	Sun Nov 29 11:49:47 2015 +0100
+++ b/src/lib-sieve/sieve-interpreter.c	Sun Nov 29 11:50:44 2015 +0100
@@ -38,6 +38,18 @@
 };
 
 /*
+ * Code loop
+ */
+
+struct sieve_interpreter_loop {
+	unsigned int level;
+	sieve_size_t begin, end;
+	const struct sieve_extension_def *ext_def;
+	pool_t pool;
+	void *context;
+};
+
+/*
  * Interpreter
  */
 
@@ -55,6 +67,10 @@
 	bool interrupted;         /* Interpreter interrupt requested */
 	bool test_result;         /* Result of previous test command */
 
+	/* Loop stack */
+	ARRAY(struct sieve_interpreter_loop) loop_stack;
+	sieve_size_t loop_limit;
+
 	/* Runtime environment */
 	struct sieve_runtime_env runenv;
 	struct sieve_runtime_trace trace;
@@ -225,14 +241,21 @@
 	struct sieve_interpreter *interp = *_interp;
 	struct sieve_runtime_env *renv = &interp->runenv;
 	const struct sieve_interpreter_extension_reg *eregs;
-	unsigned int ext_count, i;
+	struct sieve_interpreter_loop *loops;
+	unsigned int count, i;
+
+	if ( array_is_created(&interp->loop_stack) ) {
+		loops = array_get_modifiable(&interp->loop_stack, &count);
+		for ( i = 0; i < count; i++ )
+			pool_unref(&loops[i].pool);
+	}
 
 	interp->trace.indent = 0;
 	sieve_runtime_trace_end(renv);
 
 	/* Signal registered extensions that the interpreter is being destroyed */
-	eregs = array_get(&interp->extensions, &ext_count);
-	for ( i = 0; i < ext_count; i++ ) {
+	eregs = array_get(&interp->extensions, &count);
+	for ( i = 0; i < count; i++ ) {
 		if ( eregs[i].intext != NULL && eregs[i].intext->free != NULL )
 			eregs[i].intext->free(eregs[i].ext, interp, eregs[i].context);
 	}
@@ -456,6 +479,169 @@
 }
 
 /*
+ * Loop handling
+ */
+
+struct sieve_interpreter_loop *sieve_interpreter_loop_start
+(struct sieve_interpreter *interp, sieve_size_t loop_end,
+	const struct sieve_extension_def *ext_def)
+{
+	const struct sieve_runtime_env *renv = &interp->runenv;
+	struct sieve_interpreter_loop *loop;
+
+	i_assert( loop_end > interp->runenv.pc );
+
+	if ( loop_end > sieve_binary_block_get_size(renv->sblock) ) {
+		sieve_runtime_trace_error(renv,
+			"loop end offset out of range");
+		return NULL;
+	}
+
+	if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) {
+		unsigned int line =
+			sieve_runtime_get_source_location(renv, loop_end);
+
+		if ( sieve_runtime_trace_hasflag(renv, SIEVE_TRFLG_ADDRESSES) ) {
+			sieve_runtime_trace(renv, 0, "loop ends at line %d [%08llx]",
+				line, (long long unsigned int) loop_end);
+		} else {
+			sieve_runtime_trace(renv, 0, "loop ends at line %d", line);
+		}
+	}
+
+	if ( !array_is_created(&interp->loop_stack) )
+		p_array_init(&interp->loop_stack, interp->pool, 8);
+
+	loop = array_append_space(&interp->loop_stack);
+	loop->level = array_count(&interp->loop_stack)-1;
+	loop->ext_def = ext_def;
+	loop->begin = interp->runenv.pc;
+	loop->end = loop_end;
+	loop->pool =  pool_alloconly_create("sieve_interpreter", 128);
+	
+	return loop;
+}
+
+struct sieve_interpreter_loop *sieve_interpreter_loop_get
+(struct sieve_interpreter *interp, sieve_size_t loop_end,
+	const struct sieve_extension_def *ext_def)
+{
+	struct sieve_interpreter_loop *loops;
+	unsigned int count, i;
+
+	if ( !array_is_created(&interp->loop_stack) )
+		return NULL;
+
+	loops = array_get_modifiable(&interp->loop_stack, &count);
+	for ( i = count; i > 0; i-- ) {
+		/* We're really making sure our loop matches */
+		if ( loops[i-1].end == loop_end &&
+			loops[i-1].ext_def == ext_def )
+			return &loops[i-1];
+	}
+	return NULL;
+}
+
+void sieve_interpreter_loop_next(struct sieve_interpreter *interp,
+	struct sieve_interpreter_loop *loop,
+	sieve_size_t loop_begin)
+{
+	const struct sieve_runtime_env *renv = &interp->runenv;
+	struct sieve_interpreter_loop *loops;
+	unsigned int count;
+
+	if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) {
+		unsigned int line =
+			sieve_runtime_get_source_location(renv, loop_begin);
+
+		if ( sieve_runtime_trace_hasflag(renv, SIEVE_TRFLG_ADDRESSES) ) {
+			sieve_runtime_trace(renv, 0, "looping back to line %d [%08llx]",
+				line, (long long unsigned int) loop_begin);
+		} else {
+			sieve_runtime_trace(renv, 0, "looping back to line %d", line);
+		}
+	}
+
+	i_assert( loop->begin == loop_begin );
+
+	i_assert( array_is_created(&interp->loop_stack) );
+	loops = array_get_modifiable(&interp->loop_stack, &count);
+	i_assert( &loops[count-1] == loop );
+
+	interp->runenv.pc = loop_begin;
+}
+
+void sieve_interpreter_loop_break(struct sieve_interpreter *interp,
+	struct sieve_interpreter_loop *loop)
+{
+	const struct sieve_runtime_env *renv = &interp->runenv;
+	struct sieve_interpreter_loop *loops;
+	sieve_size_t loop_end = loop->end;
+	unsigned int count, i;
+
+	i_assert( array_is_created(&interp->loop_stack) );
+	loops = array_get_modifiable(&interp->loop_stack, &count);
+	for ( i = count; i > 0 && &loops[i-1] != loop; i-- )
+		pool_unref(&loops[i-1].pool);
+	i_assert( i > 0 && &loops[i-1] == loop );
+
+	array_delete(&interp->loop_stack, i-1, count - (i-1));
+
+	if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) {
+		unsigned int jmp_line =
+			sieve_runtime_get_source_location(renv, loop_end);
+
+		if ( sieve_runtime_trace_hasflag(renv, SIEVE_TRFLG_ADDRESSES) ) {
+			sieve_runtime_trace(renv, 0, "ending loop at line %d [%08llx]",
+				jmp_line, (long long unsigned int) loop_end);
+		} else {
+			sieve_runtime_trace(renv, 0, "ending loop at line %d", jmp_line);
+		}
+	}
+
+	interp->runenv.pc = loop->end;
+}
+
+struct sieve_interpreter_loop *sieve_interpreter_loop_get_surrounding
+(struct sieve_interpreter *interp,
+	struct sieve_interpreter_loop *loop,
+	const struct sieve_extension_def *ext_def)
+{
+	struct sieve_interpreter_loop *loops;
+	unsigned int count, i;
+
+	if ( !array_is_created(&interp->loop_stack) )
+		return NULL;
+
+	loops = array_get_modifiable(&interp->loop_stack, &count);
+	i_assert(loop == NULL || loop->level < count);
+
+	for ( i = (loop == NULL ? count : loop->level); i > 0; i-- ) {
+		if ( ext_def == NULL || loops[i-1].ext_def == ext_def )
+			return &loops[i-1];
+	}
+	return NULL;
+}
+
+pool_t sieve_interpreter_loop_get_pool
+(struct sieve_interpreter_loop *loop)
+{
+	return loop->pool;
+}
+
+void *sieve_interpreter_loop_get_context
+(struct sieve_interpreter_loop *loop)
+{
+	return loop->context;
+}
+
+void sieve_interpreter_loop_set_context
+(struct sieve_interpreter_loop *loop, void *context)
+{
+	loop->context = context;
+}
+
+/*
  * Program flow
  */
 
diff -r be0971931cfe -r 7c516d25ad50 src/lib-sieve/sieve-interpreter.h
--- a/src/lib-sieve/sieve-interpreter.h	Sun Nov 29 11:49:47 2015 +0100
+++ b/src/lib-sieve/sieve-interpreter.h	Sun Nov 29 11:50:44 2015 +0100
@@ -46,6 +46,38 @@
 	(struct sieve_interpreter *interp, struct sieve_result *result);
 
 /*
+ * Loop handling
+ */
+
+struct sieve_interpreter_loop;
+
+struct sieve_interpreter_loop *sieve_interpreter_loop_start
+	(struct sieve_interpreter *interp, sieve_size_t loop_end,
+		const struct sieve_extension_def *ext_def);
+struct sieve_interpreter_loop *sieve_interpreter_loop_get
+	(struct sieve_interpreter *interp, sieve_size_t loop_end,
+		const struct sieve_extension_def *ext_def);
+void sieve_interpreter_loop_next
+	(struct sieve_interpreter *interp,
+		struct sieve_interpreter_loop *loop,
+		sieve_size_t loop_begin);
+void sieve_interpreter_loop_break
+	(struct sieve_interpreter *interp,
+		struct sieve_interpreter_loop *loop);
+
+struct sieve_interpreter_loop *sieve_interpreter_loop_get_surrounding
+(struct sieve_interpreter *interp,
+	struct sieve_interpreter_loop *loop,
+	const struct sieve_extension_def *ext_def) ATTR_NULL(2, 3);
+
+pool_t sieve_interpreter_loop_get_pool
+	(struct sieve_interpreter_loop *loop) ATTR_PURE;
+void *sieve_interpreter_loop_get_context
+	(struct sieve_interpreter_loop *loop) ATTR_PURE;
+void sieve_interpreter_loop_set_context
+	(struct sieve_interpreter_loop *loop, void *context);
+
+/*
  * Program flow
  */
 


More information about the dovecot-cvs mailing list