2 * Mesa 3-D graphics library
5 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
26 * \file slang_compile_function.c
27 * slang front-end compiler
32 #include "slang_compile.h"
34 /* slang_fixup_table */
37 slang_fixup_table_init(slang_fixup_table
* fix
)
44 slang_fixup_table_free(slang_fixup_table
* fix
)
46 slang_alloc_free(fix
->table
);
47 slang_fixup_table_init(fix
);
51 * Add a new fixup address to the table.
54 slang_fixup_save(slang_fixup_table
*fixups
, GLuint address
)
56 fixups
->table
= (GLuint
*)
57 slang_alloc_realloc(fixups
->table
,
58 fixups
->count
* sizeof(GLuint
),
59 (fixups
->count
+ 1) * sizeof(GLuint
));
60 if (fixups
->table
== NULL
)
62 fixups
->table
[fixups
->count
] = address
;
72 slang_function_construct(slang_function
* func
)
74 func
->kind
= slang_func_ordinary
;
75 if (!slang_variable_construct(&func
->header
))
78 func
->parameters
= (slang_variable_scope
*)
79 slang_alloc_malloc(sizeof(slang_variable_scope
));
80 if (func
->parameters
== NULL
) {
81 slang_variable_destruct(&func
->header
);
85 _slang_variable_scope_ctr(func
->parameters
);
86 func
->param_count
= 0;
89 slang_fixup_table_init(&func
->fixups
);
94 slang_function_destruct(slang_function
* func
)
96 slang_variable_destruct(&func
->header
);
97 slang_variable_scope_destruct(func
->parameters
);
98 slang_alloc_free(func
->parameters
);
99 if (func
->body
!= NULL
) {
100 slang_operation_destruct(func
->body
);
101 slang_alloc_free(func
->body
);
103 slang_fixup_table_free(&func
->fixups
);
107 * slang_function_scope
111 _slang_function_scope_ctr(slang_function_scope
* self
)
113 self
->functions
= NULL
;
114 self
->num_functions
= 0;
115 self
->outer_scope
= NULL
;
119 slang_function_scope_destruct(slang_function_scope
* scope
)
123 for (i
= 0; i
< scope
->num_functions
; i
++)
124 slang_function_destruct(scope
->functions
+ i
);
125 slang_alloc_free(scope
->functions
);
130 * Search a list of functions for a particular function by name.
131 * \param funcs the list of functions to search
132 * \param a_name the name to search for
133 * \param all_scopes if non-zero, search containing scopes too.
134 * \return pointer to found function, or NULL.
137 slang_function_scope_find_by_name(slang_function_scope
* funcs
,
138 slang_atom a_name
, int all_scopes
)
142 for (i
= 0; i
< funcs
->num_functions
; i
++)
143 if (a_name
== funcs
->functions
[i
].header
.a_name
)
145 if (all_scopes
&& funcs
->outer_scope
!= NULL
)
146 return slang_function_scope_find_by_name(funcs
->outer_scope
, a_name
, 1);
152 * Search a list of functions for a particular function (for implementing
153 * function calls. Matching is done by first comparing the function's name,
154 * then the function's parameter list.
156 * \param funcs the list of functions to search
157 * \param fun the function to search for
158 * \param all_scopes if non-zero, search containing scopes too.
159 * \return pointer to found function, or NULL.
162 slang_function_scope_find(slang_function_scope
* funcs
, slang_function
* fun
,
167 for (i
= 0; i
< funcs
->num_functions
; i
++) {
168 slang_function
*f
= &funcs
->functions
[i
];
171 if (fun
->header
.a_name
!= f
->header
.a_name
)
173 if (fun
->param_count
!= f
->param_count
)
175 for (j
= 0; j
< fun
->param_count
; j
++) {
176 if (!slang_type_specifier_equal
177 (&fun
->parameters
->variables
[j
].type
.specifier
,
178 &f
->parameters
->variables
[j
].type
.specifier
))
181 if (j
== fun
->param_count
)
184 if (all_scopes
&& funcs
->outer_scope
!= NULL
)
185 return slang_function_scope_find(funcs
->outer_scope
, fun
, 1);
190 * _slang_build_export_code_table()
194 _slang_build_export_code_table(slang_export_code_table
* tbl
,
195 slang_function_scope
* funs
,
196 slang_code_unit
* unit
)
201 mainAtom
= slang_atom_pool_atom(tbl
->atoms
, "main");
202 if (mainAtom
== SLANG_ATOM_NULL
)
205 for (i
= 0; i
< funs
->num_functions
; i
++) {
206 if (funs
->functions
[i
].header
.a_name
== mainAtom
) {
207 slang_function
*fun
= &funs
->functions
[i
];
208 slang_export_code_entry
*e
;
209 slang_assemble_ctx A
;
211 e
= slang_export_code_table_add(tbl
);
214 e
->address
= unit
->object
->assembly
.count
;
215 e
->name
= slang_atom_pool_atom(tbl
->atoms
, "@main");
216 if (e
->name
== SLANG_ATOM_NULL
)
219 A
.file
= &unit
->object
->assembly
;
220 A
.mach
= &unit
->object
->machine
;
221 A
.atoms
= &unit
->object
->atompool
;
222 A
.space
.funcs
= &unit
->funs
;
223 A
.space
.structs
= &unit
->structs
;
224 A
.space
.vars
= &unit
->vars
;
225 slang_assembly_file_push_label(&unit
->object
->assembly
,
226 slang_asm_local_alloc
, 20);
227 slang_assembly_file_push_label(&unit
->object
->assembly
,
228 slang_asm_enter
, 20);
229 _slang_assemble_function_call(&A
, fun
, NULL
, 0, GL_FALSE
);
230 slang_assembly_file_push(&unit
->object
->assembly
, slang_asm_exit
);