diff --git a/src/lib-sieve/cmd-if.c b/src/lib-sieve/cmd-if.c index 0ba75ad815bb607d992694cfa7592f220cd0c18b..9e93826f8b7b91519aeb3b1c854e58ff40fa5428 100644 --- a/src/lib-sieve/cmd-if.c +++ b/src/lib-sieve/cmd-if.c @@ -2,6 +2,7 @@ #include "sieve-commands-private.h" #include "sieve-validator.h" #include "sieve-generator.h" +#include "sieve-code.h" /* Context */ @@ -149,7 +150,7 @@ bool cmd_if_generate /* Are we the final command in this if-elsif-else structure? */ if ( ctx_data->next != NULL ) { /* No, generate jump to end of if-elsif-else structure (resolved later) */ - sieve_generator_emit_core_opcode(generator, NULL, SIEVE_OPCODE_JMP); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_JMP); ctx_data->exit_jump = sieve_generator_emit_offset(generator, 0); } else { /* Yes, Resolve previous exit jumps to this point */ diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index 8dc7707c84386be2526ed0d9a7976133bd945f1c..65c92b13840e030755b57887a29b6b853ef4d4ad 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -1,3 +1,5 @@ +#include <stdio.h> + #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-validator.h" @@ -6,13 +8,14 @@ /* Forward declarations */ static bool cmd_reject_validate(struct sieve_validator *validator, struct sieve_command_context *cmd); -static bool ext_reject_opcode_dump(struct sieve_interpreter *interpreter, int opcode); +static bool cmd_reject_generate(struct sieve_generator *generator, struct sieve_command_context *ctx); +static bool opc_reject_dump(struct sieve_interpreter *interpreter); /* Extension definitions */ static const struct sieve_command reject_command = - { "reject", SCT_COMMAND, NULL, cmd_reject_validate, NULL, NULL }; -static const struct sieve_opcode_extension reject_opcode = + { "reject", SCT_COMMAND, NULL, cmd_reject_validate, cmd_reject_generate, NULL }; +static const struct sieve_opcode reject_opcode = { opc_reject_dump, NULL }; /* @@ -51,7 +54,7 @@ bool ext_reject_validator_load(struct sieve_validator *validator) * Generation */ -bool cmd_reject_generate +static bool cmd_reject_generate (struct sieve_generator *generator, struct sieve_command_context *ctx) { struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data; @@ -65,6 +68,16 @@ bool cmd_reject_generate return TRUE; } +/* Load extension into generator */ +bool ext_reject_generator_load(struct sieve_generator *generator) +{ + /* Register new command */ + sieve_generator_register_opcode(generator, &reject_opcode); + + return TRUE; +} + + /* * Code dump */ diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index 20c8c2aa45edee1cc77e558fb833af9bef46b721..96e2597e325d1502151465c40578a98b82cfc7d7 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -1,4 +1,7 @@ +#include <stdio.h> + #include "sieve-code.h" +#include "sieve-interpreter.h" /* Code dump for core commands */ diff --git a/src/lib-sieve/sieve-code.h b/src/lib-sieve/sieve-code.h index e8f261d3be82700b2eeab4e76ff42cbfd3bd15f2..02c4734ce8075fbf4806a7c85c3c521f0570a823 100644 --- a/src/lib-sieve/sieve-code.h +++ b/src/lib-sieve/sieve-code.h @@ -4,13 +4,15 @@ #include "sieve-common.h" #include "sieve-extensions.h" +typedef size_t sieve_size_t; + struct sieve_opcode { bool (*dump)(struct sieve_interpreter *interpreter); bool (*execute)(struct sieve_interpreter *interpreter); }; enum sieve_core_operation { - SIEVE_OPCODE_LOAD = 0x01 + SIEVE_OPCODE_LOAD = 0x01, SIEVE_OPCODE_JMP = 0x02, SIEVE_OPCODE_JMPTRUE = 0x03, SIEVE_OPCODE_JMPFALSE = 0x04, diff --git a/src/lib-sieve/sieve-commands-private.h b/src/lib-sieve/sieve-commands-private.h index ee7a93fdbc11a04449b48bef363b9890c76b04be..36fa6a8d9e3951fe831196a5690d3df26db37e95 100644 --- a/src/lib-sieve/sieve-commands-private.h +++ b/src/lib-sieve/sieve-commands-private.h @@ -65,7 +65,9 @@ bool cmd_if_generate(struct sieve_generator *generator, struct sieve_command_con bool cmd_else_generate(struct sieve_generator *generator, struct sieve_command_context *ctx); bool cmd_redirect_validate(struct sieve_validator *validator, struct sieve_command_context *context); + bool cmd_require_validate(struct sieve_validator *validator, struct sieve_command_context *context); +bool cmd_require_generate(struct sieve_generator *generator, struct sieve_command_context *ctx); extern const struct sieve_command sieve_core_commands[]; extern const unsigned int sieve_core_commands_count; diff --git a/src/lib-sieve/sieve-commands.c b/src/lib-sieve/sieve-commands.c index 669253bdf08064ae2b79f03cba7617c66aff4686..52952991f025552f7b746728da0c91d5d1d99d81 100644 --- a/src/lib-sieve/sieve-commands.c +++ b/src/lib-sieve/sieve-commands.c @@ -79,7 +79,7 @@ bool cmd_stop_generate (struct sieve_generator *generator, struct sieve_command_context *ctx __attr_unused__) { - sieve_generator_emit_opcode(generator, NULL, SIEVE_OPCODE_STOP);\ + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_STOP); return TRUE; } @@ -87,7 +87,7 @@ bool cmd_keep_generate (struct sieve_generator *generator, struct sieve_command_context *ctx __attr_unused__) { - sieve_generator_emit_opcode(generator, NULL, SIEVE_OPCODE_KEEP); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_KEEP); return TRUE; } @@ -95,7 +95,7 @@ bool cmd_discard_generate (struct sieve_generator *generator, struct sieve_command_context *ctx __attr_unused__) { - sieve_generator_emit_opcode(generator, NULL, SIEVE_OPCODE_DISCARD); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_DISCARD); return TRUE; } @@ -105,7 +105,7 @@ bool tst_false_generate struct sieve_jumplist *jumps, bool jump_true) { if ( !jump_true ) { - sieve_generator_emit_opcode(generator, NULL, SIEVE_OPCODE_JMP); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_JMP); sieve_jumplist_add(jumps, sieve_generator_emit_offset(generator, 0)); } @@ -118,7 +118,7 @@ bool tst_true_generate struct sieve_jumplist *jumps, bool jump_true) { if ( jump_true ) { - sieve_generator_emit_opcode(generator, NULL, SIEVE_OPCODE_JMP); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_JMP); sieve_jumplist_add(jumps, sieve_generator_emit_offset(generator, 0)); } diff --git a/src/lib-sieve/sieve-extensions.h b/src/lib-sieve/sieve-extensions.h index b76389b21c2567285b018aba222f360bca3f5369..15a841b3b4bc8f530fb4c67f07c12906bd29e578 100644 --- a/src/lib-sieve/sieve-extensions.h +++ b/src/lib-sieve/sieve-extensions.h @@ -9,9 +9,6 @@ struct sieve_extension { bool (*validator_load)(struct sieve_validator *validator); bool (*generator_load)(struct sieve_generator *generator); - - bool (*opcode_dump)(struct sieve_interpreter *interpreter); - bool (*opcode_execute)(struct sieve_interpreter *interpreter); }; const struct sieve_extension *sieve_extension_acquire(const char *extension); diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c index a91263bc664fd6497d6d4073665b5d986e634d3c..921e90990b5baa58e4fd71c631a6f6e912e041ef 100644 --- a/src/lib-sieve/sieve-generator.c +++ b/src/lib-sieve/sieve-generator.c @@ -7,9 +7,13 @@ #include "hash.h" #include "sieve-common.h" +#include "sieve-extensions.h" #include "sieve-commands-private.h" +#include "sieve-code.h" + #include "sieve-generator.h" + /* Jump list */ void sieve_jumplist_init(struct sieve_jumplist *jlist) { @@ -34,6 +38,13 @@ void sieve_jumplist_resolve(struct sieve_jumplist *jlist, struct sieve_generator array_free(&jlist->jumps); } +/* Opcode */ + +struct sieve_opcode_registration { + const struct sieve_opcode *opcode; + unsigned int code; +}; + /* Generator */ struct sieve_generator { @@ -74,18 +85,25 @@ void sieve_generator_free(struct sieve_generator *generator) /* Registration functions */ -void sieve_generator_register_extension - (struct sieve_validator *generator, const struct sieve_extension *extension) +void sieve_generator_register_opcode + (struct sieve_generator *generator, const struct sieve_opcode *opcode) { - unsigned int index = hash_size(generator->extensions); - - hash_insert(generator->extension, (void *) extension, (void *) index); + struct sieve_opcode_registration *reg; + + reg = p_new(generator->pool, struct sieve_opcode_registration, 1); + reg->opcode = opcode; + reg->code = hash_size(generator->opcodes); + + hash_insert(generator->opcodes, (void *) opcode, (void *) reg); } unsigned int sieve_generator_find_opcode - (struct sieve_validator *generator, const struct sieve_opcode *opcode) + (struct sieve_generator *generator, const struct sieve_opcode *opcode) { - return (unsigned int) hash_lookup(generator->opcodes, opcode); + struct sieve_opcode_registration *reg = + (struct sieve_opcode_registration *) hash_lookup(generator->opcodes, opcode); + + return reg->code; } /* Emission functions */ @@ -233,7 +251,8 @@ sieve_size_t sieve_generator_emit_string_list const struct sieve_ast_argument *stritem; unsigned int listlen = sieve_ast_strlist_count(strlist); sieve_size_t end_offset = 0; - + + /* Emit byte identifying the type of operand */ sieve_size_t address = sieve_generator_emit_byte(generator, SIEVE_OPERAND_STRING_LIST); /* Give the interpreter an easy way to skip over this string list */ @@ -263,7 +282,8 @@ sieve_size_t sieve_generator_emit_core_opcode(struct sieve_generator *generator, return sieve_generator_emit_data(generator, (void *) &op, 1); } -sieve_size_t sieve_generator_emit_opcode(struct sieve_generator *generator, struct sieve_opcode *opcode) +sieve_size_t sieve_generator_emit_opcode + (struct sieve_generator *generator, const struct sieve_opcode *opcode) { unsigned char op = (1 << 6) + sieve_generator_find_opcode(generator, opcode); @@ -291,9 +311,9 @@ bool sieve_generate_test if ( tst_node->context->command->generate(generator, tst_node->context) ) { if ( jump_true ) - sieve_generator_emit_core_opcode(generator, NULL, SIEVE_OPCODE_JMPTRUE); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_JMPTRUE); else - sieve_generator_emit_core_opcode(generator, NULL, SIEVE_OPCODE_JMPFALSE); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_JMPFALSE); sieve_jumplist_add(jlist, sieve_generator_emit_offset(generator, 0)); return TRUE; diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h index d529636461024a50d9541557a7eee04d7ec7e42e..808dc76480a73ad5506648252c8471bafffac029 100644 --- a/src/lib-sieve/sieve-generator.h +++ b/src/lib-sieve/sieve-generator.h @@ -2,14 +2,18 @@ #define __SIEVE_GENERATOR_H__ #include "sieve-ast.h" - -typedef size_t sieve_size_t; +#include "sieve-code.h" struct sieve_generator; struct sieve_generator *sieve_generator_create(struct sieve_ast *ast); void sieve_generator_free(struct sieve_generator *generator); +void sieve_generator_register_opcode + (struct sieve_generator *generator, const struct sieve_opcode *opcode); +unsigned int sieve_generator_find_opcode + (struct sieve_generator *generator, const struct sieve_opcode *opcode); + /* Jump list */ struct sieve_jumplist { @@ -27,7 +31,9 @@ inline void sieve_generator_update_data (struct sieve_generator *generator, sieve_size_t address, void *data, sieve_size_t size); inline sieve_size_t sieve_generator_get_current_address(struct sieve_generator *generator); -sieve_size_t sieve_generator_emit_opcode(struct sieve_generator *generator, const char *extension, int opcode); +sieve_size_t sieve_generator_emit_core_opcode(struct sieve_generator *generator, int opcode); +sieve_size_t sieve_generator_emit_opcode(struct sieve_generator *generator, const struct sieve_opcode *opcode); + sieve_size_t sieve_generator_emit_offset(struct sieve_generator *generator, int offset); void sieve_generator_resolve_offset(struct sieve_generator *generator, sieve_size_t address); diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index d58d6d6a6546813e7996e6c1e7c43d9256367ec5..1961e8852c9ca45a0cf317d7b38dd2ad836d9e3c 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -3,6 +3,7 @@ #include "lib.h" #include "mempool.h" +#include "array.h" #include "sieve-commands-private.h" #include "sieve-generator.h" diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c index 82a614ac1f9ca8b1b741de91d55edc7896dab18b..71938e38a899ecbfa3ad5ecc6dcf4bdefe5546f0 100644 --- a/src/lib-sieve/tst-address.c +++ b/src/lib-sieve/tst-address.c @@ -55,7 +55,7 @@ bool tst_address_generate struct sieve_command_context *ctx __attr_unused__) { struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data; - sieve_generator_emit_core_opcode(generator, NULL, SIEVE_OPCODE_ADDRESS); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_ADDRESS); /* Emit header names */ if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) diff --git a/src/lib-sieve/tst-allof.c b/src/lib-sieve/tst-allof.c index aa0d61d343764e243eca1931bd8f312b898b346e..1d708c50d5d2746169410bb0eff78010db6a87c7 100644 --- a/src/lib-sieve/tst-allof.c +++ b/src/lib-sieve/tst-allof.c @@ -44,7 +44,7 @@ bool tst_allof_generate if ( jump_true ) { /* All tests succeeded, jump to case TRUE */ - sieve_generator_emit_core_opcode(generator, NULL, SIEVE_OPCODE_JMP); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_JMP); sieve_jumplist_add(jumps, sieve_generator_emit_offset(generator, 0)); /* All false exits jump here */ diff --git a/src/lib-sieve/tst-anyof.c b/src/lib-sieve/tst-anyof.c index 46f9ac910dc8d5940b69b2526a97f0fc2611a020..0be2dba06eed6ccadfad3dd3c9a8de3496a648b1 100644 --- a/src/lib-sieve/tst-anyof.c +++ b/src/lib-sieve/tst-anyof.c @@ -43,7 +43,7 @@ bool tst_anyof_generate if ( !jump_true ) { /* All tests failed, jump to case FALSE */ - sieve_generator_emit_core_opcode(generator, NULL, SIEVE_OPCODE_JMP); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_JMP); sieve_jumplist_add(jumps, sieve_generator_emit_offset(generator, 0)); /* All true exits jump here */ diff --git a/src/lib-sieve/tst-exists.c b/src/lib-sieve/tst-exists.c index 9e77fe7245d660d8c16d9f0366108a69e8616283..752dff2cda1c30e66169eb5acc8347fc88fd7c00 100644 --- a/src/lib-sieve/tst-exists.c +++ b/src/lib-sieve/tst-exists.c @@ -35,7 +35,7 @@ bool tst_exists_generate struct sieve_command_context *ctx) { struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data; - sieve_generator_emit_core_opcode(generator, NULL, SIEVE_OPCODE_EXISTS); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_EXISTS); /* Emit header names */ if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) diff --git a/src/lib-sieve/tst-header.c b/src/lib-sieve/tst-header.c index c402e823729e2ef67fa25df8689ae52f39bb320a..9f3aad8ef54b3886f3c7646b9891f3e83840f481 100644 --- a/src/lib-sieve/tst-header.c +++ b/src/lib-sieve/tst-header.c @@ -52,7 +52,7 @@ bool tst_header_generate (struct sieve_generator *generator, struct sieve_command_context *ctx) { struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data; - sieve_generator_emit_core_opcode(generator, NULL, SIEVE_OPCODE_HEADER); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_HEADER); /* Emit header names */ if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c index fee84f398fa1159a03c5ba71cf7f31e00c5c0185..69a1994be331b0cf94b00f95ee3a54c817dcb84d 100644 --- a/src/lib-sieve/tst-size.c +++ b/src/lib-sieve/tst-size.c @@ -1,6 +1,7 @@ #include "sieve-commands.h" #include "sieve-commands-private.h" #include "sieve-validator.h" +#include "sieve-code.h" struct tst_size_context_data { enum { SIZE_UNASSIGNED, SIZE_UNDER, SIZE_OVER } type; @@ -104,9 +105,9 @@ bool tst_size_generate struct tst_size_context_data *ctx_data = (struct tst_size_context_data *) ctx->data; if ( ctx_data->type == SIZE_OVER ) - sieve_generator_emit_core_opcode(generator, NULL, SIEVE_OPCODE_SIZEOVER); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_SIZEOVER); else - sieve_generator_emit_core_opcode(generator, NULL, SIEVE_OPCODE_SIZEUNDER); + sieve_generator_emit_core_opcode(generator, SIEVE_OPCODE_SIZEUNDER); sieve_generator_emit_number(generator, ctx_data->limit);