#define LONGSTRING __extension__ in imports.h and use it to silence gcc
[mesa.git] / src / mesa / shader / slang / slang_compile_function.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file slang_compile_function.c
27 * slang front-end compiler
28 * \author Michal Krol
29 */
30
31 #include "imports.h"
32 #include "slang_compile.h"
33
34 /* slang_fixup_table */
35
36 void slang_fixup_table_init (slang_fixup_table *fix)
37 {
38 fix->table = NULL;
39 fix->count = 0;
40 }
41
42 void slang_fixup_table_free (slang_fixup_table *fix)
43 {
44 slang_alloc_free (fix->table);
45 slang_fixup_table_init (fix);
46 }
47
48 /* slang_function */
49
50 int slang_function_construct (slang_function *func)
51 {
52 func->kind = slang_func_ordinary;
53 if (!slang_variable_construct (&func->header))
54 return 0;
55 func->parameters = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
56 if (func->parameters == NULL)
57 {
58 slang_variable_destruct (&func->header);
59 return 0;
60 }
61 _slang_variable_scope_ctr (func->parameters);
62 func->param_count = 0;
63 func->body = NULL;
64 func->address = ~0;
65 slang_fixup_table_init (&func->fixups);
66 return 1;
67 }
68
69 void slang_function_destruct (slang_function *func)
70 {
71 slang_variable_destruct (&func->header);
72 slang_variable_scope_destruct (func->parameters);
73 slang_alloc_free (func->parameters);
74 if (func->body != NULL)
75 {
76 slang_operation_destruct (func->body);
77 slang_alloc_free (func->body);
78 }
79 slang_fixup_table_free (&func->fixups);
80 }
81
82 /*
83 * slang_function_scope
84 */
85
86 GLvoid
87 _slang_function_scope_ctr (slang_function_scope *self)
88 {
89 self->functions = NULL;
90 self->num_functions = 0;
91 self->outer_scope = NULL;
92 }
93
94 void slang_function_scope_destruct (slang_function_scope *scope)
95 {
96 unsigned int i;
97
98 for (i = 0; i < scope->num_functions; i++)
99 slang_function_destruct (scope->functions + i);
100 slang_alloc_free (scope->functions);
101 }
102
103 int slang_function_scope_find_by_name (slang_function_scope *funcs, slang_atom a_name, int all_scopes)
104 {
105 unsigned int i;
106
107 for (i = 0; i < funcs->num_functions; i++)
108 if (a_name == funcs->functions[i].header.a_name)
109 return 1;
110 if (all_scopes && funcs->outer_scope != NULL)
111 return slang_function_scope_find_by_name (funcs->outer_scope, a_name, 1);
112 return 0;
113 }
114
115 slang_function *slang_function_scope_find (slang_function_scope *funcs, slang_function *fun,
116 int all_scopes)
117 {
118 unsigned int i;
119
120 for (i = 0; i < funcs->num_functions; i++)
121 {
122 slang_function *f = &funcs->functions[i];
123 unsigned int j;
124
125 if (fun->header.a_name != f->header.a_name)
126 continue;
127 if (fun->param_count != f->param_count)
128 continue;
129 for (j = 0; j < fun->param_count; j++)
130 {
131 if (!slang_type_specifier_equal (&fun->parameters->variables[j].type.specifier,
132 &f->parameters->variables[j].type.specifier))
133 break;
134 }
135 if (j == fun->param_count)
136 return f;
137 }
138 if (all_scopes && funcs->outer_scope != NULL)
139 return slang_function_scope_find (funcs->outer_scope, fun, 1);
140 return NULL;
141 }
142
143 /*
144 * _slang_build_export_code_table()
145 */
146
147 GLboolean
148 _slang_build_export_code_table (slang_export_code_table *tbl, slang_function_scope *funs,
149 slang_code_unit *unit)
150 {
151 slang_atom mainAtom;
152 GLuint i;
153
154 mainAtom = slang_atom_pool_atom (tbl->atoms, "main");
155 if (mainAtom == SLANG_ATOM_NULL)
156 return GL_FALSE;
157
158 for (i = 0; i < funs->num_functions; i++)
159 {
160 if (funs->functions[i].header.a_name == mainAtom)
161 {
162 slang_function *fun = &funs->functions[i];
163 slang_export_code_entry *e;
164 slang_assemble_ctx A;
165
166 e = slang_export_code_table_add (tbl);
167 if (e == NULL)
168 return GL_FALSE;
169 e->address = unit->object->assembly.count;
170 e->name = slang_atom_pool_atom (tbl->atoms, "@main");
171 if (e->name == SLANG_ATOM_NULL)
172 return GL_FALSE;
173
174 A.file = &unit->object->assembly;
175 A.mach = &unit->object->machine;
176 A.atoms = &unit->object->atompool;
177 A.space.funcs = &unit->funs;
178 A.space.structs = &unit->structs;
179 A.space.vars = &unit->vars;
180 slang_assembly_file_push_label (&unit->object->assembly, slang_asm_local_alloc, 20);
181 slang_assembly_file_push_label (&unit->object->assembly, slang_asm_enter, 20);
182 _slang_assemble_function_call (&A, fun, NULL, 0, GL_FALSE);
183 slang_assembly_file_push (&unit->object->assembly, slang_asm_exit);
184 }
185 }
186 return GL_TRUE;
187 }
188