summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--orc/orccompiler.c11
-rw-r--r--orc/orclimits.h7
-rw-r--r--orc/orcprogram.c84
-rw-r--r--orc/orcprogram.h1
-rw-r--r--testsuite/Makefile.am3
-rw-r--r--testsuite/test-limits.c72
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;
+}
+