home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / perl5 / Glib / Install / gperl_marshal.h < prev    next >
Encoding:
C/C++ Source or Header  |  2004-01-15  |  7.0 KB  |  250 lines

  1. #ifndef __GPERL_MARSHAL_H__
  2. #define __GPERL_MARSHAL_H__
  3.  
  4. /*
  5.  * here lie a few macros to reduce the amount of copied code needed when
  6.  * writing custom marshallers for GPerlClosures.  you'll typically need
  7.  * this if you are trying to make a signal's arguments writable, implement
  8.  * custom handling of G_TYPE_POINTER arguments, or other special
  9.  * circumstances.
  10.  */
  11.  
  12. #if 0 /* comment with embedded C comments... */
  13. =for example
  14.      
  15. A typical marshaller skeleton will look like this:
  16.  
  17.  static void
  18.  some_custom_marshaler (GClosure * closure,
  19.                         GValue * return_value,
  20.                         guint n_param_values,
  21.                         const GValue * param_values,
  22.                         gpointer invocation_hint,
  23.                         gpointer marshal_data)
  24.  {
  25.          dGPERL_CLOSURE_MARSHAL_ARGS;
  26.  
  27.          GPERL_CLOSURE_MARSHAL_INIT (closure, marshal_data);
  28.  
  29.          PERL_UNUSED_VAR (return_value);
  30.          PERL_UNUSED_VAR (n_param_values);
  31.          PERL_UNUSED_VAR (invocation_hint);
  32.  
  33.          ENTER;
  34.          SAVETMPS;
  35.  
  36.          PUSHMARK (SP);
  37.  
  38.          GPERL_CLOSURE_MARSHAL_PUSH_INSTANCE (param_values);
  39.  
  40.          /*
  41.       * push more parameters onto the perl stack... the ones
  42.       * in which we are interested are param_values[1] through
  43.           * param_values[n_param_values-1], because the 0th one
  44.       * has been handled for us.
  45.       */
  46.  
  47.          GPERL_CLOSURE_MARSHAL_PUSH_DATA;
  48.  
  49.          PUTBACK;
  50.  
  51.      /* this example invokes the callback in array context.
  52.       * other options are G_DISCARD and G_SCALAR.  see C<call_sv>
  53.       * in L<perlcall>. */
  54.          GPERL_CLOSURE_MARSHAL_CALL (G_ARRAY);
  55.  
  56.          /*
  57.       * get return values, if needed, and clean up.
  58.       * "count" will contain the number of values returned on the
  59.       * stack.
  60.       */
  61.  
  62.          FREETMPS;
  63.          LEAVE;
  64.  }
  65.  
  66. =cut
  67. #endif
  68.  
  69. /*
  70. =item dGPERL_CLOSURE_MARSHAL_ARGS
  71.  
  72. Declare several stack variables that the various GPERL_CLOSURE_MARSHAL macros
  73. will need.  Does C<dSP> for you.  This must go near the top of your C
  74. function, before any code statements.
  75.  
  76. =cut
  77.  */
  78. #define dGPERL_CLOSURE_MARSHAL_ARGS    \
  79.     GPerlClosure * pc;    \
  80.     int count;        \
  81.     SV * data;        \
  82.     SV * instance;        \
  83.     dSP;
  84.  
  85. /*
  86. =item GPERL_CLOSURE_MARSHAL_INIT (closure, marshal_data)
  87.  
  88. This must be called as the first non-declaration statement in the marshaller
  89. function.  In a threaded/threadable Perl, this ensures that all Perl API
  90. calls within the function happen in the same Perl interpreter that created
  91. the callback; if this is not first, strange things will happen.  This
  92. statement also initalizes C<pc> (the perl closure object) on the stack.
  93.  
  94. =cut
  95.  */
  96. #ifdef PERL_IMPLICIT_CONTEXT
  97.  
  98. # define GPERL_CLOSURE_MARSHAL_INIT(closure, marshal_data)    \
  99.     /* make sure we're executed by the same interpreter */    \
  100.     /* that created the closure object. */            \
  101.     PERL_SET_CONTEXT (marshal_data);            \
  102.     SPAGAIN;                        \
  103.     pc = (GPerlClosure *) closure;
  104.  
  105. #else
  106.  
  107. # define GPERL_CLOSURE_MARSHAL_INIT(closure, marshal_data)    \
  108.     PERL_UNUSED_VAR (marshal_data);                \
  109.     pc = (GPerlClosure *) closure;
  110.  
  111. #endif
  112.  
  113. /*
  114. =item GPERL_CLOSURE_MARSHAL_PUSH_INSTANCE(param_values)
  115.  
  116. This pushes the callback's instance (first parameter) onto the Perl argument
  117. stack, with XPUSHs.  Handles the case of swapped instance and data.  
  118. I<param_values> is the array of GValues passed into your marshaller.
  119. Note that the instance comes from param_values[0], so you needn't worry
  120. about that one when putting the rest of the parameters on the arg stack.
  121.  
  122. This assumes that n_param_values > 1.
  123.  
  124. =cut
  125. */
  126. /* note -- keep an eye on the refcounts of instance and data! */
  127. #define GPERL_CLOSURE_MARSHAL_PUSH_INSTANCE(param_values)    \
  128.     if (GPERL_CLOSURE_SWAP_DATA (pc)) {            \
  129.         /* swap instance and data */            \
  130.         data     = gperl_sv_from_value (param_values);    \
  131.         instance = SvREFCNT_inc (pc->data);        \
  132.     } else {                        \
  133.         /* normal */                    \
  134.         instance = gperl_sv_from_value (param_values);    \
  135.         data     = SvREFCNT_inc (pc->data);        \
  136.     }                            \
  137.     if (!instance)                        \
  138.         instance = &PL_sv_undef;            \
  139.     /* the instance is always the first item in @_ */    \
  140.     XPUSHs (sv_2mortal (instance));
  141.  
  142. /*
  143. =item GPERL_CLOSURE_MARSHAL_PUSH_DATA
  144.  
  145. Push the callback's user data onto the Perl arg stack, with XPUSHs.  Handles
  146. the case of swapped instance and data.  The user data is not included in
  147. param_values.
  148.  
  149. =cut
  150. */
  151. #define GPERL_CLOSURE_MARSHAL_PUSH_DATA    \
  152.     if (data) XPUSHs (sv_2mortal (data));
  153.  
  154.  
  155. /*
  156. =item GPERL_CLOSURE_MARSHAL_CALL(flags)
  157.  
  158. Invoke the callback.  You must ensure that all the arguments are already on
  159. the stack, and that you've called PUTBACK.  This will invoke call_sv(), adding
  160. G_EVAL to the I<flags> you supply, and store the return value in I<count> on
  161. the stack (count is declared by C<dGPERL_CLOSURE_MARSHAL_ARGS>).  It then
  162. refreshes the stack pointer.  If an exception occurred, the function returns
  163. after running exception handlers.
  164.  
  165. You'll be interested in the following values for I<flags>:
  166.  
  167.  G_DISCARD
  168.      this is effectively "void return", as it discards whatever the
  169.      callback put on the return stack.
  170.  G_SCALAR
  171.      invoke the callback in scalar context.  you are pretty much
  172.      guaranteed that one item will be on the stack, even if it is
  173.      undef.
  174.  G_ARRAY
  175.      invoke the callback in array context.  C<count> (declared by
  176.      C<dGPERL_CLOSURE_MARSHAL_ARGS>) will contain the number of
  177.      items on the return stack.
  178.  
  179. As the callback is always run with G_EVAL, call_sv() will clobber ERRSV
  180. ($@); since closures are typically part of a mechanism that is transparent
  181. to the layer of Perl code that calls them, we save and restore ERRSV.  Thus,
  182. code like
  183.  
  184.   eval { something that fails }
  185.   $button->clicked;
  186.   # $@ still has value from eval above
  187.  
  188. works as expected.
  189.  
  190. See C<call_sv> in L<perlcall> for more information.
  191.  
  192. =cut
  193. */
  194. #define GPERL_CLOSURE_MARSHAL_CALL(flags)    \
  195.     {                            \
  196.     /* copy is needed to keep the old value alive. */    \
  197.     /* mortal so it will die if not stolen by SvSetSV. */    \
  198.     SV * save_errsv = sv_2mortal (newSVsv (ERRSV));        \
  199.     count = call_sv (pc->callback, (flags) | G_EVAL);    \
  200.     SPAGAIN;                        \
  201.     if (SvTRUE (ERRSV)) {                    \
  202.         gperl_run_exception_handlers ();        \
  203.         SvSetSV (ERRSV, save_errsv);            \
  204.         FREETMPS;                    \
  205.         LEAVE;                        \
  206.         return;                        \
  207.     }                            \
  208.     SvSetSV (ERRSV, save_errsv);                \
  209.     }
  210.  
  211.  
  212. /***************************************************************************/
  213.  
  214. /*
  215. =item dGPERL_CALLBACK_MARSHAL_SP
  216.  
  217. Declare the stack pointer such that it can be properly initialized by
  218. C<GPERL_CALLBACK_MARSHAL_INIT>.  Do I<not> just use C<dSP>.
  219.  
  220. =item GPERL_CALLBACK_MARSHAL_INIT(callback)
  221.  
  222. Initialize the callback stuff.  This must happen before any other Perl API
  223. statements in the callback marshaller.  In a threaded Perl, this ensures that
  224. the proper interpreter context is used; if this isn't first, you'll mix and
  225. match two contexts and bad things will happen.
  226.  
  227. =cut
  228. */
  229. #ifdef PERL_IMPLICIT_CONTEXT
  230.  
  231. # define dGPERL_CALLBACK_MARSHAL_SP    \
  232.     SV ** sp;
  233.  
  234. # define GPERL_CALLBACK_MARSHAL_INIT(callback)    \
  235.     PERL_SET_CONTEXT (callback->priv);    \
  236.     SPAGAIN;
  237.  
  238. #else
  239.  
  240. # define dGPERL_CALLBACK_MARSHAL_SP    \
  241.     dSP;
  242.  
  243. # define GPERL_CALLBACK_MARSHAL_INIT(callback)    \
  244.     /* nothing to do */
  245.  
  246. #endif
  247.  
  248.  
  249. #endif /* __GPERL_MARSHAL_H__ */
  250.