slang: Check return value from new_instruction().
[mesa.git] / src / mesa / shader / slang / slang_label.c
1
2
3 /**
4 * Functions for managing instruction labels.
5 * Basically, this is used to manage the problem of forward branches where
6 * we have a branch instruciton but don't know the target address yet.
7 */
8
9
10 #include "slang_label.h"
11 #include "slang_mem.h"
12
13
14
15 slang_label *
16 _slang_label_new(const char *name)
17 {
18 slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
19 if (l) {
20 l->Name = _slang_strdup(name);
21 l->Location = -1;
22 }
23 return l;
24 }
25
26 /**
27 * As above, but suffix the name with a unique number.
28 */
29 slang_label *
30 _slang_label_new_unique(const char *name)
31 {
32 static int id = 1;
33 slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
34 if (l) {
35 l->Name = (char *) _slang_alloc(_mesa_strlen(name) + 10);
36 if (!l->Name) {
37 _mesa_free(l);
38 return NULL;
39 }
40 _mesa_sprintf(l->Name, "%s_%d", name, id);
41 id++;
42 l->Location = -1;
43 }
44 return l;
45 }
46
47 void
48 _slang_label_delete(slang_label *l)
49 {
50 if (l->Name) {
51 _slang_free(l->Name);
52 l->Name = NULL;
53 }
54 if (l->References) {
55 _slang_free(l->References);
56 l->References = NULL;
57 }
58 _slang_free(l);
59 }
60
61
62 void
63 _slang_label_add_reference(slang_label *l, GLuint inst)
64 {
65 const GLuint oldSize = l->NumReferences * sizeof(GLuint);
66 assert(l->Location < 0);
67 l->References = _slang_realloc(l->References,
68 oldSize, oldSize + sizeof(GLuint));
69 if (l->References) {
70 l->References[l->NumReferences] = inst;
71 l->NumReferences++;
72 }
73 }
74
75
76 GLint
77 _slang_label_get_location(const slang_label *l)
78 {
79 return l->Location;
80 }
81
82
83 void
84 _slang_label_set_location(slang_label *l, GLint location,
85 struct gl_program *prog)
86 {
87 GLuint i;
88
89 assert(l->Location < 0);
90 assert(location >= 0);
91
92 l->Location = location;
93
94 /* for the instructions that were waiting to learn the label's location: */
95 for (i = 0; i < l->NumReferences; i++) {
96 const GLuint j = l->References[i];
97 prog->Instructions[j].BranchTarget = location;
98 }
99
100 if (l->References) {
101 _slang_free(l->References);
102 l->References = NULL;
103 }
104 }