diff options
-rw-r--r-- | orc/orccompiler.c | 11 | ||||
-rw-r--r-- | orc/orclimits.h | 7 | ||||
-rw-r--r-- | orc/orcprogram.c | 84 | ||||
-rw-r--r-- | orc/orcprogram.h | 1 | ||||
-rw-r--r-- | testsuite/Makefile.am | 3 | ||||
-rw-r--r-- | testsuite/test-limits.c | 72 |
6 files changed, 174 insertions, 4 deletions
diff --git a/orc/orccompiler.c b/orc/orccompiler.c index c30226a..d338a54 100644 --- a/orc/orccompiler.c +++ b/orc/orccompiler.c @@ -189,8 +189,16 @@ orc_program_compile_full (OrcProgram *program, OrcTarget *target, OrcCompiler *compiler; int i; OrcCompileResult result; + const char *error_msg; ORC_INFO("initializing compiler for program \"%s\"", program->name); + error_msg = orc_program_get_error (program); + if (error_msg && strcmp (error_msg, "")) { + ORC_WARNING ("program %s failed to compile, reason: %s", + program->name, error_msg); + return ORC_COMPILE_RESULT_UNKNOWN_PARSE; + } + compiler = malloc (sizeof(OrcCompiler)); memset (compiler, 0, sizeof(OrcCompiler)); @@ -377,8 +385,7 @@ error: program->name, compiler->result); } result = compiler->result; - if (program->error_msg) free (program->error_msg); - program->error_msg = compiler->error_msg; + orc_program_set_error (program, compiler->error_msg); if (result == 0) { result = ORC_COMPILE_RESULT_UNKNOWN_COMPILE; } diff --git a/orc/orclimits.h b/orc/orclimits.h index ebb9828..928b00c 100644 --- a/orc/orclimits.h +++ b/orc/orclimits.h @@ -29,6 +29,13 @@ ORC_BEGIN_DECLS #define ORC_MAX_VAR_SIZE 8 +#define ORC_MAX_DEST_VARS 4 +#define ORC_MAX_SRC_VARS 8 +#define ORC_MAX_TEMP_VARS 16 +#define ORC_MAX_CONST_VARS 8 +#define ORC_MAX_PARAM_VARS 8 +#define ORC_MAX_ACCUM_VARS 4 + enum { ORC_VAR_D1, ORC_VAR_D2, diff --git a/orc/orcprogram.c b/orc/orcprogram.c index 384a68f..9251b97 100644 --- a/orc/orcprogram.c +++ b/orc/orcprogram.c @@ -307,6 +307,11 @@ orc_program_add_temporary (OrcProgram *program, int size, const char *name) { int i = ORC_VAR_T1 + program->n_temp_vars; + if (program->n_temp_vars >= ORC_MAX_TEMP_VARS) { + orc_program_set_error (program, "too many temporary variables allocated"); + return 0; + } + program->vars[i].vartype = ORC_VAR_TYPE_TEMP; program->vars[i].size = size; program->vars[i].name = strdup(name); @@ -330,6 +335,11 @@ orc_program_dup_temporary (OrcProgram *program, int var, int j) { int i = ORC_VAR_T1 + program->n_temp_vars; + if (program->n_temp_vars >= ORC_MAX_TEMP_VARS) { + orc_program_set_error (program, "too many temporary variables allocated"); + return 0; + } + program->vars[i].vartype = ORC_VAR_TYPE_TEMP; program->vars[i].size = program->vars[var].size; program->vars[i].name = malloc (strlen(program->vars[var].name) + 10); @@ -357,6 +367,11 @@ orc_program_add_source_full (OrcProgram *program, int size, const char *name, { int i = ORC_VAR_S1 + program->n_src_vars; + if (program->n_src_vars >= ORC_MAX_SRC_VARS) { + orc_program_set_error (program, "too many source variables allocated"); + return 0; + } + program->vars[i].vartype = ORC_VAR_TYPE_SRC; program->vars[i].size = size; if (alignment == 0) alignment = size; @@ -402,6 +417,11 @@ orc_program_add_destination_full (OrcProgram *program, int size, const char *nam { int i = ORC_VAR_D1 + program->n_dest_vars; + if (program->n_dest_vars >= ORC_MAX_DEST_VARS) { + orc_program_set_error (program, "too many destination variables allocated"); + return 0; + } + program->vars[i].vartype = ORC_VAR_TYPE_DEST; program->vars[i].size = size; if (alignment == 0) alignment = size; @@ -449,6 +469,11 @@ orc_program_add_constant (OrcProgram *program, int size, int value, const char * i = ORC_VAR_C1 + program->n_const_vars; + if (program->n_const_vars >= ORC_MAX_CONST_VARS) { + orc_program_set_error (program, "too many constants allocated"); + return 0; + } + program->vars[i].vartype = ORC_VAR_TYPE_CONST; program->vars[i].size = size; program->vars[i].value.i = value; @@ -466,6 +491,11 @@ orc_program_add_constant_int64 (OrcProgram *program, int size, i = ORC_VAR_C1 + program->n_const_vars; + if (program->n_const_vars >= ORC_MAX_CONST_VARS) { + orc_program_set_error (program, "too many constants allocated"); + return 0; + } + program->vars[i].vartype = ORC_VAR_TYPE_CONST; program->vars[i].size = size; program->vars[i].value.i = value; @@ -505,6 +535,11 @@ orc_program_add_constant_str (OrcProgram *program, int size, i = ORC_VAR_C1 + program->n_const_vars; + if (program->n_const_vars >= ORC_MAX_CONST_VARS) { + orc_program_set_error (program, "too many constants allocated"); + return 0; + } + val_i = _strtoll (value, &end, 0); if (end[0] == 0) { program->vars[i].value.i = val_i; @@ -561,6 +596,11 @@ orc_program_add_parameter (OrcProgram *program, int size, const char *name) { int i = ORC_VAR_P1 + program->n_param_vars; + if (program->n_param_vars >= ORC_MAX_PARAM_VARS) { + orc_program_set_error (program, "too many parameter variables allocated"); + return 0; + } + program->vars[i].vartype = ORC_VAR_TYPE_PARAM; program->vars[i].param_type = ORC_PARAM_TYPE_INT; program->vars[i].size = size; @@ -585,6 +625,11 @@ orc_program_add_parameter_float (OrcProgram *program, int size, const char *name { int i = ORC_VAR_P1 + program->n_param_vars; + if (program->n_param_vars >= ORC_MAX_PARAM_VARS) { + orc_program_set_error (program, "too many parameter variables allocated"); + return 0; + } + program->vars[i].vartype = ORC_VAR_TYPE_PARAM; program->vars[i].param_type = ORC_PARAM_TYPE_FLOAT; program->vars[i].size = size; @@ -600,6 +645,11 @@ orc_program_add_parameter_double (OrcProgram *program, int size, { int i = ORC_VAR_P1 + program->n_param_vars; + if (program->n_param_vars >= ORC_MAX_PARAM_VARS) { + orc_program_set_error (program, "too many parameter variables allocated"); + return 0; + } + program->vars[i].vartype = ORC_VAR_TYPE_PARAM; program->vars[i].param_type = ORC_PARAM_TYPE_DOUBLE; program->vars[i].size = size; @@ -615,6 +665,11 @@ orc_program_add_parameter_int64 (OrcProgram *program, int size, { int i = ORC_VAR_P1 + program->n_param_vars; + if (program->n_param_vars >= ORC_MAX_PARAM_VARS) { + orc_program_set_error (program, "too many parameter variables allocated"); + return 0; + } + program->vars[i].vartype = ORC_VAR_TYPE_PARAM; program->vars[i].param_type = ORC_PARAM_TYPE_INT64; program->vars[i].size = size; @@ -639,6 +694,11 @@ orc_program_add_accumulator (OrcProgram *program, int size, const char *name) { int i = ORC_VAR_A1 + program->n_accum_vars; + if (program->n_accum_vars >= ORC_MAX_ACCUM_VARS) { + orc_program_set_error (program, "too many accumulator variables allocated"); + return 0; + } + program->vars[i].vartype = ORC_VAR_TYPE_ACCUMULATOR; program->vars[i].size = size; program->vars[i].name = strdup(name); @@ -962,7 +1022,8 @@ orc_program_get_asm_code (OrcProgram *program) * * Returns a character string containing the error message from * compilation. This string is valid until the program - * is compiled again or the program is freed. + * is compiled again, the program is freed, or another error + * is set. * * Returns: a character string */ @@ -974,6 +1035,23 @@ orc_program_get_error (OrcProgram *program) } /** + * orc_program_set_error: + * @program: a pointer to an OrcProgram structure + * @error: an error string + * + * Stores the error in the program. This string is duplicated. + * If an error has already been set, this new error is ignored. + * An error will stay till the next call to _reset, if any. + */ +void +orc_program_set_error (OrcProgram *program, const char *error) +{ + if (!program->error_msg && error) { + program->error_msg = strdup (error); + } +} + +/** * orc_program_get_max_array_size: * @program: a pointer to an OrcProgram structure * @@ -1080,6 +1158,10 @@ orc_program_reset (OrcProgram *program) free(program->asm_code); program->asm_code = NULL; } + if (program->error_msg) { + free(program->error_msg); + program->error_msg = NULL; + } } OrcCode * diff --git a/orc/orcprogram.h b/orc/orcprogram.h index 6c442e1..4316ef4 100644 --- a/orc/orcprogram.h +++ b/orc/orcprogram.h @@ -176,6 +176,7 @@ OrcCode *orc_program_take_code (OrcProgram *program); const char *orc_program_get_asm_code (OrcProgram *program); const char * orc_program_get_error (OrcProgram *program); +void orc_program_set_error (OrcProgram *program, const char *error); int orc_program_get_max_array_size (OrcProgram *program); int orc_program_get_max_accumulator_size (OrcProgram *program); diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index a2fc635..9fb62fa 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -12,7 +12,8 @@ TESTS = \ exec_parse \ perf_opcodes_sys perf_parse \ memcpy_speed \ - abi + abi \ + test-limits noinst_PROGRAMS = $(TESTS) generate_xml_table generate_xml_table2 \ generate_opcodes_sys compile_parse compile_parse_c memcpy_speed \ diff --git a/testsuite/test-limits.c b/testsuite/test-limits.c new file mode 100644 index 0000000..ed19d8a --- /dev/null +++ b/testsuite/test-limits.c @@ -0,0 +1,72 @@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <orc/orc.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <orc-test/orctest.h> + + +static int error = FALSE; +static const char *names = "0123456789abcdefX"; + +static void +test_simple (int max, int (*adder) (OrcProgram *, int, const char *)) +{ + OrcProgram *p; + int v; + OrcCompileResult result; + + p = orc_program_new (); + + /* dummy program so compile doesn't barf */ + orc_program_add_destination (p, 2, "d1"); + orc_program_add_source (p, 2, "s1"); + orc_program_append_str (p, "addw", "d1", "d1", "s1"); + + /* we've alreay added one of those */ + if (adder == orc_program_add_destination || adder == orc_program_add_source) + max--; + + /* Check we can add up to the claimed max */ + for (v = 0; v < max; v++) + (*adder) (p, 2, names + v); + result = orc_program_compile (p); + if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL (result)) + error = TRUE; + + /* Check we can not add one more */ + (*adder) (p, 2, names + v); + result = orc_program_compile (p); + if (ORC_COMPILE_RESULT_IS_SUCCESSFUL (result)) + error = TRUE; + + orc_program_free (p); +} + +static int +add_constant (OrcProgram *program, int size, const char *name) +{ + return orc_program_add_constant (program, size, 0, name); +} + +int +main (int argc, char *argv[]) +{ + orc_init(); + orc_test_init(); + + test_simple (ORC_MAX_DEST_VARS, orc_program_add_destination); + test_simple (ORC_MAX_SRC_VARS, orc_program_add_source); + test_simple (ORC_MAX_TEMP_VARS, orc_program_add_temporary); + test_simple (ORC_MAX_CONST_VARS, add_constant); + test_simple (ORC_MAX_PARAM_VARS, orc_program_add_parameter); + test_simple (ORC_MAX_ACCUM_VARS, orc_program_add_accumulator); + + if (error) return 1; + return 0; +} + |