bool ext_include_variables_save (struct sieve_binary_block *sblock, struct sieve_variable_scope_binary *global_vars) { struct sieve_variable_scope *global_scope = sieve_variable_scope_binary_get(global_vars); unsigned int count = sieve_variable_scope_size(global_scope); sieve_size_t jump; sieve_binary_emit_unsigned(sblock, count); jump = sieve_binary_emit_offset(sblock, 0); if ( count > 0 ) { unsigned int size, i; struct sieve_variable *const *vars = sieve_variable_scope_get_variables(global_scope, &size); for ( i = 0; i < size; i++ ) { sieve_binary_emit_cstring(sblock, vars[i]->identifier); } } sieve_binary_resolve_offset(sblock, jump); return TRUE; }
bool ext_include_variables_dump (struct sieve_dumptime_env *denv, struct sieve_variable_scope_binary *global_vars) { struct sieve_variable_scope *global_scope = sieve_variable_scope_binary_get(global_vars); unsigned int size; struct sieve_variable *const *vars; i_assert(global_scope != NULL); vars = sieve_variable_scope_get_variables(global_scope, &size); if ( size > 0 ) { unsigned int i; sieve_binary_dump_sectionf(denv, "Global variables"); for ( i = 0; i < size; i++ ) { sieve_binary_dumpf(denv, "%3d: '%s' \n", i, vars[i]->identifier); } } return TRUE; }
static bool opc_global_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { const struct sieve_extension *this_ext = denv->oprtn->ext; unsigned int count, i, var_count; struct sieve_variable_scope_binary *global_vars; struct sieve_variable_scope *global_scope; struct sieve_variable * const *vars; if ( !sieve_binary_read_unsigned(denv->sblock, address, &count) ) return FALSE; sieve_code_dumpf(denv, "GLOBAL (count: %u):", count); global_vars = ext_include_binary_get_global_scope(this_ext, denv->sbin); global_scope = sieve_variable_scope_binary_get(global_vars); vars = sieve_variable_scope_get_variables(global_scope, &var_count); sieve_code_descend(denv); for ( i = 0; i < count; i++ ) { unsigned int index; sieve_code_mark(denv); if ( !sieve_binary_read_unsigned(denv->sblock, address, &index) || index >= var_count ) return FALSE; sieve_code_dumpf(denv, "%d: VAR[%d]: '%s'", i, index, vars[index]->identifier); } return TRUE; }
static int opc_global_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct sieve_variable_scope_binary *global_vars; struct sieve_variable_scope *global_scope; struct sieve_variable_storage *storage; struct sieve_variable * const *vars; unsigned int var_count, count, i; if ( !sieve_binary_read_unsigned(renv->sblock, address, &count) ) { sieve_runtime_trace_error(renv, "global: count operand invalid"); return SIEVE_EXEC_BIN_CORRUPT; } global_vars = ext_include_binary_get_global_scope(this_ext, renv->sbin); global_scope = sieve_variable_scope_binary_get(global_vars); vars = sieve_variable_scope_get_variables(global_scope, &var_count); storage = ext_include_interpreter_get_global_variables (this_ext, renv->interp); for ( i = 0; i < count; i++ ) { unsigned int index; if ( !sieve_binary_read_unsigned(renv->sblock, address, &index) ) { sieve_runtime_trace_error(renv, "global: variable index operand invalid"); return SIEVE_EXEC_BIN_CORRUPT; } if ( index >= var_count ) { sieve_runtime_trace_error(renv, "global: variable index %u is invalid in global storage (> %u)", index, var_count); return SIEVE_EXEC_BIN_CORRUPT; } sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "global: exporting variable '%s' [gvid: %u, vid: %u]", vars[index]->identifier, i, index); /* Make sure variable is initialized (export) */ (void)sieve_variable_get_modifiable(storage, index, NULL); } return SIEVE_EXEC_OK; }
} return sieve_variable_scope_import(local_scope, global_var); } /* * Binary symbol table */ bool ext_include_variables_save (struct sieve_binary_block *sblock, struct sieve_variable_scope_binary *global_vars, enum sieve_error *error_r ATTR_UNUSED) { struct sieve_variable_scope *global_scope = sieve_variable_scope_binary_get(global_vars); unsigned int count = sieve_variable_scope_size(global_scope); sieve_size_t jump; sieve_binary_emit_unsigned(sblock, count); jump = sieve_binary_emit_offset(sblock, 0); if ( count > 0 ) { unsigned int size, i; struct sieve_variable *const *vars = sieve_variable_scope_get_variables(global_scope, &size); for ( i = 0; i < size; i++ ) { sieve_binary_emit_cstring(sblock, vars[i]->identifier); }