in reply to Re^5: Using $a and $b from XS
in thread Using $a and $b from XS
Maybe some time could be saved by looking up the symbols once and then filling in the aliases each time through the loop
That could definitely be done. By looking them up once at the top of the main routine and then reverting to your original scheme of passing them into the comparator sub each time (almost as constants) in addition to values to set into them would work, but just pushing and popping them as constants each comparison is going to have a hit.
So then you look at assigning the values into them inside the main routine, before passing them through. That's good, but it requires cut&paste reuse, complicates the calling of the comparator and makes the code messy.
That could probably be alleviated by the use of a couple of macros to assign the values to the globals inline to the call to the comparator, but when I tried it, the compiler generated streams of errors.
It necessitates calling macros within macros, including using some of those macros as lvalues of values returned by other macros. And worse, I don't really understand how some of those macros--which are themselves defined in terms of yet more macros--work! (Does anyone?) Therefore, I am not able to work out why what I was trying to do went bellyup.
Normally, if I get "macro expansion" problems, I just ask the compiler to output the preprocessor output so I can see what the actual effect is, but just trying to track down which damn source file is being passed to the compiler is the first problem. Trying to call it with the appropriate environment (compiler flags--libraries etc) outside of the MakeMaker nest-of-vipers is impossible.
So then I tried passing the /P flag via the Inline C options, which works, but as every source file includes every damn header in the whole crumbling edifice, it produces a file of 3/4 of a megabyte and ONE HUNDRED AND THIRTEEN THOUSAND NINE HUNDRED AND FOURTY EIGHT LINES!
And what lines. Here is what your nice elegant topNbs() function looks like by the time the C compiler comes to convert it to machine code:
void XS_main_topNbs(register PerlInterpreter *my_perl , CV* cv); void XS_main_topNbs(register PerlInterpreter *my_perl , CV* cv) { register SV **sp = (*Perl_Tstack_sp_ptr(((PerlInterpreter *)pthrea +d_getspecific((*Perl_Gthr_key_ptr(0)))))); register SV **mark = (*Per +l_Tstack_base_ptr(((PerlInterpreter *)pthread_getspecific((*Perl_Gthr +_key_ptr(0)))))) + (*(*Perl_Tmarkstack_ptr_ptr(((PerlInterpreter *)pt +hread_getspecific((*Perl_Gthr_key_ptr(0))))))--); I32 ax = mark - (*P +erl_Tstack_base_ptr(((PerlInterpreter *)pthread_getspecific((*Perl_Gt +hr_key_ptr(0)))))) + 1; I32 items = sp - mark; if (items != 3) Perl_croak(((PerlInterpreter *)pthread_getspecific((*Perl_Gthr_key +_ptr(0)))), "Usage: main::topNbs(n, cmp, data)"); sp -= items; { int n = (int)((((*Perl_Tstack_base_ptr(((PerlInterpreter *)pthr +ead_getspecific((*Perl_Gthr_key_ptr(0))))))[ax + (0)])->sv_flags & 0x +00010000) ? ((XPVIV*) ((*Perl_Tstack_base_ptr(((PerlInterpreter *)pth +read_getspecific((*Perl_Gthr_key_ptr(0))))))[ax + (0)])->sv_any)->xiv +_iv : Perl_sv_2iv(((PerlInterpreter *)pthread_getspecific((*Perl_Gthr +_key_ptr(0)))), (*Perl_Tstack_base_ptr(((PerlInterpreter *)pthread_ge +tspecific((*Perl_Gthr_key_ptr(0))))))[ax + (0)])); SV * cmp = (*Perl_Tstack_base_ptr(((PerlInterpreter *)pthread_g +etspecific((*Perl_Gthr_key_ptr(0))))))[ax + (1)]; AV * data; #line 258 "topN_pl_c7f1.xs" I32* temp; #line 314 "topN_pl_c7f1.c" if ((((*Perl_Tstack_base_ptr(((PerlInterpreter *)pthread_getspecif +ic((*Perl_Gthr_key_ptr(0))))))[ax + (2)])->sv_flags & 0x00080000) && +((((XRV*) ((*Perl_Tstack_base_ptr(((PerlInterpreter *)pthread_getspec +ific((*Perl_Gthr_key_ptr(0))))))[ax + (2)])->sv_any)->xrv_rv)->sv_fla +gs & 0xff)==SVt_PVAV) data = (AV*)((XRV*) ((*Perl_Tstack_base_ptr(((PerlInterpreter +*)pthread_getspecific((*Perl_Gthr_key_ptr(0))))))[ax + (2)])->sv_any) +->xrv_rv; else Perl_croak(((PerlInterpreter *)pthread_getspecific((*Perl_Gthr +_key_ptr(0)))), "data is not an array reference"); #line 260 "topN_pl_c7f1.xs" temp = (*Perl_Tmarkstack_ptr_ptr(((PerlInterpreter *)pthread_getsp +ecific((*Perl_Gthr_key_ptr(0))))))++; topNbs(n, cmp, data); if ((*Perl_Tmarkstack_ptr_ptr(((PerlInterpreter *)pthread_getspeci +fic((*Perl_Gthr_key_ptr(0)))))) != temp) { (*Perl_Tmarkstack_ptr_ptr(((PerlInterpreter *)pthread_getspecifi +c((*Perl_Gthr_key_ptr(0)))))) = temp; do { do { IV tmpXSoff = (0); (*Perl_Tstack_sp_ptr(((PerlInterpre +ter *)pthread_getspecific((*Perl_Gthr_key_ptr(0)))))) = (*Perl_Tstack +_base_ptr(((PerlInterpreter *)pthread_getspecific((*Perl_Gthr_key_ptr +(0)))))) + ax + (tmpXSoff - 1); return; } while (0); } while (0); } return; #line 330 "topN_pl_c7f1.c" (*Perl_Tstack_sp_ptr(((PerlInterpreter *)pthread_getspecific((*Per +l_Gthr_key_ptr(0)))))) = sp; return; } }
Now whilst the compiler may be able to make sense of it in that form, my eyes refuse to retain focus long enough to read from one end of a single line to the other.
I did try to reformat that to my usual coding standard, but--even standalone, away from the other 114, 000 lines--it caused my usually reliable reformatting macros to segfault my editor!
And do you see those oh so helpful line numbers embedded in compiler directives? Apart from the fact that they relate to intermediate files--some of which appear to get deleted--not the original source code--they are also, to the best of my ability to correlate them, WRONG!
So how does anyone debug this stuff? Symbolic debuggers (do they help)? Embedded break points? Reverse binary osmosis? Pressing their ear to the cpu and listening to the frequency of the hum?
I'm still hoping an expert will read this thread and give us some other ideas.
Hmmm. Maybe...
|
|---|