> > -    opcode_t *(*(*opcode_funcs)[2048])(); /* Opcode */
> > -                                          /* function table */
> > -    STRING_FUNCS *(*(*string_funcs)[64])();  /* String function table */
> > +    opcode_t     *(**opcode_funcs)();     /* Opcode function table */
> > +    STRING_FUNCS *(**string_funcs)();     /* String function table */
> 
> I'm a little unsure about this - where have those array declarations gone
> and why?

If you strip off the return type and argument list, the declaration of
opcode_funcs is

        *(*opcode_funcs)[2048]

which is a pointer to an array of function pointers (3 levels of
indirection). 

But if you look in interpreter.c, you find

        foo = mem_sys_allocate(2048 * sizeof(void *));
        ...        
        interpreter->opcode_funcs = (void*)foo;
        
which allocates the array and assigns it directly to opcode_funcs (2
levels of indirection), and the DO_OP macro has

        x = z->opcode_funcs; \\
        y = x[*w]; \\
        w = (y)(w,z); \\
        
which expands to

        code = (interpreter->opcode_funcs[*code])(code, interpreter);

(again, 2 levels of indirection).
 
So the declaration of opcode_funcs was at a different level of
indirection than its allocation and use. The compilers weren't
complaining about this because of all the (void *) casts. The IRIX64
compiler did complain, not about indirection levels, but about
assigning data pointers to function pointers.

For dynamic allocation of the opcode_funcs array (as in current code)
the appropriate declaration of opcode_funcs is

        opcode_t *(**opcode_funcs)();

For static allocation, write

        opcode_t *(*opcode_funcs[2048])();

and drop the mem_sys_allocate.


string_funcs isn't currently used, but I changed its declaration to
match opcode_funcs.


- SWM

Reply via email to