struct sieve_binary *sieve_binary_open (struct sieve_instance *svinst, const char *path, struct sieve_script *script, enum sieve_error *error_r) { struct sieve_binary_extension_reg *const *regs; unsigned int ext_count, i; struct sieve_binary *sbin; struct sieve_binary_file *file; i_assert( script == NULL || sieve_script_svinst(script) == svinst ); //file = _file_memory_open(path); if ( (file=_file_lazy_open(svinst, path, error_r)) == NULL ) return NULL; /* Create binary object */ sbin = sieve_binary_create(svinst, script); sbin->path = p_strdup(sbin->pool, path); sbin->file = file; if ( !_sieve_binary_open(sbin) ) { sieve_binary_unref(&sbin); if ( error_r != NULL ) *error_r = SIEVE_ERROR_NOT_VALID; return NULL; } sieve_binary_activate(sbin); /* Signal open event to extensions */ regs = array_get(&sbin->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { const struct sieve_binary_extension *binext = regs[i]->binext; if ( binext != NULL && binext->binary_open != NULL && !binext->binary_open(regs[i]->extension, sbin, regs[i]->context) ) { /* Extension thinks its corrupt */ if ( error_r != NULL ) *error_r = SIEVE_ERROR_NOT_VALID; sieve_binary_unref(&sbin); return NULL; } } return sbin; }
void sieve_generator_free(struct sieve_generator **gentr) { sieve_ast_unref(&(*gentr)->genenv.ast); sieve_error_handler_unref(&(*gentr)->ehandler); sieve_binary_debug_writer_deinit(&(*gentr)->dwriter); if ( (*gentr)->genenv.sbin != NULL ) sieve_binary_unref(&(*gentr)->genenv.sbin); pool_unref(&((*gentr)->pool)); *gentr = NULL; }
struct sieve_binary *sieve_open_script (struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, enum sieve_error *error_r) { struct sieve_instance *svinst = sieve_script_svinst(script); struct sieve_binary *sbin; T_BEGIN { /* Then try to open the matching binary */ sbin = sieve_script_binary_load(script, error_r); if (sbin != NULL) { /* Ok, it exists; now let's see if it is up to date */ if ( !sieve_binary_up_to_date(sbin, flags) ) { /* Not up to date */ if ( svinst->debug ) { sieve_sys_debug(svinst, "Script binary %s is not up-to-date", sieve_binary_path(sbin)); } sieve_binary_unref(&sbin); sbin = NULL; } } /* If the binary does not exist or is not up-to-date, we need * to (re-)compile. */ if ( sbin != NULL ) { if ( svinst->debug ) { sieve_sys_debug(svinst, "Script binary %s successfully loaded", sieve_binary_path(sbin)); } } else { sbin = sieve_compile_script(script, ehandler, flags, error_r); if ( sbin != NULL ) { if ( svinst->debug ) { sieve_sys_debug(svinst, "Script `%s' from %s successfully compiled", sieve_script_name(script), sieve_script_location(script)); } } } } T_END; return sbin; }
static int cmd_test_binary_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_operation *oprtn = renv->oprtn; string_t *binary_name = NULL; int ret; /* * Read operands */ /* Binary Name */ if ( (ret=sieve_opr_string_read(renv, address, "binary-name", &binary_name)) <= 0 ) return ret; /* * Perform operation */ if ( sieve_operation_is(oprtn, test_binary_load_operation) ) { struct sieve_binary *sbin = testsuite_binary_load(str_c(binary_name)); if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { sieve_runtime_trace(renv, 0, "testsuite: test_binary_load command"); sieve_runtime_trace_descend(renv); sieve_runtime_trace(renv, 0, "load binary `%s'", str_c(binary_name)); } if ( sbin != NULL ) { testsuite_script_set_binary(sbin); sieve_binary_unref(&sbin); } else { sieve_sys_error(testsuite_sieve_instance, "failed to load binary %s", str_c(binary_name)); return SIEVE_EXEC_FAILURE; } } else if ( sieve_operation_is(oprtn, test_binary_save_operation) ) { struct sieve_binary *sbin = testsuite_script_get_binary(); if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { sieve_runtime_trace(renv, 0, "testsuite: test_binary_save command"); sieve_runtime_trace_descend(renv); sieve_runtime_trace(renv, 0, "save binary `%s'", str_c(binary_name)); } if ( sbin != NULL ) testsuite_binary_save(sbin, str_c(binary_name)); else { sieve_sys_error(testsuite_sieve_instance, "no compiled binary to save as %s", str_c(binary_name)); return SIEVE_EXEC_FAILURE; } } else { i_unreached(); } return SIEVE_EXEC_OK; }
struct sieve_binary *sieve_generator_run (struct sieve_generator *gentr, struct sieve_binary_block **sblock_r) { bool topmost = ( sblock_r == NULL || *sblock_r == NULL ); struct sieve_binary *sbin; struct sieve_binary_block *sblock, *debug_block; const struct sieve_extension *const *extensions; unsigned int i, ext_count; bool result = TRUE; /* Initialize */ if ( topmost ) { sbin = sieve_binary_create_new(sieve_ast_script(gentr->genenv.ast)); sblock = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_MAIN_PROGRAM); } else { sblock = *sblock_r; sbin = sieve_binary_block_get_binary(sblock); } i_assert(sbin != NULL); sieve_binary_ref(sbin); gentr->genenv.sbin = sbin; gentr->genenv.sblock = sblock; /* Create debug block */ debug_block = sieve_binary_block_create(sbin); gentr->dwriter = sieve_binary_debug_writer_init(debug_block); (void)sieve_binary_emit_unsigned (sblock, sieve_binary_block_get_id(debug_block)); /* Load extensions linked to the AST and emit a list in code */ extensions = sieve_ast_extensions_get(gentr->genenv.ast, &ext_count); (void) sieve_binary_emit_unsigned(sblock, ext_count); for ( i = 0; i < ext_count; i++ ) { const struct sieve_extension *ext = extensions[i]; /* Link to binary */ (void)sieve_binary_extension_link(sbin, ext); /* Emit */ sieve_binary_emit_extension(sblock, ext, 0); /* Load */ if ( ext->def != NULL && ext->def->generator_load != NULL && !ext->def->generator_load(ext, &gentr->genenv) ) result = FALSE; } /* Generate code */ if ( result ) { if ( !sieve_generate_block (&gentr->genenv, sieve_ast_root(gentr->genenv.ast))) result = FALSE; else if ( topmost ) sieve_binary_activate(sbin); } /* Cleanup */ gentr->genenv.sbin = NULL; gentr->genenv.sblock = NULL; sieve_binary_unref(&sbin); if ( !result ) { if ( topmost ) { sieve_binary_unref(&sbin); if ( sblock_r != NULL ) *sblock_r = NULL; } sbin = NULL; } else { if ( sblock_r != NULL ) *sblock_r = sblock; } return sbin; }
void sieve_close(struct sieve_binary **sbin) { sieve_binary_unref(sbin); }