[PATCH 6/6] d3dcompiler: Parse initializer lists using a variable-size array.

Zebediah Figura zfigura at codeweavers.com
Fri Aug 9 09:52:49 CDT 2019


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/d3dcompiler_43/d3dcompiler_private.h |   8 +-
 dlls/d3dcompiler_43/hlsl.y                | 117 +++++++++++-----------
 2 files changed, 67 insertions(+), 58 deletions(-)

diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index d6db46b4536..b576c2401b6 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -980,6 +980,12 @@ struct parse_colon_attribute
     struct reg_reservation *reg_reservation;
 };
 
+struct parse_initializer
+{
+    struct hlsl_ir_node **args;
+    unsigned int args_count;
+};
+
 struct parse_variable_def
 {
     struct list entry;
@@ -989,7 +995,7 @@ struct parse_variable_def
     unsigned int array_size;
     const char *semantic;
     struct reg_reservation *reg_reservation;
-    struct list *initializer;
+    struct parse_initializer initializer;
 };
 
 struct parse_function
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index c18efcc1350..1dedbcb8a24 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -378,14 +378,13 @@ oom:
     return NULL;
 }
 
-static unsigned int initializer_size(struct list *initializer)
+static unsigned int initializer_size(const struct parse_initializer *initializer)
 {
-    unsigned int count = 0;
-    struct hlsl_ir_node *node;
+    unsigned int count = 0, i;
 
-    LIST_FOR_EACH_ENTRY(node, initializer, struct hlsl_ir_node, entry)
+    for (i = 0; i < initializer->args_count; ++i)
     {
-        count += components_count_type(node->data_type);
+        count += components_count_type(initializer->args[i]->data_type);
     }
     TRACE("Initializer size = %u.\n", count);
     return count;
@@ -488,28 +487,29 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha
     return NULL;
 }
 
-static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var, struct list *initializer)
+static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var,
+        struct parse_initializer *initializer)
 {
     struct hlsl_type *type = var->node.data_type;
-    struct hlsl_ir_node *node;
     struct hlsl_struct_field *field;
-    struct list *cur_node;
     struct hlsl_ir_node *assignment;
     struct hlsl_ir_deref *deref;
+    unsigned int i = 0;
 
     if (initializer_size(initializer) != components_count_type(type))
     {
         hlsl_report_message(var->node.loc.file, var->node.loc.line, var->node.loc.col, HLSL_LEVEL_ERROR,
                 "structure initializer mismatch");
-        free_instr_list(initializer);
+        for (i = 0; i < initializer->args_count; ++i)
+            free_instr(initializer->args[i]);
         return;
     }
-    cur_node = list_head(initializer);
-    assert(cur_node);
-    node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
+
     LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
     {
-        if (!cur_node)
+        struct hlsl_ir_node *node = initializer->args[i];
+
+        if (i++ >= initializer->args_count)
         {
             d3dcompiler_free(initializer);
             return;
@@ -528,19 +528,12 @@ static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var, s
         }
         else
             FIXME("Initializing with \"mismatched\" fields is not supported yet.\n");
-        cur_node = list_next(initializer, cur_node);
-        node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
     }
 
     /* Free initializer elements in excess. */
-    while (cur_node)
-    {
-        struct list *next = list_next(initializer, cur_node);
-        free_instr(node);
-        cur_node = next;
-        node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
-    }
-    d3dcompiler_free(initializer);
+    for (; i < initializer->args_count; ++i)
+        free_instr(initializer->args[i]);
+    d3dcompiler_free(initializer->args);
 }
 
 static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list)
@@ -593,7 +586,7 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
             local = FALSE;
         }
 
-        if (var->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer)
+        if (var->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer.args_count)
         {
             hlsl_report_message(v->loc.file, v->loc.line, v->loc.col,
                     HLSL_LEVEL_ERROR, "const variable without initializer");
@@ -611,10 +604,9 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
         }
         TRACE("Declared variable %s.\n", var->name);
 
-        if (v->initializer)
+        if (v->initializer.args_count)
         {
-            unsigned int size = initializer_size(v->initializer);
-            struct hlsl_ir_node *node;
+            unsigned int size = initializer_size(&v->initializer), i;
 
             TRACE("Variable with initializer.\n");
             if (type->type <= HLSL_CLASS_LAST_NUMERIC
@@ -624,7 +616,9 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
                 {
                     hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
                             "'%s' initializer does not match", v->name);
-                    free_instr_list(v->initializer);
+                    for (i = 0; i < v->initializer.args_count; ++i)
+                        free_instr(v->initializer.args[i]);
+                    d3dcompiler_free(v->initializer.args);
                     d3dcompiler_free(v);
                     continue;
                 }
@@ -634,43 +628,51 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
             {
                 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
                         "'%s' initializer does not match", v->name);
-                free_instr_list(v->initializer);
+                for (i = 0; i < v->initializer.args_count; ++i)
+                    free_instr(v->initializer.args[i]);
+                d3dcompiler_free(v->initializer.args);
                 d3dcompiler_free(v);
                 continue;
             }
 
             if (type->type == HLSL_CLASS_STRUCT)
             {
-                struct_var_initializer(statements_list, var, v->initializer);
+                struct_var_initializer(statements_list, var, &v->initializer);
                 d3dcompiler_free(v);
                 continue;
             }
             if (type->type > HLSL_CLASS_LAST_NUMERIC)
             {
                 FIXME("Initializers for non scalar/struct variables not supported yet.\n");
-                free_instr_list(v->initializer);
+                for (i = 0; i < v->initializer.args_count; ++i)
+                    free_instr(v->initializer.args[i]);
+                d3dcompiler_free(v->initializer.args);
                 d3dcompiler_free(v);
                 continue;
             }
             if (v->array_size > 0)
             {
                 FIXME("Initializing arrays is not supported yet.\n");
-                free_instr_list(v->initializer);
+                for (i = 0; i < v->initializer.args_count; ++i)
+                    free_instr(v->initializer.args[i]);
+                d3dcompiler_free(v->initializer.args);
                 d3dcompiler_free(v);
                 continue;
             }
-            if (list_count(v->initializer) > 1)
+            if (v->initializer.args_count > 1)
             {
                 FIXME("Complex initializers are not supported yet.\n");
-                free_instr_list(v->initializer);
+                for (i = 0; i < v->initializer.args_count; ++i)
+                    free_instr(v->initializer.args[i]);
+                d3dcompiler_free(v->initializer.args);
                 d3dcompiler_free(v);
                 continue;
             }
-            node = LIST_ENTRY(list_head(v->initializer), struct hlsl_ir_node, entry);
+
             assignment = make_assignment(&var->node, ASSIGN_OP_ASSIGN,
-                    BWRITERSP_WRITEMASK_ALL, node);
+                    BWRITERSP_WRITEMASK_ALL, v->initializer.args[0]);
+            d3dcompiler_free(v->initializer.args);
             list_add_tail(statements_list, &assignment->entry);
-            d3dcompiler_free(v->initializer);
         }
         d3dcompiler_free(v);
     }
@@ -696,6 +698,7 @@ static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, s
     struct parse_variable_def *v, *v_next;
     struct hlsl_struct_field *field;
     struct list *list;
+    unsigned int i;
 
     list = d3dcompiler_alloc(sizeof(*list));
     if (!list)
@@ -718,11 +721,13 @@ static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, s
         field->name = v->name;
         field->modifiers = modifiers;
         field->semantic = v->semantic;
-        if (v->initializer)
+        if (v->initializer.args_count)
         {
             hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
                     "struct field with an initializer.\n");
-            free_instr_list(v->initializer);
+            for (i = 0; i < v->initializer.args_count; ++i)
+                free_instr(v->initializer.args[i]);
+            d3dcompiler_free(v->initializer.args);
         }
         list_add_tail(list, &field->entry);
         d3dcompiler_free(v);
@@ -905,6 +910,7 @@ static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tr
     struct list *list;
     struct parse_function function;
     struct parse_parameter parameter;
+    struct parse_initializer initializer;
     struct parse_variable_def *variable_def;
     struct parse_if_body if_body;
     enum parse_unary_op unary_op;
@@ -1028,8 +1034,8 @@ static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tr
 %type <type> unnamed_struct_spec
 %type <list> type_specs
 %type <variable_def> type_spec
-%type <list> complex_initializer
-%type <list> initializer_expr_list
+%type <initializer> complex_initializer
+%type <initializer> initializer_expr_list
 %type <instr> initializer_expr
 %type <modifiers> var_modifiers
 %type <list> field
@@ -1675,9 +1681,9 @@ var_modifiers:            /* Empty */
 
 complex_initializer:      initializer_expr
                             {
-                                $$ = d3dcompiler_alloc(sizeof(*$$));
-                                list_init($$);
-                                list_add_head($$, &$1->entry);
+                                $$.args_count = 1;
+                                $$.args = d3dcompiler_alloc(sizeof(*$$.args));
+                                $$.args[0] = $1;
                             }
                         | '{' initializer_expr_list '}'
                             {
@@ -1695,14 +1701,15 @@ initializer_expr:         assignment_expr
 
 initializer_expr_list:    initializer_expr
                             {
-                                $$ = d3dcompiler_alloc(sizeof(*$$));
-                                list_init($$);
-                                list_add_head($$, &$1->entry);
+                                $$.args_count = 1;
+                                $$.args = d3dcompiler_alloc(sizeof(*$$.args));
+                                $$.args[0] = $1;
                             }
                         | initializer_expr_list ',' initializer_expr
                             {
                                 $$ = $1;
-                                list_add_tail($$, &$3->entry);
+                                $$.args = d3dcompiler_realloc($$.args, ($$.args_count + 1) * sizeof(*$$.args));
+                                $$.args[$$.args_count++] = $3;
                             }
 
 boolean:                  KW_TRUE
@@ -2080,7 +2087,6 @@ postfix_expr:             primary_expr
                         | var_modifiers type '(' initializer_expr_list ')'
                             {
                                 struct hlsl_ir_constructor *constructor;
-                                struct hlsl_ir_node *instr;
 
                                 TRACE("%s constructor.\n", debug_hlsl_type($2));
                                 if ($1)
@@ -2097,25 +2103,22 @@ postfix_expr:             primary_expr
                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
                                     return -1;
                                 }
-                                if ($2->dimx * $2->dimy != initializer_size($4))
+                                if ($2->dimx * $2->dimy != initializer_size(&$4))
                                 {
                                     hlsl_message("Line %u: wrong number of components in constructor.\n",
                                             hlsl_ctx.line_no);
                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
                                     return -1;
                                 }
+                                assert($4.args_count <= ARRAY_SIZE(constructor->args));
 
                                 constructor = d3dcompiler_alloc(sizeof(*constructor));
                                 constructor->node.type = HLSL_IR_CONSTRUCTOR;
                                 set_location(&constructor->node.loc, &@3);
                                 constructor->node.data_type = $2;
-                                constructor->args_count = 0;
-                                LIST_FOR_EACH_ENTRY(instr, $4, struct hlsl_ir_node, entry)
-                                {
-                                    constructor->args[constructor->args_count++] = instr;
-                                }
-                                d3dcompiler_free($4);
-
+                                constructor->args_count = $4.args_count;
+                                memcpy(constructor->args, $4.args, $4.args_count * sizeof(*$4.args));
+                                d3dcompiler_free($4.args);
                                 $$ = &constructor->node;
                             }
 
-- 
2.20.1




More information about the wine-devel mailing list