[PATCH vkd3d 1/6] vkd3d-shader: Return a vkd3d_string_buffer from hlsl_type_to_string().

Zebediah Figura zfigura at codeweavers.com
Tue Feb 23 15:56:56 CST 2021


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 libs/vkd3d-shader/hlsl.c                 | 62 +++++++++++++-----------
 libs/vkd3d-shader/hlsl.h                 |  4 +-
 libs/vkd3d-shader/hlsl.y                 | 20 +++++---
 libs/vkd3d-shader/vkd3d_shader_main.c    | 54 +++++++++++++++++++++
 libs/vkd3d-shader/vkd3d_shader_private.h | 11 +++++
 5 files changed, 114 insertions(+), 37 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index 52b3dd10..78eacf28 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -648,10 +648,10 @@ static int compare_function_decl_rb(const void *key, const struct rb_entry *entr
     return 0;
 }
 
-char *hlsl_type_to_string(const struct hlsl_type *type)
+struct vkd3d_string_buffer *hlsl_type_to_string(struct vkd3d_string_buffer_list *string_buffers,
+        const struct hlsl_type *type)
 {
-    const char *name;
-    char *string;
+    struct vkd3d_string_buffer *string;
 
     static const char base_types[HLSL_TYPE_LAST_SCALAR + 1][7] =
     {
@@ -663,66 +663,70 @@ char *hlsl_type_to_string(const struct hlsl_type *type)
         "bool",
     };
 
+    if (!(string = vkd3d_string_buffer_get(string_buffers)))
+        return NULL;
+
     if (type->name)
-        return vkd3d_strdup(type->name);
+    {
+        vkd3d_string_buffer_printf(string, "%s", type->name);
+        return string;
+    }
 
     switch (type->type)
     {
         case HLSL_CLASS_SCALAR:
-            return vkd3d_strdup(base_types[type->base_type]);
+            vkd3d_string_buffer_printf(string, "%s", base_types[type->base_type]);
+            return string;
 
         case HLSL_CLASS_VECTOR:
-            name = base_types[type->base_type];
-            if ((string = malloc(strlen(name) + 2)))
-                sprintf(string, "%s%u", name, type->dimx);
+            vkd3d_string_buffer_printf(string, "%s%u", base_types[type->base_type], type->dimx);
             return string;
 
         case HLSL_CLASS_MATRIX:
-            name = base_types[type->base_type];
-            if ((string = malloc(strlen(name) + 4)))
-                sprintf(string, "%s%ux%u", name, type->dimx, type->dimy);
+            vkd3d_string_buffer_printf(string, "%s%ux%u", base_types[type->base_type], type->dimx, type->dimy);
             return string;
 
         case HLSL_CLASS_ARRAY:
         {
+            struct vkd3d_string_buffer *inner_string;
             const struct hlsl_type *t;
-            char *inner_string;
-            size_t len = 1;
 
             for (t = type; t->type == HLSL_CLASS_ARRAY; t = t->e.array.type)
-                len += 14;
-            if (!(inner_string = hlsl_type_to_string(t)))
-                return NULL;
-            len += strlen(inner_string);
+                ;
 
-            if ((string = malloc(len)))
+            if ((inner_string = hlsl_type_to_string(string_buffers, t)))
             {
-                strcpy(string, inner_string);
-                for (t = type; t->type == HLSL_CLASS_ARRAY; t = t->e.array.type)
-                    sprintf(string + strlen(string), "[%u]", t->e.array.elements_count);
+                vkd3d_string_buffer_printf(string, "%s", inner_string->buffer);
+                vkd3d_string_buffer_release(string_buffers, inner_string);
             }
 
-            vkd3d_free(inner_string);
+            for (t = type; t->type == HLSL_CLASS_ARRAY; t = t->e.array.type)
+                vkd3d_string_buffer_printf(string, "[%u]", t->e.array.elements_count);
             return string;
         }
 
         case HLSL_CLASS_STRUCT:
-            return vkd3d_strdup("<anonymous struct>");
+            vkd3d_string_buffer_printf(string, "<anonymous struct>");
+            return string;
 
         default:
-            return vkd3d_strdup("<unexpected type>");
+            vkd3d_string_buffer_printf(string, "<unexpected type>");
+            return string;
     }
 }
 
 const char *debug_hlsl_type(const struct hlsl_type *type)
 {
+    struct vkd3d_string_buffer_list string_buffers;
+    struct vkd3d_string_buffer *string;
     const char *ret;
-    char *string;
 
-    if (!(string = hlsl_type_to_string(type)))
+    vkd3d_string_buffer_list_init(&string_buffers);
+    if (!(string = hlsl_type_to_string(&string_buffers, type)))
         return NULL;
-    ret = vkd3d_dbg_sprintf("%s", string);
-    vkd3d_free(string);
+    ret = vkd3d_dbg_sprintf("%s", string->buffer);
+    vkd3d_string_buffer_release(&string_buffers, string);
+    vkd3d_string_buffer_list_cleanup(&string_buffers);
     return ret;
 }
 
@@ -1526,6 +1530,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, struct vkd3d_shader_message_cont
     ctx->source_files_count = 1;
     ctx->location.source_name = ctx->source_files[0];
     ctx->location.line = ctx->location.column = 1;
+    vkd3d_string_buffer_list_init(&ctx->string_buffers);
 
     ctx->matrix_majority = HLSL_COLUMN_MAJOR;
 
@@ -1553,6 +1558,7 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx)
     for (i = 0; i < ctx->source_files_count; ++i)
         vkd3d_free((void *)ctx->source_files[i]);
     vkd3d_free(ctx->source_files);
+    vkd3d_string_buffer_list_cleanup(&ctx->string_buffers);
 
     rb_destroy(&ctx->functions, free_function_rb, NULL);
 
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index a374f54a..62f7d88b 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -390,6 +390,7 @@ struct hlsl_ctx
     unsigned int source_files_count;
     struct vkd3d_shader_location location;
     struct vkd3d_shader_message_context *message_context;
+    struct vkd3d_string_buffer_list string_buffers;
     bool failed;
 
     void *scanner;
@@ -496,7 +497,8 @@ static inline void hlsl_src_remove(struct hlsl_src *src)
 
 const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
 
-char *hlsl_type_to_string(const struct hlsl_type *type) DECLSPEC_HIDDEN;
+struct vkd3d_string_buffer *hlsl_type_to_string(struct vkd3d_string_buffer_list *string_buffers,
+        const struct hlsl_type *type) DECLSPEC_HIDDEN;
 char *hlsl_modifiers_to_string(unsigned int modifiers) DECLSPEC_HIDDEN;
 const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) DECLSPEC_HIDDEN;
 
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index ea640b94..1fb1b7f3 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -255,13 +255,15 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct
 
     if (!implicit_compatible_data_types(src_type, dst_type))
     {
-        char *src_string = hlsl_type_to_string(src_type), *dst_string = hlsl_type_to_string(dst_type);
+        struct vkd3d_string_buffer *src_string, *dst_string;
 
+        src_string = hlsl_type_to_string(&ctx->string_buffers, src_type);
+        dst_string = hlsl_type_to_string(&ctx->string_buffers, dst_type);
         if (src_string && dst_string)
             hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
-                    "Can't implicitly convert from %s to %s.", src_string, dst_string);
-        vkd3d_free(src_string);
-        vkd3d_free(dst_string);
+                    "Can't implicitly convert from %s to %s.", src_string->buffer, dst_string->buffer);
+        vkd3d_string_buffer_release(&ctx->string_buffers, src_string);
+        vkd3d_string_buffer_release(&ctx->string_buffers, dst_string);
         return NULL;
     }
 
@@ -2744,13 +2746,15 @@ unary_expr:
 
             if (!compatible_data_types(src_type, dst_type))
             {
-                char *src_string = hlsl_type_to_string(src_type), *dst_string = hlsl_type_to_string(dst_type);
+                struct vkd3d_string_buffer *src_string, *dst_string;
 
+                src_string = hlsl_type_to_string(&ctx->string_buffers, src_type);
+                dst_string = hlsl_type_to_string(&ctx->string_buffers, dst_type);
                 if (src_string && dst_string)
                     hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Can't cast from %s to %s.",
-                            src_string, dst_string);
-                vkd3d_free(src_string);
-                vkd3d_free(dst_string);
+                            src_string->buffer, dst_string->buffer);
+                vkd3d_string_buffer_release(&ctx->string_buffers, src_string);
+                vkd3d_string_buffer_release(&ctx->string_buffers, dst_string);
                 YYABORT;
             }
 
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index bae2852a..681dd4f2 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -33,6 +33,12 @@ void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer)
     vkd3d_free(buffer->buffer);
 }
 
+static void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer)
+{
+    buffer->buffer[0] = '\0';
+    buffer->content_size = 0;
+}
+
 static bool vkd3d_string_buffer_resize(struct vkd3d_string_buffer *buffer, int rc)
 {
     unsigned int new_buffer_size = buffer->buffer_size * 2;
@@ -107,6 +113,54 @@ void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const
     }
 }
 
+void vkd3d_string_buffer_list_init(struct vkd3d_string_buffer_list *list)
+{
+    list_init(&list->list);
+}
+
+void vkd3d_string_buffer_list_cleanup(struct vkd3d_string_buffer_list *list)
+{
+    struct vkd3d_string_buffer *buffer, *buffer_next;
+
+    LIST_FOR_EACH_ENTRY_SAFE(buffer, buffer_next, &list->list, struct vkd3d_string_buffer, entry)
+    {
+        vkd3d_string_buffer_cleanup(buffer);
+        vkd3d_free(buffer);
+    }
+    list_init(&list->list);
+}
+
+struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_list *list)
+{
+    struct vkd3d_string_buffer *buffer;
+
+    if (list_empty(&list->list))
+    {
+        if (!(buffer = vkd3d_malloc(sizeof(*buffer))))
+            return NULL;
+        vkd3d_string_buffer_init(buffer);
+        if (!vkd3d_string_buffer_resize(buffer, 1))
+        {
+            vkd3d_free(buffer);
+            return NULL;
+        }
+    }
+    else
+    {
+        buffer = LIST_ENTRY(list_head(&list->list), struct vkd3d_string_buffer, entry);
+        list_remove(&buffer->entry);
+    }
+    vkd3d_string_buffer_clear(buffer);
+    return buffer;
+}
+
+void vkd3d_string_buffer_release(struct vkd3d_string_buffer_list *list, struct vkd3d_string_buffer *buffer)
+{
+    if (!buffer)
+        return;
+    list_add_head(&list->list, &buffer->entry);
+}
+
 void vkd3d_shader_message_context_init(struct vkd3d_shader_message_context *context,
         enum vkd3d_shader_log_level log_level)
 {
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index e837dbcd..2ef3d5da 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -865,17 +865,28 @@ bool shader_sm4_is_end(void *data, const DWORD **ptr) DECLSPEC_HIDDEN;
 
 struct vkd3d_string_buffer
 {
+    struct list entry;
     char *buffer;
     unsigned int buffer_size;
     unsigned int content_size;
 };
 
+struct vkd3d_string_buffer_list
+{
+    struct list list;
+};
+
 enum vkd3d_result vkd3d_dxbc_binary_to_text(void *data,
         const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out) DECLSPEC_HIDDEN;
 void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer) DECLSPEC_HIDDEN;
+struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_list *list) DECLSPEC_HIDDEN;
 void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer) DECLSPEC_HIDDEN;
+void vkd3d_string_buffer_list_cleanup(struct vkd3d_string_buffer_list *list) DECLSPEC_HIDDEN;
+void vkd3d_string_buffer_list_init(struct vkd3d_string_buffer_list *list) DECLSPEC_HIDDEN;
 int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer,
         const char *format, ...) VKD3D_PRINTF_FUNC(2, 3) DECLSPEC_HIDDEN;
+void vkd3d_string_buffer_release(struct vkd3d_string_buffer_list *list,
+        struct vkd3d_string_buffer *buffer) DECLSPEC_HIDDEN;
 #define vkd3d_string_buffer_trace(buffer) \
         vkd3d_string_buffer_trace_(buffer, __FUNCTION__)
 void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const char *function) DECLSPEC_HIDDEN;
-- 
2.30.1




More information about the wine-devel mailing list