Thank you for the very thorough (sp?) explanation. It explains what I could only guess.
// Andreas
Martin Stjernholm, Roxen IS @ Pike developers forum wrote:
You have to get the number of references to the array correct. Since you reference it from THIS->acs_map, you must account for that:
THIS->acs_map = Pike_sp[-1].u.array; add_ref (THIS->acs_map);
Then you also should pop it off the stack:
THIS->acs_map = Pike_sp[-1].u.array; add_ref (THIS->acs_map); pop_stack();
The only thing that should remain on the stack when your function returns is the return value (if you want to return any). I guess the interpreter considered the array to be the return value in this case, and simply popped it away.
If you really want to micro-optimize you'll note that the code above increases the refcount in the array with add_ref and then decrease it again in pop_stack. You can avoid that extra work by manually decreasing the stack pointer:
THIS->acs_map = Pike_sp[-1].u.array; Pike_sp--;
This essentially "moves" the array ref from the stack to your variable. I wouldn't recommend that kind of trickery unless the code is time critical, however. Macros like add_ref and pop_stack makes the code easier to understand and they also have nifty debug features built-in if you compile with rtldebug, dmalloc, and/or valgrind support.
Btw, your code assumes that THIS->acs_map doesn't reference an array already. If it might do, you have to free it first to avoid a leak:
if (THIS->acs_map) free_array (THIS->acs_map); THIS->acs_map = Pike_sp[-1].u.array; add_ref (THIS->acs_map); pop_stack();