Hm, wait. You have it in THIS... that might be enough. D'oh...
Mirar @ Pike developers forum wrote:
Hm, wait. You have it in THIS... that might be enough. D'oh...
Hmm.. doesn't seem like my variables show up (with correct values), unless added to a pike class... ?
why doesn't this work (as expected == what am I doing wrong):
// Module variables PIKEVAR array(int) acs_map; PIKEVAR int LINES; PIKEVAR int COLS; PIKEVAR int TABSIZE;
PIKEFUN int initscr() { DPRINTF( "nc: initscr()\n" );
initscr();
// init acs_map int i; check_stack(120); BEGIN_AGGREGATE_ARRAY(120) { push_int(0); for( i = 1; acs_map[i]; i++ ) { if( i >= 512 ) Pike_error( "Unexpected large acs_map!" );
DPRINTF( " acs_map[%d]: %d\r\n" COMMA i COMMA acs_map[i] );
push_int(acs_map[ i ]); DO_AGGREGATE_ARRAY(120); } } END_AGGREGATE_ARRAY;
THIS->acs_map = Pike_sp[-1].u.array;
DPRINTF( "nc: acs_map: %x\r\n" COMMA THIS->acs_map ); DPRINTF( "nc: acs_map: size %d\r\n" COMMA THIS->acs_map->size ); DPRINTF( "nc: acs_map: item 0 %d\r\n" COMMA THIS->acs_map->item[0].u.integer ); DPRINTF( "nc: acs_map: item 10 %d\r\n" COMMA THIS->acs_map->item[10].u.integer );
// init vars THIS->LINES = LINES; THIS->COLS = COLS; THIS->TABSIZE = TABSIZE;
DPRINTF( "nc: LINES: %d\r\n" COMMA THIS->LINES ); // tells me lines = 60, but the value from the pike script says = 0.
not sure if I should pop_stack() or anything after assigning the value to THIS->acs_map (or it that's the way to do it at all?). when I run pike, the variables is present in the module, but all with the int value 0.
I have a PIKEFUN int foo; inside a PIKECLASS which i set to THIS->foo = 123; in it's INIT{}, and that comes out alright..
Kaos wrote:
Mirar @ Pike developers forum wrote:
Hm, wait. You have it in THIS... that might be enough. D'oh...
Hmm.. doesn't seem like my variables show up (with correct values), unless added to a pike class... ?
Ok, found out that I need to access the vars with Foo->bar, not Foo.bar (as it becomes if I use import, which seems like a bad idea(tm) ). But I still get seg fault when I try to access my array. Basic int's works fine, but haven't figured out how to save my array that I've built on the stack.
Any hints?
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();
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();
pike-devel@lists.lysator.liu.se