diff options
Diffstat (limited to 'src/mesa/shader/slang/slang_compile.c')
-rw-r--r-- | src/mesa/shader/slang/slang_compile.c | 1413 |
1 files changed, 706 insertions, 707 deletions
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 02850ebf129..808cf9b82a0 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -27,135 +27,135 @@ * slang front-end compiler * \author Michal Krol */ -
-#include "imports.h"
-#include "grammar_mesa.h"
+ +#include "imports.h" +#include "grammar_mesa.h" #include "slang_utility.h" #include "slang_compile.h" #include "slang_preprocess.h" -#include "slang_storage.h"
-#include "slang_assemble.h"
-#include "slang_execute.h"
+#include "slang_storage.h" +#include "slang_assemble.h" +#include "slang_execute.h" /* - This is a straightforward implementation of the slang front-end compiler. - Lots of error-checking functionality is missing but every well-formed shader source should - compile successfully and execute as expected. However, some semantically ill-formed shaders - may be accepted resulting in undefined behaviour. -*/
-
-/* slang_var_pool */
-
-static GLuint slang_var_pool_alloc (slang_var_pool *pool, unsigned int size)
-{
- GLuint addr;
-
- addr = pool->next_addr;
- pool->next_addr += size;
- return addr;
+ * This is a straightforward implementation of the slang front-end compiler. + * Lots of error-checking functionality is missing but every well-formed shader source should + * compile successfully and execute as expected. However, some semantically ill-formed shaders + * may be accepted resulting in undefined behaviour. + */ + +/* slang_var_pool */ + +static GLuint slang_var_pool_alloc (slang_var_pool *pool, unsigned int size) +{ + GLuint addr; + + addr = pool->next_addr; + pool->next_addr += size; + return addr; } /* slang_translation_unit */ int slang_translation_unit_construct (slang_translation_unit *unit) { - unit->assembly = (slang_assembly_file *) slang_alloc_malloc (sizeof (slang_assembly_file));
- if (unit->assembly == NULL)
- return 0;
- if (!slang_assembly_file_construct (unit->assembly))
- {
- slang_alloc_free (unit->assembly);
- return 0;
- }
- unit->global_pool = (slang_var_pool *) slang_alloc_malloc (sizeof (slang_var_pool));
- if (unit->global_pool == NULL)
- {
- slang_assembly_file_destruct (unit->assembly);
- slang_alloc_free (unit->assembly);
- return 0;
- }
- unit->global_pool->next_addr = 0;
- unit->machine = (slang_machine *) slang_alloc_malloc (sizeof (slang_machine));
- if (unit->machine == NULL)
- {
- slang_alloc_free (unit->global_pool);
- slang_assembly_file_destruct (unit->assembly);
- slang_alloc_free (unit->assembly);
- return 0;
- }
- slang_machine_init (unit->machine);
- unit->atom_pool = (slang_atom_pool *) slang_alloc_malloc (sizeof (slang_atom_pool));
- if (unit->atom_pool == NULL)
- {
- slang_alloc_free (unit->machine);
- slang_alloc_free (unit->global_pool);
- slang_assembly_file_destruct (unit->assembly);
- slang_alloc_free (unit->assembly);
- return 0;
- }
- slang_atom_pool_construct (unit->atom_pool);
- if (!slang_translation_unit_construct2 (unit, unit->assembly, unit->global_pool, unit->machine,
- unit->atom_pool))
- {
- slang_alloc_free (unit->atom_pool);
- slang_alloc_free (unit->machine);
- slang_alloc_free (unit->global_pool);
- slang_assembly_file_destruct (unit->assembly);
- slang_alloc_free (unit->assembly);
- return 0;
- }
- unit->free_assembly = 1;
- unit->free_global_pool = 1;
- unit->free_machine = 1;
- unit->free_atom_pool = 1;
+ unit->assembly = (slang_assembly_file *) slang_alloc_malloc (sizeof (slang_assembly_file)); + if (unit->assembly == NULL) + return 0; + if (!slang_assembly_file_construct (unit->assembly)) + { + slang_alloc_free (unit->assembly); + return 0; + } + unit->global_pool = (slang_var_pool *) slang_alloc_malloc (sizeof (slang_var_pool)); + if (unit->global_pool == NULL) + { + slang_assembly_file_destruct (unit->assembly); + slang_alloc_free (unit->assembly); + return 0; + } + unit->global_pool->next_addr = 0; + unit->machine = (slang_machine *) slang_alloc_malloc (sizeof (slang_machine)); + if (unit->machine == NULL) + { + slang_alloc_free (unit->global_pool); + slang_assembly_file_destruct (unit->assembly); + slang_alloc_free (unit->assembly); + return 0; + } + slang_machine_init (unit->machine); + unit->atom_pool = (slang_atom_pool *) slang_alloc_malloc (sizeof (slang_atom_pool)); + if (unit->atom_pool == NULL) + { + slang_alloc_free (unit->machine); + slang_alloc_free (unit->global_pool); + slang_assembly_file_destruct (unit->assembly); + slang_alloc_free (unit->assembly); + return 0; + } + slang_atom_pool_construct (unit->atom_pool); + if (!slang_translation_unit_construct2 (unit, unit->assembly, unit->global_pool, unit->machine, + unit->atom_pool)) + { + slang_alloc_free (unit->atom_pool); + slang_alloc_free (unit->machine); + slang_alloc_free (unit->global_pool); + slang_assembly_file_destruct (unit->assembly); + slang_alloc_free (unit->assembly); + return 0; + } + unit->free_assembly = 1; + unit->free_global_pool = 1; + unit->free_machine = 1; + unit->free_atom_pool = 1; + return 1; +} + +int slang_translation_unit_construct2 (slang_translation_unit *unit, slang_assembly_file *file, + slang_var_pool *pool, struct slang_machine_ *mach, slang_atom_pool *atoms) +{ + if (!slang_variable_scope_construct (&unit->globals)) + return 0; + if (!slang_function_scope_construct (&unit->functions)) + { + slang_variable_scope_destruct (&unit->globals); + return 0; + } + if (!slang_struct_scope_construct (&unit->structs)) + { + slang_variable_scope_destruct (&unit->globals); + slang_function_scope_destruct (&unit->functions); + return 0; + } + unit->assembly = file; + unit->free_assembly = 0; + unit->global_pool = pool; + unit->free_global_pool = 0; + unit->machine = mach; + unit->free_machine = 0; + unit->atom_pool = atoms; + unit->free_atom_pool = 0; return 1; -}
-
-int slang_translation_unit_construct2 (slang_translation_unit *unit, slang_assembly_file *file,
- slang_var_pool *pool, struct slang_machine_ *mach, slang_atom_pool *atoms)
-{
- if (!slang_variable_scope_construct (&unit->globals))
- return 0;
- if (!slang_function_scope_construct (&unit->functions))
- {
- slang_variable_scope_destruct (&unit->globals);
- return 0;
- }
- if (!slang_struct_scope_construct (&unit->structs))
- {
- slang_variable_scope_destruct (&unit->globals);
- slang_function_scope_destruct (&unit->functions);
- return 0;
- }
- unit->assembly = file;
- unit->free_assembly = 0;
- unit->global_pool = pool;
- unit->free_global_pool = 0;
- unit->machine = mach;
- unit->free_machine = 0;
- unit->atom_pool = atoms;
- unit->free_atom_pool = 0;
- return 1;
} void slang_translation_unit_destruct (slang_translation_unit *unit) { slang_variable_scope_destruct (&unit->globals); slang_function_scope_destruct (&unit->functions); - slang_struct_scope_destruct (&unit->structs);
- if (unit->free_assembly)
- {
- slang_assembly_file_destruct (unit->assembly);
- slang_alloc_free (unit->assembly);
- }
- if (unit->free_global_pool)
- slang_alloc_free (unit->global_pool);
- if (unit->free_machine)
- slang_alloc_free (unit->machine);
- if (unit->free_atom_pool)
- {
- slang_atom_pool_destruct (unit->atom_pool);
- slang_alloc_free (unit->atom_pool);
+ slang_struct_scope_destruct (&unit->structs); + if (unit->free_assembly) + { + slang_assembly_file_destruct (unit->assembly); + slang_alloc_free (unit->assembly); + } + if (unit->free_global_pool) + slang_alloc_free (unit->global_pool); + if (unit->free_machine) + slang_alloc_free (unit->machine); + if (unit->free_atom_pool) + { + slang_atom_pool_destruct (unit->atom_pool); + slang_alloc_free (unit->atom_pool); } } @@ -177,14 +177,14 @@ void slang_info_log_destruct (slang_info_log *log) static int slang_info_log_message (slang_info_log *log, const char *prefix, const char *msg) { - unsigned int new_size;
+ unsigned int new_size; if (log->dont_free_text) return 0; new_size = slang_string_length (prefix) + 3 + slang_string_length (msg); if (log->text != NULL) - {
- unsigned int text_len = slang_string_length (log->text);
+ { + unsigned int text_len = slang_string_length (log->text); log->text = (char *) slang_alloc_realloc (log->text, text_len + 1, new_size + text_len + 1); } @@ -246,38 +246,38 @@ typedef struct slang_parse_ctx_ { const byte *I; slang_info_log *L; - int parsing_builtin;
- int global_scope;
+ int parsing_builtin; + int global_scope; slang_atom_pool *atoms; -} slang_parse_ctx;
-
-/* slang_output_ctx */
-
-typedef struct slang_output_ctx_
-{
- slang_variable_scope *vars;
- slang_function_scope *funs;
- slang_struct_scope *structs;
- slang_assembly_file *assembly;
- slang_var_pool *global_pool;
- slang_machine *machine;
+} slang_parse_ctx; + +/* slang_output_ctx */ + +typedef struct slang_output_ctx_ +{ + slang_variable_scope *vars; + slang_function_scope *funs; + slang_struct_scope *structs; + slang_assembly_file *assembly; + slang_var_pool *global_pool; + slang_machine *machine; } slang_output_ctx; /* _slang_compile() */ static void parse_identifier_str (slang_parse_ctx *C, char **id) { - *id = (char *) C->I;
+ *id = (char *) C->I; C->I += _mesa_strlen (*id) + 1; -}
-
-static slang_atom parse_identifier (slang_parse_ctx *C)
-{
- const char *id;
-
- id = (const char *) C->I;
- C->I += _mesa_strlen (id) + 1;
- return slang_atom_pool_atom (C->atoms, id);
+} + +static slang_atom parse_identifier (slang_parse_ctx *C) +{ + const char *id; + + id = (const char *) C->I; + C->I += _mesa_strlen (id) + 1; + return slang_atom_pool_atom (C->atoms, id); } static int parse_number (slang_parse_ctx *C, int *number) @@ -311,9 +311,9 @@ static int parse_float (slang_parse_ctx *C, float *number) parse_identifier_str (C, &integral); parse_identifier_str (C, &fractional); - parse_identifier_str (C, &exponent);
+ parse_identifier_str (C, &exponent); - whole = (char *) (slang_alloc_malloc ((_mesa_strlen (integral) + _mesa_strlen (fractional) +
+ whole = (char *) (slang_alloc_malloc ((_mesa_strlen (integral) + _mesa_strlen (fractional) + _mesa_strlen (exponent) + 3) * sizeof (char))); if (whole == NULL) { @@ -348,151 +348,151 @@ static int check_revision (slang_parse_ctx *C) } static int parse_statement (slang_parse_ctx *, slang_output_ctx *, slang_operation *); -static int parse_expression (slang_parse_ctx *, slang_output_ctx *, slang_operation *);
-static int parse_type_specifier (slang_parse_ctx *, slang_output_ctx *, slang_type_specifier *);
-
-/* structure field */
-#define FIELD_NONE 0
-#define FIELD_NEXT 1
-#define FIELD_ARRAY 2
-
-static int parse_struct_field_var (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var)
-{
- var->a_name = parse_identifier (C);
- if (var->a_name == SLANG_ATOM_NULL)
- return 0;
-
- switch (*C->I++)
- {
- case FIELD_NONE:
- break;
- case FIELD_ARRAY:
- var->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
- if (var->array_size == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- if (!slang_operation_construct (var->array_size))
- {
- slang_alloc_free (var->array_size);
- var->array_size = NULL;
- return 0;
- }
- if (!parse_expression (C, O, var->array_size))
- return 0;
- break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-static int parse_struct_field (slang_parse_ctx *C, slang_output_ctx *O, slang_struct *st,
- slang_type_specifier *sp)
-{
- slang_output_ctx o = *O;
-
- o.structs = st->structs;
- if (!parse_type_specifier (C, &o, sp))
- return 0;
- do
- {
- slang_variable *var;
-
- st->fields->variables = (slang_variable *) slang_alloc_realloc (st->fields->variables,
- st->fields->num_variables * sizeof (slang_variable),
- (st->fields->num_variables + 1) * sizeof (slang_variable));
- if (st->fields->variables == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- var = &st->fields->variables[st->fields->num_variables];
- if (!slang_variable_construct (var))
- return 0;
- st->fields->num_variables++;
- if (!slang_type_specifier_copy (&var->type.specifier, sp))
- return 0;
- if (!parse_struct_field_var (C, &o, var))
- return 0;
- }
- while (*C->I++ != FIELD_NONE);
-
- return 1;
-}
-
-static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct **st)
-{
- slang_atom a_name;
- const char *name;
-
- /* parse struct name (if any) and make sure it is unique in current scope */
- a_name = parse_identifier (C);
- if (a_name == SLANG_ATOM_NULL)
- return 0;
- name = slang_atom_pool_id (C->atoms, a_name);
- if (name[0] != '\0' && slang_struct_scope_find (O->structs, a_name, 0) != NULL)
- {
- slang_info_log_error (C->L, "%s: duplicate type name", name);
- return 0;
- }
-
- /* set-up a new struct */
- *st = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
- if (*st == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- if (!slang_struct_construct (*st))
- {
- slang_alloc_free (*st);
- *st = NULL;
- slang_info_log_memory (C->L);
- return 0;
- }
- (**st).a_name = a_name;
- (**st).structs->outer_scope = O->structs;
-
- /* parse individual struct fields */
- do
- {
- slang_type_specifier sp;
-
- if (!slang_type_specifier_construct (&sp))
- return 0;
- if (!parse_struct_field (C, O, *st, &sp))
- {
- slang_type_specifier_destruct (&sp);
- return 0;
- }
- }
- while (*C->I++ != FIELD_NONE);
-
- /* if named struct, copy it to current scope */
- if (name[0] != '\0')
- {
- slang_struct *s;
-
- O->structs->structs = (slang_struct *) slang_alloc_realloc (O->structs->structs,
- O->structs->num_structs * sizeof (slang_struct),
- (O->structs->num_structs + 1) * sizeof (slang_struct));
- if (O->structs->structs == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- s = &O->structs->structs[O->structs->num_structs];
- if (!slang_struct_construct (s))
- return 0;
- O->structs->num_structs++;
- if (!slang_struct_copy (s, *st))
- return 0;
- }
-
- return 1;
+static int parse_expression (slang_parse_ctx *, slang_output_ctx *, slang_operation *); +static int parse_type_specifier (slang_parse_ctx *, slang_output_ctx *, slang_type_specifier *); + +/* structure field */ +#define FIELD_NONE 0 +#define FIELD_NEXT 1 +#define FIELD_ARRAY 2 + +static int parse_struct_field_var (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var) +{ + var->a_name = parse_identifier (C); + if (var->a_name == SLANG_ATOM_NULL) + return 0; + + switch (*C->I++) + { + case FIELD_NONE: + break; + case FIELD_ARRAY: + var->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); + if (var->array_size == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + if (!slang_operation_construct (var->array_size)) + { + slang_alloc_free (var->array_size); + var->array_size = NULL; + return 0; + } + if (!parse_expression (C, O, var->array_size)) + return 0; + break; + default: + return 0; + } + + return 1; +} + +static int parse_struct_field (slang_parse_ctx *C, slang_output_ctx *O, slang_struct *st, + slang_type_specifier *sp) +{ + slang_output_ctx o = *O; + + o.structs = st->structs; + if (!parse_type_specifier (C, &o, sp)) + return 0; + do + { + slang_variable *var; + + st->fields->variables = (slang_variable *) slang_alloc_realloc (st->fields->variables, + st->fields->num_variables * sizeof (slang_variable), + (st->fields->num_variables + 1) * sizeof (slang_variable)); + if (st->fields->variables == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + var = &st->fields->variables[st->fields->num_variables]; + if (!slang_variable_construct (var)) + return 0; + st->fields->num_variables++; + if (!slang_type_specifier_copy (&var->type.specifier, sp)) + return 0; + if (!parse_struct_field_var (C, &o, var)) + return 0; + } + while (*C->I++ != FIELD_NONE); + + return 1; +} + +static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct **st) +{ + slang_atom a_name; + const char *name; + + /* parse struct name (if any) and make sure it is unique in current scope */ + a_name = parse_identifier (C); + if (a_name == SLANG_ATOM_NULL) + return 0; + name = slang_atom_pool_id (C->atoms, a_name); + if (name[0] != '\0' && slang_struct_scope_find (O->structs, a_name, 0) != NULL) + { + slang_info_log_error (C->L, "%s: duplicate type name", name); + return 0; + } + + /* set-up a new struct */ + *st = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct)); + if (*st == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + if (!slang_struct_construct (*st)) + { + slang_alloc_free (*st); + *st = NULL; + slang_info_log_memory (C->L); + return 0; + } + (**st).a_name = a_name; + (**st).structs->outer_scope = O->structs; + + /* parse individual struct fields */ + do + { + slang_type_specifier sp; + + if (!slang_type_specifier_construct (&sp)) + return 0; + if (!parse_struct_field (C, O, *st, &sp)) + { + slang_type_specifier_destruct (&sp); + return 0; + } + } + while (*C->I++ != FIELD_NONE); + + /* if named struct, copy it to current scope */ + if (name[0] != '\0') + { + slang_struct *s; + + O->structs->structs = (slang_struct *) slang_alloc_realloc (O->structs->structs, + O->structs->num_structs * sizeof (slang_struct), + (O->structs->num_structs + 1) * sizeof (slang_struct)); + if (O->structs->structs == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + s = &O->structs->structs[O->structs->num_structs]; + if (!slang_struct_construct (s)) + return 0; + O->structs->num_structs++; + if (!slang_struct_copy (s, *st)) + return 0; + } + + return 1; } /* type qualifier */ @@ -632,24 +632,24 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_output_ctx *O, slang_ spec->type = slang_spec_sampler2DShadow; break; case TYPE_SPECIFIER_STRUCT: - spec->type = slang_spec_struct;
+ spec->type = slang_spec_struct; if (!parse_struct (C, O, &spec->_struct)) return 0; break; - case TYPE_SPECIFIER_TYPENAME:
+ case TYPE_SPECIFIER_TYPENAME: spec->type = slang_spec_struct; { slang_atom a_name; - slang_struct *stru;
+ slang_struct *stru; - a_name = parse_identifier (C);
+ a_name = parse_identifier (C); if (a_name == NULL) - return 0;
+ return 0; stru = slang_struct_scope_find (O->structs, a_name, 1); if (stru == NULL) { - slang_info_log_error (C->L, "%s: undeclared type name",
+ slang_info_log_error (C->L, "%s: undeclared type name", slang_atom_pool_id (C->atoms, a_name)); return 0; } @@ -676,7 +676,7 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_output_ctx *O, slang_ return 1; } -static int parse_fully_specified_type (slang_parse_ctx *C, slang_output_ctx *O,
+static int parse_fully_specified_type (slang_parse_ctx *C, slang_output_ctx *O, slang_fully_specified_type *type) { if (!parse_type_qualifier (C, &type->qualifier)) @@ -748,10 +748,10 @@ static int parse_fully_specified_type (slang_parse_ctx *C, slang_output_ctx *O, #define OP_POSTINCREMENT 60 #define OP_POSTDECREMENT 61 -static int parse_child_operation (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper,
+static int parse_child_operation (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper, int statement) -{
- slang_operation *ch;
+{ + slang_operation *ch; oper->children = (slang_operation *) slang_alloc_realloc (oper->children, oper->num_children * sizeof (slang_operation), @@ -760,7 +760,7 @@ static int parse_child_operation (slang_parse_ctx *C, slang_output_ctx *O, slang { slang_info_log_memory (C->L); return 0; - }
+ } ch = &oper->children[oper->num_children]; if (!slang_operation_construct (ch)) { @@ -780,7 +780,7 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera oper->locals->outer_scope = O->vars; switch (*C->I++) { - case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
+ case OP_BLOCK_BEGIN_NO_NEW_SCOPE: /* parse child statements, do not create new variable scope */ oper->type = slang_oper_block_no_new_scope; while (*C->I != OP_END) @@ -788,32 +788,32 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera return 0; C->I++; break; - case OP_BLOCK_BEGIN_NEW_SCOPE:
+ case OP_BLOCK_BEGIN_NEW_SCOPE: /* parse child statements, create new variable scope */ - {
- slang_output_ctx o = *O;
-
- oper->type = slang_oper_block_new_scope;
+ { + slang_output_ctx o = *O; + + oper->type = slang_oper_block_new_scope; o.vars = oper->locals; - while (*C->I != OP_END)
+ while (*C->I != OP_END) if (!parse_child_operation (C, &o, oper, 1)) - return 0;
- C->I++;
+ return 0; + C->I++; } break; - case OP_DECLARE:
+ case OP_DECLARE: /* local variable declaration, individual declarators are stored as children identifiers */ oper->type = slang_oper_variable_decl; { - const unsigned int first_var = O->vars->num_variables;
-
+ const unsigned int first_var = O->vars->num_variables; + /* parse the declaration, note that there can be zero or more than one declarators */ if (!parse_declaration (C, O)) return 0; if (first_var < O->vars->num_variables) { const unsigned int num_vars = O->vars->num_variables - first_var; - unsigned int i;
+ unsigned int i; oper->children = (slang_operation *) slang_alloc_malloc (num_vars * sizeof ( slang_operation)); @@ -830,7 +830,7 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera } for (i = first_var; i < O->vars->num_variables; i++) { - slang_operation *o = &oper->children[i - first_var];
+ slang_operation *o = &oper->children[i - first_var]; o->type = slang_oper_identifier; o->locals->outer_scope = O->vars; @@ -839,10 +839,10 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera } } break; - case OP_ASM:
+ case OP_ASM: /* the __asm statement, parse the mnemonic and all its arguments as expressions */ - oper->type = slang_oper_asm;
- oper->a_id = parse_identifier (C);
+ oper->type = slang_oper_asm; + oper->a_id = parse_identifier (C); if (oper->a_id == SLANG_ATOM_NULL) return 0; while (*C->I != OP_END) @@ -879,15 +879,15 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera return 0; break; case OP_WHILE: - {
- slang_output_ctx o = *O;
-
- oper->type = slang_oper_while;
+ { + slang_output_ctx o = *O; + + oper->type = slang_oper_while; o.vars = oper->locals; if (!parse_child_operation (C, &o, oper, 1)) return 0; if (!parse_child_operation (C, &o, oper, 1)) - return 0;
+ return 0; } break; case OP_DO: @@ -898,10 +898,10 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera return 0; break; case OP_FOR: - {
- slang_output_ctx o = *O;
-
- oper->type = slang_oper_for;
+ { + slang_output_ctx o = *O; + + oper->type = slang_oper_for; o.vars = oper->locals; if (!parse_child_operation (C, &o, oper, 1)) return 0; @@ -910,41 +910,41 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera if (!parse_child_operation (C, &o, oper, 0)) return 0; if (!parse_child_operation (C, &o, oper, 1)) - return 0;
+ return 0; } break; default: return 0; } return 1; -}
-
-static int handle_nary_expression (slang_parse_ctx *C, slang_operation *op, slang_operation **ops,
- unsigned int *total_ops, unsigned int n)
-{
- unsigned int i;
-
- op->children = (slang_operation *) slang_alloc_malloc (n * sizeof (slang_operation));
- if (op->children == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- op->num_children = n;
-
- for (i = 0; i < n; i++)
- op->children[i] = (*ops)[*total_ops - (n + 1 - i)];
- (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];
- *total_ops -= n;
-
- *ops = (slang_operation *) slang_alloc_realloc (*ops, (*total_ops + n) * sizeof (slang_operation),
- *total_ops * sizeof (slang_operation));
- if (*ops == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- return 1;
+} + +static int handle_nary_expression (slang_parse_ctx *C, slang_operation *op, slang_operation **ops, + unsigned int *total_ops, unsigned int n) +{ + unsigned int i; + + op->children = (slang_operation *) slang_alloc_malloc (n * sizeof (slang_operation)); + if (op->children == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + op->num_children = n; + + for (i = 0; i < n; i++) + op->children[i] = (*ops)[*total_ops - (n + 1 - i)]; + (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1]; + *total_ops -= n; + + *ops = (slang_operation *) slang_alloc_realloc (*ops, (*total_ops + n) * sizeof (slang_operation), + *total_ops * sizeof (slang_operation)); + if (*ops == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + return 1; } static int is_constructor_name (const char *name, slang_atom a_name, slang_struct_scope *structs) @@ -963,8 +963,8 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper while (*C->I != OP_END) { slang_operation *op; - const unsigned int op_code = *C->I++;
-
+ const unsigned int op_code = *C->I++; + /* allocate default operation, becomes a no-op if not used */ ops = (slang_operation *) slang_alloc_realloc (ops, num_ops * sizeof (slang_operation), (num_ops + 1) * sizeof (slang_operation)); @@ -980,7 +980,7 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper return 0; } num_ops++; - op->locals->outer_scope = O->vars;
+ op->locals->outer_scope = O->vars; switch (op_code) { @@ -1006,7 +1006,7 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper break; case OP_PUSH_IDENTIFIER: op->type = slang_oper_identifier; - op->a_id = parse_identifier (C);
+ op->a_id = parse_identifier (C); if (op->a_id == SLANG_ATOM_NULL) return 0; break; @@ -1155,28 +1155,28 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper break; case OP_CALL: op->type = slang_oper_call; - op->a_id = parse_identifier (C);
+ op->a_id = parse_identifier (C); if (op->a_id == SLANG_ATOM_NULL) return 0; while (*C->I != OP_END) if (!parse_child_operation (C, O, op, 0)) return 0; C->I++; - if (!C->parsing_builtin && !slang_function_scope_find_by_name (O->funs, op->a_id, 1))
- {
- const char *id;
-
+ if (!C->parsing_builtin && !slang_function_scope_find_by_name (O->funs, op->a_id, 1)) + { + const char *id; + id = slang_atom_pool_id (C->atoms, op->a_id); if (!is_constructor_name (id, op->a_id, O->structs)) { slang_info_log_error (C->L, "%s: undeclared function name", id); return 0; - }
+ } } break; case OP_FIELD: op->type = slang_oper_field; - op->a_id = parse_identifier (C);
+ op->a_id = parse_identifier (C); if (op->a_id == SLANG_ATOM_NULL) return 0; if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) @@ -1196,7 +1196,7 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper return 0; } } - C->I++;
+ C->I++; *oper = *ops; slang_alloc_free (ops); @@ -1212,12 +1212,12 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper #define PARAMETER_ARRAY_NOT_PRESENT 0 #define PARAMETER_ARRAY_PRESENT 1 -static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O,
+static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *param) { - slang_storage_aggregate agg;
-
- /* parse and validate the parameter's type qualifiers (there can be two at most) because
+ slang_storage_aggregate agg; + + /* parse and validate the parameter's type qualifiers (there can be two at most) because * not all combinations are valid */ if (!parse_type_qualifier (C, ¶m->type.qualifier)) return 0; @@ -1250,15 +1250,15 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O, break; default: return 0; - }
-
+ } + /* parse parameter's type specifier and name */ if (!parse_type_specifier (C, O, ¶m->type.specifier)) - return 0;
+ return 0; param->a_name = parse_identifier (C); - if (param->a_name == SLANG_ATOM_NULL)
- return 0;
-
+ if (param->a_name == SLANG_ATOM_NULL) + return 0; + /* if the parameter is an array, parse its size (the size must be explicitly defined */ if (*C->I++ == PARAMETER_ARRAY_PRESENT) { @@ -1276,22 +1276,22 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O, return 0; } if (!parse_expression (C, O, param->array_size)) - return 0;
+ return 0; /* TODO: execute the array_size */ - }
-
- /* calculate the parameter size */
- if (!slang_storage_aggregate_construct (&agg))
- return 0;
- if (!_slang_aggregate_variable (&agg, ¶m->type.specifier, param->array_size, O->funs,
- O->structs, O->vars, O->machine, O->assembly, C->atoms))
- {
- slang_storage_aggregate_destruct (&agg);
- return 0;
- }
- param->size = _slang_sizeof_aggregate (&agg);
- slang_storage_aggregate_destruct (&agg);
- /* TODO: allocate the local address here? */
+ } + + /* calculate the parameter size */ + if (!slang_storage_aggregate_construct (&agg)) + return 0; + if (!_slang_aggregate_variable (&agg, ¶m->type.specifier, param->array_size, O->funs, + O->structs, O->vars, O->machine, O->assembly, C->atoms)) + { + slang_storage_aggregate_destruct (&agg); + return 0; + } + param->size = _slang_sizeof_aggregate (&agg); + slang_storage_aggregate_destruct (&agg); + /* TODO: allocate the local address here? */ return 1; } @@ -1372,9 +1372,9 @@ static const struct { static slang_atom parse_operator_name (slang_parse_ctx *C) { - unsigned int i;
+ unsigned int i; - for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++)
+ for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++) { if (operator_names[i].o_code == (unsigned int) (*C->I)) { @@ -1386,23 +1386,23 @@ static slang_atom parse_operator_name (slang_parse_ctx *C) } C->I++; return atom; - }
+ } } return 0; } static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func) -{
+{ /* parse function type and name */ if (!parse_fully_specified_type (C, O, &func->header.type)) return 0; switch (*C->I++) { - case FUNCTION_ORDINARY:
+ case FUNCTION_ORDINARY: func->kind = slang_func_ordinary; func->header.a_name = parse_identifier (C); - if (func->header.a_name == SLANG_ATOM_NULL)
- return 0;
+ if (func->header.a_name == SLANG_ATOM_NULL) + return 0; break; case FUNCTION_CONSTRUCTOR: func->kind = slang_func_constructor; @@ -1418,18 +1418,18 @@ static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, sl break; case FUNCTION_OPERATOR: func->kind = slang_func_operator; - func->header.a_name = parse_operator_name (C);
+ func->header.a_name = parse_operator_name (C); if (func->header.a_name == SLANG_ATOM_NULL) return 0; break; default: return 0; - }
-
+ } + /* parse function parameters */ while (*C->I++ == PARAMETER_NEXT) - {
- slang_variable *p;
+ { + slang_variable *p; func->parameters->variables = (slang_variable *) slang_alloc_realloc ( func->parameters->variables, @@ -1439,31 +1439,31 @@ static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, sl { slang_info_log_memory (C->L); return 0; - }
+ } p = &func->parameters->variables[func->parameters->num_variables]; - if (!slang_variable_construct (p))
- return 0;
+ if (!slang_variable_construct (p)) + return 0; func->parameters->num_variables++; if (!parse_parameter_declaration (C, O, p)) return 0; - }
-
- /* function formal parameters and local variables share the same scope, so save
- * the information about param count in a seperate place
- * also link the scope to the global variable scope so when a given identifier is not
+ } + + /* function formal parameters and local variables share the same scope, so save + * the information about param count in a seperate place + * also link the scope to the global variable scope so when a given identifier is not * found here, the search process continues in the global space */ - func->param_count = func->parameters->num_variables;
+ func->param_count = func->parameters->num_variables; func->parameters->outer_scope = O->vars; return 1; } static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func) -{
- slang_output_ctx o = *O;
+{ + slang_output_ctx o = *O; if (!parse_function_prototype (C, O, func)) - return 0;
-
+ return 0; + /* create function's body operation */ func->body = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); if (func->body == NULL) @@ -1477,110 +1477,109 @@ static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, s func->body = NULL; slang_info_log_memory (C->L); return 0; - }
-
- /* to parse the body the parse context is modified in order to capture parsed variables
- * into function's local variable scope */
- C->global_scope = 0;
+ } + + /* to parse the body the parse context is modified in order to capture parsed variables + * into function's local variable scope */ + C->global_scope = 0; o.vars = func->parameters; if (!parse_statement (C, &o, func->body)) - return 0;
+ return 0; C->global_scope = 1; return 1; -}
-
-static int initialize_global (slang_assemble_ctx *A, slang_variable *var)
-{
- slang_assembly_file_restore_point point;
- slang_machine mach;
- slang_assembly_local_info info;
- slang_operation op_id, op_assign;
- int result;
- slang_assembly_flow_control flow;
- slang_assembly_stack_info stk;
-
- /* save the current assembly */
- if (!slang_assembly_file_restore_point_save (A->file, &point))
- return 0;
-
- /* setup the machine */
- mach = *A->mach;
- mach.ip = A->file->count;
-
- /* allocate local storage for expression */
- info.ret_size = 0;
- info.addr_tmp = 0;
- info.swizzle_tmp = 4;
- if (!slang_assembly_file_push_label (A->file, slang_asm_local_alloc, 20))
- return 0;
- if (!slang_assembly_file_push_label (A->file, slang_asm_enter, 20))
- return 0;
-
- /* construct the left side of assignment */
- if (!slang_operation_construct (&op_id))
- return 0;
- op_id.type = slang_oper_identifier;
- op_id.a_id = var->a_name;
-
- /* put the variable into operation's scope */
- op_id.locals->variables = (slang_variable *) slang_alloc_malloc (sizeof (slang_variable));
- if (op_id.locals->variables == NULL)
- {
- slang_operation_destruct (&op_id);
- return 0;
- }
- op_id.locals->num_variables = 1;
- op_id.locals->variables[0] = *var;
-
- /* construct the assignment expression */
- if (!slang_operation_construct (&op_assign))
- {
- op_id.locals->num_variables = 0;
- slang_operation_destruct (&op_id);
- return 0;
- }
- op_assign.type = slang_oper_assign;
- op_assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
- if (op_assign.children == NULL)
- {
- slang_operation_destruct (&op_assign);
- op_id.locals->num_variables = 0;
- slang_operation_destruct (&op_id);
- return 0;
- }
- op_assign.num_children = 2;
- op_assign.children[0] = op_id;
- op_assign.children[1] = *var->initializer;
-
- /* insert the actual expression */
- result = _slang_assemble_operation (A->file, &op_assign, 0, &flow, &A->space, &info, &stk, A->mach, A->atoms);
-
- /* carefully destroy the operations */
- op_assign.num_children = 0;
- slang_alloc_free (op_assign.children);
- op_assign.children = NULL;
- slang_operation_destruct (&op_assign);
- op_id.locals->num_variables = 0;
- slang_operation_destruct (&op_id);
-
- if (!result)
- return 0;
- if (!slang_assembly_file_push (A->file, slang_asm_exit))
- return 0;
-
- /* execute the expression */
- if (!_slang_execute2 (A->file, &mach))
- return 0;
-
- /* restore the old assembly */
- if (!slang_assembly_file_restore_point_load (A->file, &point))
- return 0;
-
- /* now we copy the contents of the initialized variable back to the original machine */
- _mesa_memcpy ((GLubyte *) A->mach->mem + var->address, (GLubyte *) mach.mem + var->address,
- var->size);
-
- return 1;
+} + +static GLboolean initialize_global (slang_assemble_ctx *A, slang_variable *var) +{ + slang_assembly_file_restore_point point; + slang_machine mach; + slang_assembly_local_info save_local = A->local; + slang_operation op_id, op_assign; + GLboolean result; + + /* save the current assembly */ + if (!slang_assembly_file_restore_point_save (A->file, &point)) + return GL_FALSE; + + /* setup the machine */ + mach = *A->mach; + mach.ip = A->file->count; + + /* allocate local storage for expression */ + A->local.ret_size = 0; + A->local.addr_tmp = 0; + A->local.swizzle_tmp = 4; + if (!slang_assembly_file_push_label (A->file, slang_asm_local_alloc, 20)) + return GL_FALSE; + if (!slang_assembly_file_push_label (A->file, slang_asm_enter, 20)) + return GL_FALSE; + + /* construct the left side of assignment */ + if (!slang_operation_construct (&op_id)) + return GL_FALSE; + op_id.type = slang_oper_identifier; + op_id.a_id = var->a_name; + + /* put the variable into operation's scope */ + op_id.locals->variables = (slang_variable *) slang_alloc_malloc (sizeof (slang_variable)); + if (op_id.locals->variables == NULL) + { + slang_operation_destruct (&op_id); + return GL_FALSE; + } + op_id.locals->num_variables = 1; + op_id.locals->variables[0] = *var; + + /* construct the assignment expression */ + if (!slang_operation_construct (&op_assign)) + { + op_id.locals->num_variables = 0; + slang_operation_destruct (&op_id); + return GL_FALSE; + } + op_assign.type = slang_oper_assign; + op_assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation)); + if (op_assign.children == NULL) + { + slang_operation_destruct (&op_assign); + op_id.locals->num_variables = 0; + slang_operation_destruct (&op_id); + return GL_FALSE; + } + op_assign.num_children = 2; + op_assign.children[0] = op_id; + op_assign.children[1] = *var->initializer; + + /* insert the actual expression */ + result = _slang_assemble_operation_ (A, &op_assign, slang_ref_forbid); + + /* carefully destroy the operations */ + op_assign.num_children = 0; + slang_alloc_free (op_assign.children); + op_assign.children = NULL; + slang_operation_destruct (&op_assign); + op_id.locals->num_variables = 0; + slang_operation_destruct (&op_id); + + if (!result) + return GL_FALSE; + if (!slang_assembly_file_push (A->file, slang_asm_exit)) + return GL_FALSE; + + /* execute the expression */ + if (!_slang_execute2 (A->file, &mach)) + return GL_FALSE; + + /* restore the old assembly */ + if (!slang_assembly_file_restore_point_load (A->file, &point)) + return GL_FALSE; + A->local = save_local; + + /* now we copy the contents of the initialized variable back to the original machine */ + _mesa_memcpy ((GLubyte *) A->mach->mem + var->address, (GLubyte *) mach.mem + var->address, + var->size); + + return GL_TRUE; } /* init declarator list */ @@ -1594,15 +1593,15 @@ static int initialize_global (slang_assemble_ctx *A, slang_variable *var) #define VARIABLE_ARRAY_EXPLICIT 3 #define VARIABLE_ARRAY_UNKNOWN 4 -static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
+static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, const slang_fully_specified_type *type) { - slang_variable *var;
-
- /* empty init declatator (without name, e.g. "float ;") */
+ slang_variable *var; + + /* empty init declatator (without name, e.g. "float ;") */ if (*C->I++ == VARIABLE_NONE) - return 1;
-
+ return 1; + /* make room for the new variable and initialize it */ O->vars->variables = (slang_variable *) slang_alloc_realloc (O->vars->variables, O->vars->num_variables * sizeof (slang_variable), @@ -1613,25 +1612,25 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, return 0; } var = &O->vars->variables[O->vars->num_variables]; - if (!slang_variable_construct (var))
- return 0;
- O->vars->num_variables++;
-
- /* copy the declarator qualifier type, parse the identifier */
+ if (!slang_variable_construct (var)) + return 0; + O->vars->num_variables++; + + /* copy the declarator qualifier type, parse the identifier */ var->global = C->global_scope; var->type.qualifier = type->qualifier; var->a_name = parse_identifier (C); - if (var->a_name == SLANG_ATOM_NULL)
- return 0;
+ if (var->a_name == SLANG_ATOM_NULL) + return 0; switch (*C->I++) { - case VARIABLE_NONE:
+ case VARIABLE_NONE: /* simple variable declarator - just copy the specifier */ if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier)) return 0; break; - case VARIABLE_INITIALIZER:
+ case VARIABLE_INITIALIZER: /* initialized variable - copy the specifier and parse the expression */ if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier)) return 0; @@ -1679,12 +1678,12 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, slang_info_log_memory (C->L); return 0; } - if (!slang_type_specifier_construct (var->type.specifier._array))
- {
- slang_alloc_free (var->type.specifier._array);
- var->type.specifier._array = NULL;
- slang_info_log_memory (C->L);
- return 0;
+ if (!slang_type_specifier_construct (var->type.specifier._array)) + { + slang_alloc_free (var->type.specifier._array); + var->type.specifier._array = NULL; + slang_info_log_memory (C->L); + return 0; } if (!slang_type_specifier_copy (var->type.specifier._array, &type->specifier)) return 0; @@ -1706,39 +1705,39 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, break; default: return 0; - }
-
+ } + /* allocate global address space for a variable with a known size */ if (C->global_scope && !(var->type.specifier.type == slang_spec_array && var->array_size == NULL)) { slang_storage_aggregate agg; - if (!slang_storage_aggregate_construct (&agg))
+ if (!slang_storage_aggregate_construct (&agg)) return 0; if (!_slang_aggregate_variable (&agg, &var->type.specifier, var->array_size, O->funs, O->structs, O->vars, O->machine, O->assembly, C->atoms)) { slang_storage_aggregate_destruct (&agg); return 0; - }
- var->size = _slang_sizeof_aggregate (&agg);
- slang_storage_aggregate_destruct (&agg);
+ } + var->size = _slang_sizeof_aggregate (&agg); + slang_storage_aggregate_destruct (&agg); var->address = slang_var_pool_alloc (O->global_pool, var->size); - }
-
- /* initialize global variable */
- if (C->global_scope && var->initializer != NULL)
- {
- slang_assemble_ctx A;
-
- A.file = O->assembly;
- A.mach = O->machine;
- A.atoms = C->atoms;
- A.space.funcs = O->funs;
- A.space.structs = O->structs;
- A.space.vars = O->vars;
- if (!initialize_global (&A, var))
- return 0;
+ } + + /* initialize global variable */ + if (C->global_scope && var->initializer != NULL) + { + slang_assemble_ctx A; + + A.file = O->assembly; + A.mach = O->machine; + A.atoms = C->atoms; + A.space.funcs = O->funs; + A.space.structs = O->structs; + A.space.vars = O->vars; + if (!initialize_global (&A, var)) + return 0; } return 1; } @@ -1746,16 +1745,16 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, static int parse_init_declarator_list (slang_parse_ctx *C, slang_output_ctx *O) { slang_fully_specified_type type; -
+ /* parse the fully specified type, common to all declarators */ - if (!slang_fully_specified_type_construct (&type))
+ if (!slang_fully_specified_type_construct (&type)) return 0; if (!parse_fully_specified_type (C, O, &type)) { slang_fully_specified_type_destruct (&type); return 0; - }
-
+ } + /* parse declarators, pass-in the parsed type */ do { @@ -1765,19 +1764,19 @@ static int parse_init_declarator_list (slang_parse_ctx *C, slang_output_ctx *O) return 0; } } - while (*C->I++ == DECLARATOR_NEXT);
+ while (*C->I++ == DECLARATOR_NEXT); slang_fully_specified_type_destruct (&type); return 1; } -static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definition,
+static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definition, slang_function **parsed_func_ret) { slang_function parsed_func, *found_func; /* parse function definition/declaration */ - if (!slang_function_construct (&parsed_func))
+ if (!slang_function_construct (&parsed_func)) return 0; if (definition) { @@ -1803,7 +1802,7 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti { /* add the parsed function to the function list */ O->funs->functions = (slang_function *) slang_alloc_realloc (O->funs->functions, - O->funs->num_functions * sizeof (slang_function),
+ O->funs->num_functions * sizeof (slang_function), (O->funs->num_functions + 1) * sizeof (slang_function)); if (O->funs->functions == NULL) { @@ -1821,18 +1820,18 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti { /* TODO: check function return type qualifiers and specifiers */ if (definition) - {
+ { if (found_func->body != NULL) { slang_info_log_error (C->L, "%s: function already has a body", slang_atom_pool_id (C->atoms, parsed_func.header.a_name)); slang_function_destruct (&parsed_func); return 0; - }
-
- /* destroy the existing function declaration and replace it with the new one,
- * remember to save the fixup table */
- parsed_func.fixups = found_func->fixups;
+ } + + /* destroy the existing function declaration and replace it with the new one, + * remember to save the fixup table */ + parsed_func.fixups = found_func->fixups; slang_fixup_table_init (&found_func->fixups); slang_function_destruct (found_func); *found_func = parsed_func; @@ -1850,15 +1849,15 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti /* assemble the parsed function */ { slang_assemble_ctx A; -
- A.file = O->assembly;
- A.mach = O->machine;
- A.atoms = C->atoms;
+ + A.file = O->assembly; + A.mach = O->machine; + A.atoms = C->atoms; A.space.funcs = O->funs; A.space.structs = O->structs; - A.space.vars = O->vars;
- if (!_slang_assemble_function (&A, *parsed_func_ret))
- return 0;
+ A.space.vars = O->vars; + if (!_slang_assemble_function (&A, *parsed_func_ret)) + return 0; } return 1; } @@ -1875,12 +1874,12 @@ static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O) if (!parse_init_declarator_list (C, O)) return 0; break; - case DECLARATION_FUNCTION_PROTOTYPE:
- {
- slang_function *dummy_func;
+ case DECLARATION_FUNCTION_PROTOTYPE: + { + slang_function *dummy_func; if (!parse_function (C, O, 0, &dummy_func)) - return 0;
+ return 0; } break; default: @@ -1895,28 +1894,28 @@ static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O) #define EXTERNAL_DECLARATION 2 static int parse_translation_unit (slang_parse_ctx *C, slang_translation_unit *unit) -{
- slang_output_ctx o;
-
- /* setup output context */
- o.funs = &unit->functions;
- o.structs = &unit->structs;
- o.vars = &unit->globals;
- o.assembly = unit->assembly;
- o.global_pool = unit->global_pool;
- o.machine = unit->machine;
-
+{ + slang_output_ctx o; + + /* setup output context */ + o.funs = &unit->functions; + o.structs = &unit->structs; + o.vars = &unit->globals; + o.assembly = unit->assembly; + o.global_pool = unit->global_pool; + o.machine = unit->machine; + /* parse individual functions and declarations */ while (*C->I != EXTERNAL_NULL) { switch (*C->I++) { - case EXTERNAL_FUNCTION_DEFINITION:
- {
- slang_function *func;
+ case EXTERNAL_FUNCTION_DEFINITION: + { + slang_function *func; if (!parse_function (C, &o, 1, &func)) - return 0;
+ return 0; } break; case EXTERNAL_DECLARATION: @@ -1929,39 +1928,39 @@ static int parse_translation_unit (slang_parse_ctx *C, slang_translation_unit *u } C->I++; return 1; -}
-
-#define BUILTIN_CORE 0
-#define BUILTIN_COMMON 1
-#define BUILTIN_TARGET 2
+} + +#define BUILTIN_CORE 0 +#define BUILTIN_COMMON 1 +#define BUILTIN_TARGET 2 #define BUILTIN_TOTAL 3 static int compile_binary (const byte *prod, slang_translation_unit *unit, slang_unit_type type, - slang_info_log *log, slang_translation_unit *builtins, slang_assembly_file *file,
- slang_var_pool *pool, slang_machine *mach, slang_translation_unit *downlink,
+ slang_info_log *log, slang_translation_unit *builtins, slang_assembly_file *file, + slang_var_pool *pool, slang_machine *mach, slang_translation_unit *downlink, slang_atom_pool *atoms) { - slang_parse_ctx C;
-
- /* create translation unit object */
- if (file != NULL)
- {
- if (!slang_translation_unit_construct2 (unit, file, pool, mach, atoms))
- return 0;
- unit->type = type;
+ slang_parse_ctx C; + + /* create translation unit object */ + if (file != NULL) + { + if (!slang_translation_unit_construct2 (unit, file, pool, mach, atoms)) + return 0; + unit->type = type; } /* set-up parse context */ C.I = prod; C.L = log; - C.parsing_builtin = builtins == NULL;
- C.global_scope = 1;
- C.atoms = unit->atom_pool;
+ C.parsing_builtin = builtins == NULL; + C.global_scope = 1; + C.atoms = unit->atom_pool; if (!check_revision (&C)) - {
- slang_translation_unit_destruct (unit);
- return 0;
+ { + slang_translation_unit_destruct (unit); + return 0; } if (downlink != NULL) @@ -2000,9 +1999,9 @@ static int compile_with_grammar (grammar id, const char *source, slang_translati slang_info_log_error (log, buf); return 0; } -
+ /* syntax is okay - translate it to internal representation */ - if (!compile_binary (prod, unit, type, log, builtins, NULL, NULL, NULL,
+ if (!compile_binary (prod, unit, type, log, builtins, NULL, NULL, NULL, &builtins[BUILTIN_TARGET], NULL)) { grammar_alloc_free (prod); @@ -2031,109 +2030,109 @@ static const byte slang_fragment_builtin_gc[] = { static const byte slang_vertex_builtin_gc[] = { #include "library/slang_vertex_builtin_gc.h" -};
-
-static int compile (grammar *id, slang_translation_unit *builtin_units, int *compiled,
- const char *source, slang_translation_unit *unit, slang_unit_type type, slang_info_log *log)
-{
- slang_translation_unit *builtins = NULL;
-
- /* load slang grammar */
- *id = grammar_load_from_text ((const byte *) (slang_shader_syn));
- if (*id == 0)
- {
- byte buf[1024];
- int pos;
-
- grammar_get_last_error (buf, 1024, &pos);
- slang_info_log_error (log, (const char *) (buf));
- return 0;
- }
-
- /* set shader type - the syntax is slightly different for different shaders */
- if (type == slang_unit_fragment_shader || type == slang_unit_fragment_builtin)
- grammar_set_reg8 (*id, (const byte *) "shader_type", 1);
- else
- grammar_set_reg8 (*id, (const byte *) "shader_type", 2);
-
- /* enable language extensions */
- grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 1);
-
- /* if parsing user-specified shader, load built-in library */
- if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader)
- {
- /* compile core functionality first */
- if (!compile_binary (slang_core_gc, &builtin_units[BUILTIN_CORE],
- slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,
- unit->machine, NULL, unit->atom_pool))
- return 0;
- compiled[BUILTIN_CORE] = 1;
-
- /* compile common functions and variables, link to core */
- if (!compile_binary (slang_common_builtin_gc, &builtin_units[BUILTIN_COMMON],
- slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,
- unit->machine, &builtin_units[BUILTIN_CORE], unit->atom_pool))
- return 0;
- compiled[BUILTIN_COMMON] = 1;
-
- /* compile target-specific functions and variables, link to common */
- if (type == slang_unit_fragment_shader)
- {
- if (!compile_binary (slang_fragment_builtin_gc, &builtin_units[BUILTIN_TARGET],
- slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,
- unit->machine, &builtin_units[BUILTIN_COMMON], unit->atom_pool))
- return 0;
- }
- else if (type == slang_unit_vertex_shader)
- {
- if (!compile_binary (slang_vertex_builtin_gc, &builtin_units[BUILTIN_TARGET],
- slang_unit_vertex_builtin, log, NULL, unit->assembly, unit->global_pool,
- unit->machine, &builtin_units[BUILTIN_COMMON], unit->atom_pool))
- return 0;
- }
- compiled[BUILTIN_TARGET] = 1;
-
- /* disable language extensions */
- grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 0);
- builtins = builtin_units;
- }
-
- /* compile the actual shader - pass-in built-in library for external shader */
- if (!compile_with_grammar (*id, source, unit, type, log, builtins))
- return 0;
-
- return 1;
+}; + +static int compile (grammar *id, slang_translation_unit *builtin_units, int *compiled, + const char *source, slang_translation_unit *unit, slang_unit_type type, slang_info_log *log) +{ + slang_translation_unit *builtins = NULL; + + /* load slang grammar */ + *id = grammar_load_from_text ((const byte *) (slang_shader_syn)); + if (*id == 0) + { + byte buf[1024]; + int pos; + + grammar_get_last_error (buf, 1024, &pos); + slang_info_log_error (log, (const char *) (buf)); + return 0; + } + + /* set shader type - the syntax is slightly different for different shaders */ + if (type == slang_unit_fragment_shader || type == slang_unit_fragment_builtin) + grammar_set_reg8 (*id, (const byte *) "shader_type", 1); + else + grammar_set_reg8 (*id, (const byte *) "shader_type", 2); + + /* enable language extensions */ + grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 1); + + /* if parsing user-specified shader, load built-in library */ + if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) + { + /* compile core functionality first */ + if (!compile_binary (slang_core_gc, &builtin_units[BUILTIN_CORE], + slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool, + unit->machine, NULL, unit->atom_pool)) + return 0; + compiled[BUILTIN_CORE] = 1; + + /* compile common functions and variables, link to core */ + if (!compile_binary (slang_common_builtin_gc, &builtin_units[BUILTIN_COMMON], + slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool, + unit->machine, &builtin_units[BUILTIN_CORE], unit->atom_pool)) + return 0; + compiled[BUILTIN_COMMON] = 1; + + /* compile target-specific functions and variables, link to common */ + if (type == slang_unit_fragment_shader) + { + if (!compile_binary (slang_fragment_builtin_gc, &builtin_units[BUILTIN_TARGET], + slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool, + unit->machine, &builtin_units[BUILTIN_COMMON], unit->atom_pool)) + return 0; + } + else if (type == slang_unit_vertex_shader) + { + if (!compile_binary (slang_vertex_builtin_gc, &builtin_units[BUILTIN_TARGET], + slang_unit_vertex_builtin, log, NULL, unit->assembly, unit->global_pool, + unit->machine, &builtin_units[BUILTIN_COMMON], unit->atom_pool)) + return 0; + } + compiled[BUILTIN_TARGET] = 1; + + /* disable language extensions */ + grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 0); + builtins = builtin_units; + } + + /* compile the actual shader - pass-in built-in library for external shader */ + if (!compile_with_grammar (*id, source, unit, type, log, builtins)) + return 0; + + return 1; } -
+ int _slang_compile (const char *source, slang_translation_unit *unit, slang_unit_type type, slang_info_log *log) -{
+{ int success; grammar id = 0; -// slang_translation_unit builtin_units[BUILTIN_TOTAL];
- slang_translation_unit *builtin_units;
- int compiled[BUILTIN_TOTAL] = { 0 };
-
- /* create the main unit first */
- if (!slang_translation_unit_construct (unit))
- return 0;
+/* slang_translation_unit builtin_units[BUILTIN_TOTAL];*/ + slang_translation_unit *builtin_units; + int compiled[BUILTIN_TOTAL] = { 0 }; + + /* create the main unit first */ + if (!slang_translation_unit_construct (unit)) + return 0; unit->type = type; -
+ builtin_units = (slang_translation_unit *) slang_alloc_malloc (BUILTIN_TOTAL * sizeof (slang_translation_unit)); success = compile (&id, builtin_units, compiled, source, unit, type, log); - /* destroy built-in library */
+ /* destroy built-in library */ /* XXX: free with the unit */ /*if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) - {
- int i;
-
- for (i = 0; i < BUILTIN_TOTAL; i++)
+ { + int i; + + for (i = 0; i < BUILTIN_TOTAL; i++) if (compiled[i] != 0) slang_translation_unit_destruct (&builtin_units[i]); - }*/
+ }*/ if (id != 0) - grammar_destroy (id);
+ grammar_destroy (id); return success; } |