Add support for forward function declarations.
authorMichal Krol <mjkrol@gmail.org>
Wed, 15 Feb 2006 11:15:16 +0000 (11:15 +0000)
committerMichal Krol <mjkrol@gmail.org>
Wed, 15 Feb 2006 11:15:16 +0000 (11:15 +0000)
src/mesa/shader/slang/slang_assemble.c
src/mesa/shader/slang/slang_assemble.h
src/mesa/shader/slang/slang_assemble_assignment.c
src/mesa/shader/slang/slang_assemble_assignment.h
src/mesa/shader/slang/slang_compile.c
src/mesa/shader/slang/slang_compile_function.c
src/mesa/shader/slang/slang_compile_function.h

index 45b6b19..698b3bf 100644 (file)
@@ -268,22 +268,36 @@ slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom
 \r
 /* _slang_assemble_function() */\r
 \r
-int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,\r
-       slang_assembly_name_space *space, slang_machine *mach, slang_atom_pool *atoms)\r
+int _slang_assemble_function (slang_assemble_ctx *A, slang_function *fun)\r
 {\r
        unsigned int param_size, local_size;\r
        unsigned int skip, cleanup;\r
-       slang_assembly_flow_control flow;\r
-       slang_assembly_local_info info;\r
-       slang_assembly_stack_info stk;\r
 \r
-       fun->address = file->count;\r
+       fun->address = A->file->count;\r
 \r
        if (fun->body == NULL)\r
        {\r
-               /* TODO: jump to the actual function body */\r
+               /* jump to the actual function body - we do not know it, so add the instruction\r
+                * to fixup table */\r
+               fun->fixups.table = (GLuint *) slang_alloc_realloc (fun->fixups.table,\r
+                       fun->fixups.count * sizeof (GLuint), (fun->fixups.count + 1) * sizeof (GLuint));\r
+               if (fun->fixups.table == NULL)\r
+                       return 0;\r
+               fun->fixups.table[fun->fixups.count] = fun->address;\r
+               fun->fixups.count++;\r
+               if (!PUSH (A->file, slang_asm_jump))\r
+                       return 0;\r
                return 1;\r
        }\r
+       else\r
+       {\r
+               GLuint i;\r
+\r
+               /* resolve all fixup table entries and delete it */\r
+               for (i = 0; i < fun->fixups.count; i++)\r
+                       A->file->code[fun->fixups.table[i]].param[0] = fun->address;\r
+               slang_fixup_table_free (&fun->fixups);\r
+       }\r
 \r
        /* At this point traverse function formal parameters and code to calculate\r
         * total memory size to be allocated on the stack.\r
@@ -294,71 +308,82 @@ int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,
        /* calculate return value size */\r
        param_size = 0;\r
        if (fun->header.type.specifier.type != slang_spec_void)\r
-               if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,\r
-                               &param_size, mach, file, atoms))\r
+               if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, &A->space,\r
+                               &param_size, A->mach, A->file, A->atoms))\r
                        return 0;\r
-       info.ret_size = param_size;\r
+       A->local.ret_size = param_size;\r
 \r
        /* calculate formal parameter list size */\r
-       if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, &param_size, mach, file,\r
-                       atoms))\r
+       if (!sizeof_variables (fun->parameters, 0, fun->param_count, &A->space, &param_size, A->mach, A->file,\r
+                       A->atoms))\r
                return 0;\r
 \r
        /* calculate local variables size - take into account the four-byte return address and\r
         * temporaries for various tasks (4 for addr and 16 for swizzle temporaries).\r
         * these include variables from the formal parameter scope and from the code */\r
-       info.addr_tmp = param_size + 4;\r
-       info.swizzle_tmp = param_size + 4 + 4;\r
+       A->local.addr_tmp = param_size + 4;\r
+       A->local.swizzle_tmp = param_size + 4 + 4;\r
        local_size = param_size + 4 + 4 + 16;\r
-       if (!sizeof_variables (fun->parameters, fun->param_count, fun->parameters->num_variables, space,\r
-                       &local_size, mach, file, atoms))\r
+       if (!sizeof_variables (fun->parameters, fun->param_count, fun->parameters->num_variables, &A->space,\r
+                       &local_size, A->mach, A->file, A->atoms))\r
                return 0;\r
-       if (!collect_locals (fun->body, space, &local_size, mach, file, atoms))\r
+       if (!collect_locals (fun->body, &A->space, &local_size, A->mach, A->file, A->atoms))\r
                return 0;\r
 \r
        /* allocate local variable storage */\r
-       if (!PLAB (file, slang_asm_local_alloc, local_size - param_size - 4))\r
+       if (!PLAB (A->file, slang_asm_local_alloc, local_size - param_size - 4))\r
                return 0;\r
 \r
        /* mark a new frame for function variable storage */\r
-       if (!PLAB (file, slang_asm_enter, local_size))\r
+       if (!PLAB (A->file, slang_asm_enter, local_size))\r
                return 0;\r
 \r
        /* jump directly to the actual code */\r
-       skip = file->count;\r
-       if (!push_new (file))\r
+       skip = A->file->count;\r
+       if (!push_new (A->file))\r
                return 0;\r
-       file->code[skip].type = slang_asm_jump;\r
+       A->file->code[skip].type = slang_asm_jump;\r
 \r
        /* all "return" statements will be directed here */\r
-       flow.function_end = file->count;\r
-       cleanup = file->count;\r
-       if (!push_new (file))\r
+       A->flow.function_end = A->file->count;\r
+       cleanup = A->file->count;\r
+       if (!push_new (A->file))\r
                return 0;\r
-       file->code[cleanup].type = slang_asm_jump;\r
+       A->file->code[cleanup].type = slang_asm_jump;\r
 \r
        /* execute the function body */\r
-       file->code[skip].param[0] = file->count;\r
-       if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk, mach, atoms))\r
+       A->file->code[skip].param[0] = A->file->count;\r
+       if (!_slang_assemble_operation_ (A, fun->body, slang_ref_freelance))\r
                return 0;\r
 \r
        /* this is the end of the function - restore the old function frame */\r
-       file->code[cleanup].param[0] = file->count;\r
-       if (!PUSH (file, slang_asm_leave))\r
+       A->file->code[cleanup].param[0] = A->file->count;\r
+       if (!PUSH (A->file, slang_asm_leave))\r
                return 0;\r
 \r
        /* free local variable storage */\r
-       if (!PLAB (file, slang_asm_local_free, local_size - param_size - 4))\r
+       if (!PLAB (A->file, slang_asm_local_free, local_size - param_size - 4))\r
                return 0;\r
 \r
        /* return from the function */\r
-       if (!PUSH (file, slang_asm_return))\r
+       if (!PUSH (A->file, slang_asm_return))\r
                return 0;\r
        return 1;\r
 }\r
 \r
 int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int ref,\r
-       slang_assembly_name_space *space, slang_machine *mach, slang_atom_pool *atoms)\r
+       slang_assembly_name_space *space, struct slang_machine_ *mach, slang_atom_pool *atoms)\r
+{\r
+       slang_assemble_ctx A;\r
+\r
+       A.file = file;\r
+       A.mach = mach;\r
+       A.atoms = atoms;\r
+       A.space = *space;\r
+       return _slang_cleanup_stack_ (&A, op);\r
+}\r
+\r
+int _slang_cleanup_stack_ (slang_assemble_ctx *A, slang_operation *op)\r
 {\r
        slang_assembly_typeinfo ti;\r
        unsigned int size = 0;\r
@@ -366,15 +391,15 @@ int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int re
        /* get type info of the operation and calculate its size */\r
        if (!slang_assembly_typeinfo_construct (&ti))\r
                return 0;\r
-       if (!_slang_typeof_operation (op, space, &ti, atoms))\r
+       if (!_slang_typeof_operation (op, &A->space, &ti, A->atoms))\r
        {\r
                slang_assembly_typeinfo_destruct (&ti);\r
                return 0;\r
        }\r
-       if (ref)\r
+       if (A->ref == slang_ref_force)\r
                size = 4;\r
        else if (ti.spec.type != slang_spec_void)\r
-               if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size, mach, file, atoms))\r
+               if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, &A->space, &size, A->mach, A->file, A->atoms))\r
                {\r
                        slang_assembly_typeinfo_destruct (&ti);\r
                        return 0;\r
@@ -384,7 +409,7 @@ int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int re
        /* if nonzero, free it from the stack */\r
        if (size != 0)\r
        {\r
-               if (!PLAB (file, slang_asm_local_free, size))\r
+               if (!PLAB (A->file, slang_asm_local_free, size))\r
                        return 0;\r
        }\r
        return 1;\r
@@ -499,9 +524,8 @@ int _slang_dereference (slang_assembly_file *file, slang_operation *op,
        return result;\r
 }\r
 \r
-int _slang_call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params,\r
-       unsigned int param_count, int assignment, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)\r
+int _slang_assemble_function_call (slang_assemble_ctx *A, slang_function *fun,\r
+       slang_operation *params, GLuint param_count, GLboolean assignment)\r
 {\r
        unsigned int i;\r
        slang_assembly_stack_info p_stk[64];\r
@@ -515,52 +539,50 @@ int _slang_call_function (slang_assembly_file *file, slang_function *fun, slang_
        {\r
                unsigned int ret_size = 0;\r
 \r
-               if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,\r
-                               &ret_size, mach, file, atoms))\r
+               if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, &A->space,\r
+                               &ret_size, A->mach, A->file, A->atoms))\r
                        return 0;\r
-               if (!PLAB (file, slang_asm_local_alloc, ret_size))\r
+               if (!PLAB (A->file, slang_asm_local_alloc, ret_size))\r
                        return 0;\r
        }\r
 \r
        /* push the actual parameters on the stack */\r
        for (i = 0; i < param_count; i++)\r
        {\r
-               slang_assembly_flow_control flow;\r
-\r
                if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||\r
                        fun->parameters->variables[i].type.qualifier == slang_qual_out)\r
                {\r
-                       if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
+                       if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))\r
                                return 0;\r
                        /* TODO: optimize the "out" parameter case */\r
-                       if (!_slang_assemble_operation (file, &params[i], 1, &flow, space, info, &p_stk[i],\r
-                                       mach, atoms))\r
+                       if (!_slang_assemble_operation_ (A, &params[i], slang_ref_force))\r
                                return 0;\r
-                       if (!PUSH (file, slang_asm_addr_copy))\r
+                       p_stk[i] = A->swz;\r
+                       if (!PUSH (A->file, slang_asm_addr_copy))\r
                                return 0;\r
-                       if (!PUSH (file, slang_asm_addr_deref))\r
+                       if (!PUSH (A->file, slang_asm_addr_deref))\r
                                return 0;\r
                        if (i == 0 && assignment)\r
                        {\r
                                /* duplicate the resulting address */\r
-                               if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
+                               if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))\r
                                        return 0;\r
-                               if (!PUSH (file, slang_asm_addr_deref))\r
+                               if (!PUSH (A->file, slang_asm_addr_deref))\r
                                        return 0;\r
                        }\r
-                       if (!_slang_dereference (file, &params[i], space, info, mach, atoms))\r
+                       if (!_slang_dereference (A->file, &params[i], &A->space, &A->local, A->mach, A->atoms))\r
                                return 0;\r
                }\r
                else\r
                {\r
-                       if (!_slang_assemble_operation (file, &params[i], 0, &flow, space, info, &p_stk[i],\r
-                                       mach, atoms))\r
+                       if (!_slang_assemble_operation_ (A, &params[i], slang_ref_forbid))\r
                                return 0;\r
+                       p_stk[i] = A->swz;\r
                }\r
        }\r
 \r
        /* call the function */\r
-       if (!PLAB (file, slang_asm_call, fun->address))\r
+       if (!PLAB (A->file, slang_asm_call, fun->address))\r
                return 0;\r
 \r
        /* pop the parameters from the stack */\r
@@ -573,16 +595,17 @@ int _slang_call_function (slang_assembly_file *file, slang_function *fun, slang_
                {\r
                        /* for output parameter copy the contents of the formal parameter\r
                         * back to the original actual parameter */\r
-                       if (!_slang_assemble_assignment (file, &params[j], space, info, &p_stk[j], mach, atoms))\r
+                       A->swz = p_stk[j];\r
+                       if (!_slang_assemble_assignment (A, &params[j]))\r
                                return 0;\r
                        /* pop the actual parameter's address */\r
-                       if (!PLAB (file, slang_asm_local_free, 4))\r
+                       if (!PLAB (A->file, slang_asm_local_free, 4))\r
                                return 0;\r
                }\r
                else\r
                {\r
                        /* pop the value of the parameter */\r
-                       if (!_slang_cleanup_stack (file, &params[j], 0, space, mach, atoms))\r
+                       if (!_slang_cleanup_stack_ (A, &params[j]))\r
                                return 0;\r
                }\r
        }\r
@@ -590,27 +613,23 @@ int _slang_call_function (slang_assembly_file *file, slang_function *fun, slang_
        return 1;\r
 }\r
 \r
-/* TODO: migrate to full-atom version */\r
-int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,\r
-       unsigned int param_count, int assignment, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)\r
+int _slang_assemble_function_call_name (slang_assemble_ctx *A, const char *name,\r
+       slang_operation *params, GLuint param_count, GLboolean assignment)\r
 {\r
        slang_atom atom;\r
        slang_function *fun;\r
 \r
-       atom = slang_atom_pool_atom (atoms, name);\r
+       atom = slang_atom_pool_atom (A->atoms, name);\r
        if (atom == SLANG_ATOM_NULL)\r
                return 0;\r
-       fun = _slang_locate_function (space->funcs, atom, params, param_count, space, atoms);\r
+       fun = _slang_locate_function (A->space.funcs, atom, params, param_count, &A->space, A->atoms);\r
        if (fun == NULL)\r
                return 0;\r
-       return _slang_call_function (file, fun, params, param_count, assignment, space, info, mach,\r
-               atoms);\r
+       return _slang_assemble_function_call (A, fun, params, param_count, assignment);\r
 }\r
 \r
-static int call_function_name_dummyint (slang_assembly_file *file, const char *name,\r
-       slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info,\r
-       slang_machine *mach, slang_atom_pool *atoms)\r
+static int assemble_function_call_name_dummyint (slang_assemble_ctx *A, const char *name,\r
+       slang_operation *params)\r
 {\r
        slang_operation p[2];\r
        int result;\r
@@ -619,7 +638,7 @@ static int call_function_name_dummyint (slang_assembly_file *file, const char *n
        if (!slang_operation_construct (&p[1]))\r
                return 0;\r
        p[1].type = slang_oper_literal_int;\r
-       result = call_function_name (file, name, p, 2, 0, space, info, mach, atoms);\r
+       result = _slang_assemble_function_call_name (A, name, p, 2, GL_FALSE);\r
        slang_operation_destruct (&p[1]);\r
        return result;\r
 }\r
@@ -1001,19 +1020,40 @@ static int handle_field (slang_assembly_typeinfo *tia, slang_assembly_typeinfo *
        return 1;\r
 }\r
 \r
-int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, int reference,\r
-       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info, slang_assembly_stack_info *stk, slang_machine *mach,\r
-       slang_atom_pool *atoms)\r
+int _slang_assemble_operation (slang_assembly_file *file, struct slang_operation_ *op, int reference,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space, slang_assembly_local_info *info,\r
+       slang_assembly_stack_info *stk, struct slang_machine_ *mach, slang_atom_pool *atoms)\r
 {\r
-       unsigned int assem;\r
+       slang_assemble_ctx A;\r
+\r
+       A.file = file;\r
+       A.mach = mach;\r
+       A.atoms = atoms;\r
+       A.space = *space;\r
+       A.flow = *flow;\r
+       A.local = *info;\r
+       if (!_slang_assemble_operation_ (&A, op, reference ? slang_ref_force : slang_ref_forbid))\r
+               return 0;\r
+       *stk = A.swz;\r
+       return 1;\r
+}\r
 \r
-       stk->swizzle.num_components = 0;\r
+int _slang_assemble_operation_ (slang_assemble_ctx *A, slang_operation *op, slang_ref_type ref)\r
+{\r
+       unsigned int assem;\r
+       slang_assembly_stack_info swz;\r
 \r
-       assem = file->count;\r
-       if (!push_new (file))\r
+       assem = A->file->count;\r
+       if (!push_new (A->file))\r
                return 0;\r
 \r
+if (ref == slang_ref_freelance)\r
+ref = slang_ref_forbid;\r
+\r
+       /* set default results */\r
+       A->ref = (ref == slang_ref_freelance) ? slang_ref_force : ref;\r
+       swz.swizzle.num_components = 0;\r
+\r
        switch (op->type)\r
        {\r
        case slang_oper_block_no_new_scope:\r
@@ -1023,13 +1063,9 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
 \r
                        for (i = 0; i < op->num_children; i++)\r
                        {\r
-                               slang_assembly_stack_info stk;\r
-\r
-                               if (!_slang_assemble_operation (file, &op->children[i], 0, flow, space, info, &stk,\r
-                                               mach, atoms))\r
+                               if (!_slang_assemble_operation_ (A, &op->children[i], slang_ref_freelance))\r
                                        return 0;\r
-                               /* ignore the stk */\r
-                               if (!_slang_cleanup_stack (file, &op->children[i], 0, space, mach, atoms))\r
+                               if (!_slang_cleanup_stack_ (A, &op->children[i]))\r
                                        return 0;\r
                        }\r
                }\r
@@ -1049,95 +1085,92 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
                {\r
                        unsigned int i;\r
 \r
-                       for (i = 0; i < op->num_children; i++)\r
-                       {\r
-                               slang_assembly_stack_info stk;\r
-\r
-                               if (!_slang_assemble_operation (file, &op->children[i], i == 0, flow, space, info,\r
-                                               &stk, mach, atoms))\r
+                       if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_force))\r
+                               return 0;\r
+                       for (i = 1; i < op->num_children; i++)\r
+                               if (!_slang_assemble_operation_ (A, &op->children[i], slang_ref_forbid))\r
                                        return 0;\r
-                               /* __asm statement does not support any swizzles, so lets ignore stk for now */\r
-                       }\r
-                       if (!call_asm_instruction (file, op->a_id, atoms))\r
+                       if (!call_asm_instruction (A->file, op->a_id, A->atoms))\r
                                return 0;\r
                }\r
                break;\r
        case slang_oper_break:\r
-               file->code[assem].type = slang_asm_jump;\r
-               file->code[assem].param[0] = flow->loop_end;\r
+               A->file->code[assem].type = slang_asm_jump;\r
+               A->file->code[assem].param[0] = A->flow.loop_end;\r
                break;\r
        case slang_oper_continue:\r
-               file->code[assem].type = slang_asm_jump;\r
-               file->code[assem].param[0] = flow->loop_start;\r
+               A->file->code[assem].type = slang_asm_jump;\r
+               A->file->code[assem].param[0] = A->flow.loop_start;\r
                break;\r
        case slang_oper_discard:\r
-               file->code[assem].type = slang_asm_discard;\r
-               if (!PUSH (file, slang_asm_exit))\r
+               A->file->code[assem].type = slang_asm_discard;\r
+               if (!PUSH (A->file, slang_asm_exit))\r
                        return 0;\r
                break;\r
        case slang_oper_return:\r
-               if (info->ret_size != 0)\r
+               if (A->local.ret_size != 0)\r
                {\r
-                       slang_assembly_stack_info stk;\r
-\r
                        /* push the result's address */\r
-                       if (!PLAB2 (file, slang_asm_local_addr, 0, info->ret_size))\r
+                       if (!PLAB2 (A->file, slang_asm_local_addr, 0, A->local.ret_size))\r
                                return 0;\r
-                       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,\r
-                                       mach, atoms))\r
+                       if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_forbid))\r
                                return 0;\r
 \r
-                       /* ignore the stk from latest operation, reset swizzle to 0 for the assignment */\r
-                       stk.swizzle.num_components = 0;\r
+                       A->swz.swizzle.num_components = 0;\r
                        /* assign the operation to the function result (it was reserved on the stack) */\r
-                       if (!_slang_assemble_assignment (file, op->children, space, info, &stk, mach, atoms))\r
+                       if (!_slang_assemble_assignment (A, op->children))\r
                                return 0;\r
 \r
-                       if (!PLAB (file, slang_asm_local_free, 4))\r
+                       if (!PLAB (A->file, slang_asm_local_free, 4))\r
                                return 0;\r
                }\r
-               if (!PLAB (file, slang_asm_jump, flow->function_end))\r
+               if (!PLAB (A->file, slang_asm_jump, A->flow.function_end))\r
                        return 0;\r
                break;\r
        case slang_oper_expression:\r
-               {\r
-                       slang_assembly_stack_info stk;\r
-\r
-                       assert (!reference);\r
-                       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk, mach, atoms))\r
-                               return 0;\r
-                       /* ignore the stk info */\r
-               }\r
+               if (ref == slang_ref_force)\r
+                       return 0;\r
+               if (!_slang_assemble_operation_ (A, &op->children[0], ref))\r
+                       return 0;\r
                break;\r
        case slang_oper_if:\r
-               if (!_slang_assemble_if (file, op, flow, space, info, mach, atoms))\r
+               if (!_slang_assemble_if (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_while:\r
-               if (!_slang_assemble_while (file, op, flow, space, info, mach, atoms))\r
+               if (!_slang_assemble_while (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_do:\r
-               if (!_slang_assemble_do (file, op, flow, space, info, mach, atoms))\r
+               if (!_slang_assemble_do (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_for:\r
-               if (!_slang_assemble_for (file, op, flow, space, info, mach, atoms))\r
+               if (!_slang_assemble_for (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_void:\r
                break;\r
        case slang_oper_literal_bool:\r
-               file->code[assem].type = slang_asm_bool_push;\r
-               file->code[assem].literal = op->literal;\r
+               if (ref == slang_ref_force)\r
+                       return 0;\r
+               A->file->code[assem].type = slang_asm_bool_push;\r
+               A->file->code[assem].literal = op->literal;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_literal_int:\r
-               file->code[assem].type = slang_asm_int_push;\r
-               file->code[assem].literal = op->literal;\r
+               if (ref == slang_ref_force)\r
+                       return 0;\r
+               A->file->code[assem].type = slang_asm_int_push;\r
+               A->file->code[assem].literal = op->literal;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_literal_float:\r
-               file->code[assem].type = slang_asm_float_push;\r
-               file->code[assem].literal = op->literal;\r
+               if (ref == slang_ref_force)\r
+                       return 0;\r
+               A->file->code[assem].type = slang_asm_float_push;\r
+               A->file->code[assem].literal = op->literal;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_identifier:\r
                {\r
@@ -1149,69 +1182,64 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
                        if (var == NULL)\r
                                return 0;\r
                        size = 0;\r
-                       if (!sizeof_variable (&var->type.specifier, slang_qual_none, var->array_size, space,\r
-                                       &size, mach, file, atoms))\r
+                       if (!sizeof_variable (&var->type.specifier, slang_qual_none, var->array_size, &A->space,\r
+                                       &size, A->mach, A->file, A->atoms))\r
                                return 0;\r
 \r
                        /* prepare stack for dereferencing */\r
-                       if (!reference)\r
-                               if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
+                       if (ref == slang_ref_forbid)\r
+                               if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))\r
                                        return 0;\r
 \r
                        /* push the variable's address */\r
                        if (var->global)\r
                        {\r
-                               if (!PLAB (file, slang_asm_addr_push, var->address))\r
+                               if (!PLAB (A->file, slang_asm_addr_push, var->address))\r
                                        return 0;\r
                        }\r
                        else\r
                        {\r
-                               if (!PLAB2 (file, slang_asm_local_addr, var->address, size))\r
+                               if (!PLAB2 (A->file, slang_asm_local_addr, var->address, size))\r
                                        return 0;\r
                        }\r
 \r
                        /* perform the dereference */\r
-                       if (!reference)\r
+                       if (ref == slang_ref_forbid)\r
                        {\r
-                               if (!PUSH (file, slang_asm_addr_copy))\r
+                               if (!PUSH (A->file, slang_asm_addr_copy))\r
                                        return 0;\r
-                               if (!PLAB (file, slang_asm_local_free, 4))\r
+                               if (!PLAB (A->file, slang_asm_local_free, 4))\r
                                        return 0;\r
-                               if (!_slang_dereference (file, op, space, info, mach, atoms))\r
+                               if (!_slang_dereference (A->file, op, &A->space, &A->local, A->mach, A->atoms))\r
                                        return 0;\r
                        }\r
                }\r
                break;\r
        case slang_oper_sequence:\r
-               {\r
-                       slang_assembly_stack_info stk;\r
-\r
-                       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,\r
-                                       mach, atoms))\r
-                               return 0;\r
-                       /* TODO: pass-in stk to cleanup */\r
-                       if (!_slang_cleanup_stack (file, &op->children[0], 0, space, mach, atoms))\r
-                               return 0;\r
-                       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info,\r
-                                       &stk, mach, atoms))\r
-                               return 0;\r
-                       /* TODO: inspect stk */\r
-               }\r
+               if (ref == slang_ref_force)\r
+                       return 0;\r
+               if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_freelance))\r
+                       return 0;\r
+               if (!_slang_cleanup_stack_ (A, &op->children[0]))\r
+                       return 0;\r
+               if (!_slang_assemble_operation_ (A, &op->children[1], slang_ref_forbid))\r
+                       return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_assign:\r
-               if (!_slang_assemble_assign (file, op, "=", reference, space, info, mach, atoms))\r
+               if (!_slang_assemble_assign (A, op, "=", ref))\r
                        return 0;\r
                break;\r
        case slang_oper_addassign:\r
-               if (!_slang_assemble_assign (file, op, "+=", reference, space, info, mach, atoms))\r
+               if (!_slang_assemble_assign (A, op, "+=", ref))\r
                        return 0;\r
                break;\r
        case slang_oper_subassign:\r
-               if (!_slang_assemble_assign (file, op, "-=", reference, space, info, mach, atoms))\r
+               if (!_slang_assemble_assign (A, op, "-=", ref))\r
                        return 0;\r
                break;\r
        case slang_oper_mulassign:\r
-               if (!_slang_assemble_assign (file, op, "*=", reference, space, info, mach, atoms))\r
+               if (!_slang_assemble_assign (A, op, "*=", ref))\r
                        return 0;\r
                break;\r
        /*case slang_oper_modassign:*/\r
@@ -1221,111 +1249,116 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
        /*case slang_oper_xorassign:*/\r
        /*case slang_oper_andassign:*/\r
        case slang_oper_divassign:\r
-               if (!_slang_assemble_assign (file, op, "/=", reference, space, info, mach, atoms))\r
+               if (!_slang_assemble_assign (A, op, "/=", ref))\r
                        return 0;\r
                break;\r
        case slang_oper_select:\r
-               if (!_slang_assemble_select (file, op, flow, space, info, mach, atoms))\r
+               if (!_slang_assemble_select (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_logicalor:\r
-               if (!_slang_assemble_logicalor (file, op, flow, space, info, mach, atoms))\r
+               if (!_slang_assemble_logicalor (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_logicaland:\r
-               if (!_slang_assemble_logicaland (file, op, flow, space, info, mach, atoms))\r
+               if (!_slang_assemble_logicaland (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_logicalxor:\r
-               if (!call_function_name (file, "^^", op->children, 2, 0, space, info, mach, atoms))\r
+               if (!_slang_assemble_function_call_name (A, "^^", op->children, 2, GL_FALSE))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        /*case slang_oper_bitor:*/\r
        /*case slang_oper_bitxor:*/\r
        /*case slang_oper_bitand:*/\r
        case slang_oper_less:\r
-               if (!call_function_name (file, "<", op->children, 2, 0, space, info, mach, atoms))\r
+               if (!_slang_assemble_function_call_name (A, "<", op->children, 2, GL_FALSE))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_greater:\r
-               if (!call_function_name (file, ">", op->children, 2, 0, space, info, mach, atoms))\r
+               if (!_slang_assemble_function_call_name (A, ">", op->children, 2, GL_FALSE))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_lessequal:\r
-               if (!call_function_name (file, "<=", op->children, 2, 0, space, info, mach, atoms))\r
+               if (!_slang_assemble_function_call_name (A, "<=", op->children, 2, GL_FALSE))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_greaterequal:\r
-               if (!call_function_name (file, ">=", op->children, 2, 0, space, info, mach, atoms))\r
+               if (!_slang_assemble_function_call_name (A, ">=", op->children, 2, GL_FALSE))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        /*case slang_oper_lshift:*/\r
        /*case slang_oper_rshift:*/\r
        case slang_oper_add:\r
-               if (!call_function_name (file, "+", op->children, 2, 0, space, info, mach, atoms))\r
+               if (!_slang_assemble_function_call_name (A, "+", op->children, 2, GL_FALSE))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_subtract:\r
-               if (!call_function_name (file, "-", op->children, 2, 0, space, info, mach, atoms))\r
+               if (!_slang_assemble_function_call_name (A, "-", op->children, 2, GL_FALSE))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_multiply:\r
-               if (!call_function_name (file, "*", op->children, 2, 0, space, info, mach, atoms))\r
+               if (!_slang_assemble_function_call_name (A, "*", op->children, 2, GL_FALSE))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        /*case slang_oper_modulus:*/\r
        case slang_oper_divide:\r
-               if (!call_function_name (file, "/", op->children, 2, 0, space, info, mach, atoms))\r
+               if (!_slang_assemble_function_call_name (A, "/", op->children, 2, GL_FALSE))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_equal:\r
-               {\r
-                       slang_assembly_stack_info stk;\r
-\r
-                       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,\r
-                                       mach, atoms))\r
-                               return 0;\r
-                       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk,\r
-                                       mach, atoms))\r
-                               return 0;\r
-                       if (!equality (file, op->children, space, info, 1, mach, atoms))\r
-                               return 0;\r
-               }\r
+               if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_forbid))\r
+                       return 0;\r
+               if (!_slang_assemble_operation_ (A, &op->children[1], slang_ref_forbid))\r
+                       return 0;\r
+               if (!equality (A->file, op->children, &A->space, &A->local, 1, A->mach, A->atoms))\r
+                       return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_notequal:\r
-               {\r
-                       slang_assembly_stack_info stk;\r
-\r
-                       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,\r
-                                       mach, atoms))\r
-                               return 0;\r
-                       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk,\r
-                                       mach, atoms))\r
-                               return 0;\r
-                       if (!equality (file, op->children, space, info, 0, mach, atoms))\r
-                               return 0;\r
-               }\r
+               if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_forbid))\r
+                       return 0;\r
+               if (!_slang_assemble_operation_ (A, &op->children[1], slang_ref_forbid))\r
+                       return 0;\r
+               if (!equality (A->file, op->children, &A->space, &A->local, 0, A->mach, A->atoms))\r
+                       return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_preincrement:\r
-               if (!_slang_assemble_assign (file, op, "++", reference, space, info, mach, atoms))\r
+               if (!_slang_assemble_assign (A, op, "++", ref))\r
                        return 0;\r
                break;\r
        case slang_oper_predecrement:\r
-               if (!_slang_assemble_assign (file, op, "--", reference, space, info, mach, atoms))\r
+               if (!_slang_assemble_assign (A, op, "--", ref))\r
                        return 0;\r
                break;\r
        case slang_oper_plus:\r
-               if (!_slang_dereference (file, op, space, info, mach, atoms))\r
+               if (!_slang_dereference (A->file, op, &A->space, &A->local, A->mach, A->atoms))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_minus:\r
-               if (!call_function_name (file, "-", op->children, 1, 0, space, info, mach, atoms))\r
+               if (!_slang_assemble_function_call_name (A, "-", op->children, 1, GL_FALSE))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        /*case slang_oper_complement:*/\r
        case slang_oper_not:\r
-               if (!call_function_name (file, "!", op->children, 1, 0, space, info, mach, atoms))\r
+               if (!_slang_assemble_function_call_name (A, "!", op->children, 1, GL_FALSE))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_subscript:\r
                {\r
@@ -1338,8 +1371,8 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
                                slang_assembly_typeinfo_destruct (&ti_arr);\r
                                return 0;\r
                        }\r
-                       if (!handle_subscript (&ti_elem, &ti_arr, file, op, reference, flow, space, info,\r
-                                       mach, atoms))\r
+                       if (!handle_subscript (&ti_elem, &ti_arr, A->file, op, ref != slang_ref_forbid, &A->flow, &A->space, &A->local,\r
+                                       A->mach, A->atoms))\r
                        {\r
                                slang_assembly_typeinfo_destruct (&ti_arr);\r
                                slang_assembly_typeinfo_destruct (&ti_elem);\r
@@ -1353,8 +1386,8 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
                {\r
                        slang_function *fun;\r
 \r
-                       fun = _slang_locate_function (space->funcs, op->a_id, op->children, op->num_children,\r
-                               space, atoms);\r
+                       fun = _slang_locate_function (A->space.funcs, op->a_id, op->children, op->num_children,\r
+                               &A->space, A->atoms);\r
                        if (fun == NULL)\r
                        {\r
 /*                             if (!_slang_assemble_constructor (file, op, flow, space, info, mach))\r
@@ -1362,10 +1395,10 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
                        }\r
                        else\r
                        {\r
-                               if (!_slang_call_function (file, fun, op->children, op->num_children, 0, space,\r
-                                               info, mach, atoms))\r
+                               if (!_slang_assemble_function_call (A, fun, op->children, op->num_children, GL_FALSE))\r
                                        return 0;\r
                        }\r
+                       A->ref = slang_ref_forbid;\r
                }\r
                break;\r
        case slang_oper_field:\r
@@ -1379,8 +1412,8 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
                                slang_assembly_typeinfo_destruct (&ti_after);\r
                                return 0;\r
                        }\r
-                       if (!handle_field (&ti_after, &ti_before, file, op, reference, flow, space, info, stk,\r
-                                       mach, atoms))\r
+                       if (!handle_field (&ti_after, &ti_before, A->file, op, ref != slang_ref_forbid, &A->flow, &A->space, &A->local, &swz,\r
+                                       A->mach, A->atoms))\r
                        {\r
                                slang_assembly_typeinfo_destruct (&ti_after);\r
                                slang_assembly_typeinfo_destruct (&ti_before);\r
@@ -1391,16 +1424,21 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
                }\r
                break;\r
        case slang_oper_postincrement:\r
-               if (!call_function_name_dummyint (file, "++", op->children, space, info, mach, atoms))\r
+               if (!assemble_function_call_name_dummyint (A, "++", op->children))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        case slang_oper_postdecrement:\r
-               if (!call_function_name_dummyint (file, "--", op->children, space, info, mach, atoms))\r
+               if (!assemble_function_call_name_dummyint (A, "--", op->children))\r
                        return 0;\r
+               A->ref = slang_ref_forbid;\r
                break;\r
        default:\r
                return 0;\r
        }\r
+\r
+       A->swz = swz;\r
+\r
        return 1;\r
 }\r
 \r
index c3af8d8..3d5eec2 100644 (file)
@@ -125,19 +125,19 @@ typedef struct slang_assembly_flow_control_
        unsigned int function_end;                      /* for "return" statement */\r
 } slang_assembly_flow_control;\r
 \r
-typedef struct slang_assembly_name_space_\r
+typedef struct slang_assembly_local_info_\r
 {\r
-       struct slang_function_scope_ *funcs;\r
-       struct slang_struct_scope_ *structs;\r
-       struct slang_variable_scope_ *vars;\r
-} slang_assembly_name_space;\r
-\r
-slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name,\r
-       slang_operation *params, unsigned int num_params, slang_assembly_name_space *space,\r
-       slang_atom_pool *);\r
+       unsigned int ret_size;\r
+       unsigned int addr_tmp;\r
+       unsigned int swizzle_tmp;\r
+} slang_assembly_local_info;\r
 \r
-int _slang_assemble_function (slang_assembly_file *, struct slang_function_ *,\r
-       slang_assembly_name_space *, struct slang_machine_ *, slang_atom_pool *);\r
+typedef enum\r
+{\r
+       slang_ref_force,\r
+       slang_ref_forbid,\r
+       slang_ref_freelance\r
+} slang_ref_type;\r
 \r
 /*\r
        holds a complete information about vector swizzle - the <swizzle> array contains\r
@@ -155,22 +155,48 @@ typedef struct slang_assembly_stack_info_
        slang_swizzle swizzle;\r
 } slang_assembly_stack_info;\r
 \r
-int _slang_cleanup_stack (slang_assembly_file *, slang_operation *, int ref,\r
-       slang_assembly_name_space *, struct slang_machine_ *, slang_atom_pool *);\r
+typedef struct slang_assembly_name_space_\r
+{\r
+       struct slang_function_scope_ *funcs;\r
+       struct slang_struct_scope_ *structs;\r
+       struct slang_variable_scope_ *vars;\r
+} slang_assembly_name_space;\r
 \r
-typedef struct slang_assembly_local_info_\r
+typedef struct slang_assemble_ctx_\r
 {\r
-       unsigned int ret_size;\r
-       unsigned int addr_tmp;\r
-       unsigned int swizzle_tmp;\r
-} slang_assembly_local_info;\r
+       slang_assembly_file *file;\r
+       struct slang_machine_ *mach;\r
+       slang_atom_pool *atoms;\r
+       slang_assembly_name_space space;\r
+       slang_assembly_flow_control flow;\r
+       slang_assembly_local_info local;\r
+       slang_ref_type ref;\r
+       slang_assembly_stack_info swz;\r
+} slang_assemble_ctx;\r
+\r
+slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name,\r
+       slang_operation *params, unsigned int num_params, slang_assembly_name_space *space,\r
+       slang_atom_pool *);\r
+\r
+int _slang_assemble_function (slang_assemble_ctx *, struct slang_function_ *);\r
+\r
+int _slang_cleanup_stack (slang_assembly_file *, slang_operation *, int ref,\r
+       slang_assembly_name_space *, struct slang_machine_ *, slang_atom_pool *);\r
+int _slang_cleanup_stack_ (slang_assemble_ctx *, slang_operation *);\r
 \r
 int _slang_dereference (slang_assembly_file *, slang_operation *, slang_assembly_name_space *,\r
        slang_assembly_local_info *, struct slang_machine_ *, slang_atom_pool *);\r
 \r
+int _slang_assemble_function_call (slang_assemble_ctx *, slang_function *,\r
+       slang_operation *, GLuint, GLboolean);\r
+\r
+int _slang_assemble_function_call_name (slang_assemble_ctx *, const char *,\r
+       slang_operation *, GLuint, GLboolean);\r
+\r
 int _slang_assemble_operation (slang_assembly_file *, struct slang_operation_ *, int reference,\r
        slang_assembly_flow_control *, slang_assembly_name_space *, slang_assembly_local_info *,\r
        slang_assembly_stack_info *, struct slang_machine_ *, slang_atom_pool *);\r
+int _slang_assemble_operation_ (slang_assemble_ctx *, struct slang_operation_ *, slang_ref_type);\r
 \r
 #ifdef __cplusplus\r
 }\r
index 3c35e86..afecf08 100644 (file)
@@ -117,9 +117,7 @@ static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggr
        return 1;\r
 }\r
 \r
-int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,\r
-       slang_assembly_name_space *space, slang_assembly_local_info *info, slang_assembly_stack_info *stk,\r
-       struct slang_machine_ *mach, slang_atom_pool *atoms)\r
+int _slang_assemble_assignment (slang_assemble_ctx *A, slang_operation *op)\r
 {\r
        slang_assembly_typeinfo ti;\r
        int result;\r
@@ -128,7 +126,7 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
 \r
        if (!slang_assembly_typeinfo_construct (&ti))\r
                return 0;\r
-       if (!_slang_typeof_operation (op, space, &ti, atoms))\r
+       if (!_slang_typeof_operation (op, &A->space, &ti, A->atoms))\r
        {\r
                slang_assembly_typeinfo_destruct (&ti);\r
                return 0;\r
@@ -139,8 +137,8 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
                slang_assembly_typeinfo_destruct (&ti);\r
                return 0;\r
        }\r
-       if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,\r
-                       space->vars, mach, file, atoms))\r
+       if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, A->space.funcs, A->space.structs,\r
+                       A->space.vars, A->mach, A->file, A->atoms))\r
        {\r
                slang_storage_aggregate_destruct (&agg);\r
                slang_assembly_typeinfo_destruct (&ti);\r
@@ -149,7 +147,7 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
 \r
        index = 0;\r
        size = _slang_sizeof_aggregate (&agg);\r
-       result = assign_aggregate (file, &agg, &index, size, info, stk);\r
+       result = assign_aggregate (A->file, &agg, &index, size, &A->local, &A->swz);\r
 \r
        slang_storage_aggregate_destruct (&agg);\r
        slang_assembly_typeinfo_destruct (&ti);\r
@@ -163,48 +161,41 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
        children\r
 */\r
 \r
-int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,\r
-       unsigned int param_count, int assignment, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms);\r
-\r
-int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, const char *oper,\r
-       int ref, slang_assembly_name_space *space, slang_assembly_local_info *info,\r
-       struct slang_machine_ *mach, slang_atom_pool *atoms)\r
+int _slang_assemble_assign (slang_assemble_ctx *A, slang_operation *op, const char *oper,\r
+       slang_ref_type ref)\r
 {\r
-       slang_assembly_stack_info l_stk, r_stk;\r
-       slang_assembly_flow_control flow;\r
+       slang_assembly_stack_info stk;\r
 \r
-       if (!ref)\r
+       if (ref == slang_ref_forbid)\r
        {\r
-               if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
+               if (!slang_assembly_file_push_label2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))\r
                        return 0;\r
        }\r
 \r
        if (slang_string_compare ("=", oper) == 0)\r
        {\r
-               if (!_slang_assemble_operation (file, &op->children[0], 1, &flow, space, info, &l_stk, mach,\r
-                               atoms))\r
+               if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_force))\r
                        return 0;\r
-               if (!_slang_assemble_operation (file, &op->children[1], 0, &flow, space, info, &r_stk, mach,\r
-                               atoms))\r
+               stk = A->swz;\r
+               if (!_slang_assemble_operation_ (A, &op->children[1], slang_ref_forbid))\r
                        return 0;\r
-               if (!_slang_assemble_assignment (file, op->children, space, info, &l_stk, mach, atoms))\r
+               A->swz = stk;\r
+               if (!_slang_assemble_assignment (A, op->children))\r
                        return 0;\r
        }\r
        else\r
        {\r
-               if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info, mach,\r
-                               atoms))\r
+               if (!_slang_assemble_function_call_name (A, oper, op->children, op->num_children, GL_TRUE))\r
                        return 0;\r
        }\r
 \r
-       if (!ref)\r
+       if (ref == slang_ref_forbid)\r
        {\r
-               if (!slang_assembly_file_push (file, slang_asm_addr_copy))\r
+               if (!slang_assembly_file_push (A->file, slang_asm_addr_copy))\r
                        return 0;\r
-               if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+               if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, 4))\r
                        return 0;\r
-               if (!_slang_dereference (file, op->children, space, info, mach, atoms))\r
+               if (!_slang_dereference (A->file, op->children, &A->space, &A->local, A->mach, A->atoms))\r
                        return 0;\r
        }\r
 \r
index 1dc48b1..dfec8b0 100644 (file)
 extern "C" {\r
 #endif\r
 \r
-int _slang_assemble_assignment (slang_assembly_file *, slang_operation *,\r
-       slang_assembly_name_space *, slang_assembly_local_info *, slang_assembly_stack_info *,\r
-       struct slang_machine_ *, slang_atom_pool *);\r
+int _slang_assemble_assignment (slang_assemble_ctx *, slang_operation *);\r
 \r
-int _slang_assemble_assign (slang_assembly_file *, slang_operation *, const char *, int ref,\r
-       slang_assembly_name_space *, slang_assembly_local_info *, struct slang_machine_ *,\r
-       slang_atom_pool *);\r
+int _slang_assemble_assign (slang_assemble_ctx *, slang_operation *, const char *, slang_ref_type);\r
 \r
 #ifdef __cplusplus\r
 }\r
index 1124320..eb02ccc 100644 (file)
@@ -1489,8 +1489,7 @@ static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, s
        return 1;
 }\r
 \r
-static int initialize_global (slang_assembly_file *file, slang_machine *pmach,\r
-       slang_assembly_name_space *space, slang_variable *var, slang_atom_pool *atoms)\r
+static int initialize_global (slang_assemble_ctx *A, slang_variable *var)\r
 {\r
        slang_assembly_file_restore_point point;\r
        slang_machine mach;\r
@@ -1501,20 +1500,20 @@ static int initialize_global (slang_assembly_file *file, slang_machine *pmach,
        slang_assembly_stack_info stk;\r
 \r
        /* save the current assembly */\r
-       if (!slang_assembly_file_restore_point_save (file, &point))\r
+       if (!slang_assembly_file_restore_point_save (A->file, &point))\r
                return 0;\r
 \r
        /* setup the machine */\r
-       mach = *pmach;\r
-       mach.ip = file->count;\r
+       mach = *A->mach;\r
+       mach.ip = A->file->count;\r
 \r
        /* allocate local storage for expression */\r
        info.ret_size = 0;\r
        info.addr_tmp = 0;\r
        info.swizzle_tmp = 4;\r
-       if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, 20))\r
+       if (!slang_assembly_file_push_label (A->file, slang_asm_local_alloc, 20))\r
                return 0;\r
-       if (!slang_assembly_file_push_label (file, slang_asm_enter, 20))\r
+       if (!slang_assembly_file_push_label (A->file, slang_asm_enter, 20))\r
                return 0;\r
 \r
        /* construct the left side of assignment */\r
@@ -1554,7 +1553,7 @@ static int initialize_global (slang_assembly_file *file, slang_machine *pmach,
        op_assign.children[1] = *var->initializer;\r
 \r
        /* insert the actual expression */\r
-       result = _slang_assemble_operation (file, &op_assign, 0, &flow, space, &info, &stk, pmach, atoms);\r
+       result = _slang_assemble_operation (A->file, &op_assign, 0, &flow, &A->space, &info, &stk, A->mach, A->atoms);\r
 \r
        /* carefully destroy the operations */\r
        op_assign.num_children = 0;\r
@@ -1566,19 +1565,19 @@ static int initialize_global (slang_assembly_file *file, slang_machine *pmach,
 \r
        if (!result)\r
                return 0;\r
-       if (!slang_assembly_file_push (file, slang_asm_exit))\r
+       if (!slang_assembly_file_push (A->file, slang_asm_exit))\r
                return 0;\r
 \r
        /* execute the expression */\r
-       if (!_slang_execute2 (file, &mach))\r
+       if (!_slang_execute2 (A->file, &mach))\r
                return 0;\r
 \r
        /* restore the old assembly */\r
-       if (!slang_assembly_file_restore_point_load (file, &point))\r
+       if (!slang_assembly_file_restore_point_load (A->file, &point))\r
                return 0;\r
 \r
        /* now we copy the contents of the initialized variable back to the original machine */\r
-       _mesa_memcpy ((GLubyte *) pmach->mem + var->address, (GLubyte *) mach.mem + var->address,\r
+       _mesa_memcpy ((GLubyte *) A->mach->mem + var->address, (GLubyte *) mach.mem + var->address,\r
                var->size);\r
 \r
        return 1;\r
@@ -1728,12 +1727,15 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
        /* initialize global variable */\r
        if (C->global_scope && var->initializer != NULL)\r
        {\r
-               slang_assembly_name_space space;\r
-\r
-               space.funcs = O->funs;\r
-               space.structs = O->structs;\r
-               space.vars = O->vars;\r
-               if (!initialize_global (O->assembly, O->machine, &space, var, C->atoms))\r
+               slang_assemble_ctx A;\r
+\r
+               A.file = O->assembly;\r
+               A.mach = O->machine;\r
+               A.atoms = C->atoms;\r
+               A.space.funcs = O->funs;\r
+               A.space.structs = O->structs;\r
+               A.space.vars = O->vars;\r
+               if (!initialize_global (&A, var))\r
                        return 0;\r
        }
        return 1;
@@ -1783,7 +1785,7 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti
                        return 0;
                }
        }
-/*     else
+       else
        {
                if (!parse_function_prototype (C, O, &parsed_func))
                {
@@ -1813,45 +1815,48 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti
                /* return the newly parsed function */
                *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
        }
-/*     else
+       else
        {
                /* TODO: check function return type qualifiers and specifiers */
-/*             if (definition)
-               {
-                       /* destroy the existing function declaration and replace it with the new one */
-/*                     if (found_func->body != NULL)
+               if (definition)
+               {\r
+                       if (found_func->body != NULL)
                        {
                                slang_info_log_error (C->L, "%s: function already has a body",
-                                       parsed_func.header.name);
+                                       slang_atom_pool_id (C->atoms, parsed_func.header.a_name));
                                slang_function_destruct (&parsed_func);
                                return 0;
-                       }
+                       }\r
+\r
+                       /* destroy the existing function declaration and replace it with the new one,\r
+                        * remember to save the fixup table */\r
+                       parsed_func.fixups = found_func->fixups;\r
+                       slang_fixup_table_init (&found_func->fixups);
                        slang_function_destruct (found_func);
                        *found_func = parsed_func;
                }
                else
                {
                        /* another declaration of the same function prototype - ignore it */
-/*                     slang_function_destruct (&parsed_func);
+                       slang_function_destruct (&parsed_func);
                }
 
                /* return the found function */
-/*             *parsed_func_ret = found_func;
+               *parsed_func_ret = found_func;
        }
 
        /* assemble the parsed function */
-       if (definition)
        {
-               slang_assembly_name_space space;
-\r
-               space.funcs = O->funs;
-               space.structs = O->structs;
-               space.vars = O->vars;\r
-               if (!_slang_assemble_function (O->assembly, *parsed_func_ret, &space, O->machine, C->atoms))\r
-               {\r
-                       const char *name = slang_atom_pool_id (C->atoms, (**parsed_func_ret).header.a_name);
+               slang_assemble_ctx A;
+\r
+               A.file = O->assembly;\r
+               A.mach = O->machine;\r
+               A.atoms = C->atoms;\r
+               A.space.funcs = O->funs;
+               A.space.structs = O->structs;
+               A.space.vars = O->vars;\r
+               if (!_slang_assemble_function (&A, *parsed_func_ret))\r
                        return 0;\r
-               }
        }
        return 1;
 }
index d62b009..5edba72 100644 (file)
 #include "slang_compile_operation.h"\r
 #include "slang_compile_function.h"\r
 \r
+/* slang_fixup_table */\r
+\r
+void slang_fixup_table_init (slang_fixup_table *fix)\r
+{\r
+       fix->table = NULL;\r
+       fix->count = 0;\r
+}\r
+\r
+void slang_fixup_table_free (slang_fixup_table *fix)\r
+{\r
+       slang_alloc_free (fix->table);\r
+       slang_fixup_table_init (fix);\r
+}\r
+\r
 /* slang_function */\r
 \r
 int slang_function_construct (slang_function *func)\r
@@ -56,6 +70,7 @@ int slang_function_construct (slang_function *func)
        func->param_count = 0;\r
        func->body = NULL;\r
        func->address = ~0;\r
+       slang_fixup_table_init (&func->fixups);\r
        return 1;\r
 }\r
 \r
@@ -69,6 +84,7 @@ void slang_function_destruct (slang_function *func)
                slang_operation_destruct (func->body);\r
                slang_alloc_free (func->body);\r
        }\r
+       slang_fixup_table_free (&func->fixups);\r
 }\r
 \r
 /* slang_function_scope */\r
index 59743df..d120881 100644 (file)
@@ -36,6 +36,15 @@ typedef enum slang_function_kind_
        slang_func_operator\r
 } slang_function_kind;\r
 \r
+typedef struct slang_fixup_table_\r
+{\r
+       GLuint *table;\r
+       GLuint count;\r
+} slang_fixup_table;\r
+\r
+void slang_fixup_table_init (slang_fixup_table *);\r
+void slang_fixup_table_free (slang_fixup_table *);\r
+\r
 typedef struct slang_function_\r
 {\r
        slang_function_kind kind;\r
@@ -44,6 +53,7 @@ typedef struct slang_function_
        unsigned int param_count;\r
        slang_operation *body;\r
        unsigned int address;\r
+       slang_fixup_table fixups;\r
 } slang_function;\r
 \r
 int slang_function_construct (slang_function *);\r