1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
#ifndef EASYXS_PERLCALL_H
#define EASYXS_PERLCALL_H 1
#include "init.h"
static inline void _EASYXS_SET_ARGS (pTHX_ SV* object, SV** args) {
dSP;
unsigned argscount = 0;
if (args) {
while (args[argscount] != NULL) argscount++;
}
ENTER;
SAVETMPS;
PUSHMARK(SP);
if (object || argscount) {
EXTEND(SP, (object ? 1 : 0) + argscount);
if (object) PUSHs( sv_mortalcopy(object) );
unsigned a=0;
while (a < argscount) mPUSHs( args[a++] );
PUTBACK;
}
}
#define exs_call_sv_void(sv, args) STMT_START { \
_EASYXS_SET_ARGS(aTHX_ NULL, args); \
call_sv(sv, G_DISCARD | G_VOID); \
FREETMPS; \
LEAVE; \
} STMT_END
#define exs_call_method_void(object, methname, args) STMT_START { \
_EASYXS_SET_ARGS(aTHX_ object, args); \
\
call_method( methname, G_DISCARD | G_VOID ); \
\
FREETMPS; \
LEAVE; \
} STMT_END
static inline SV* _easyxs_fetch_scalar_return (pTHX_ int count) {
dSP;
SPAGAIN;
SV* ret;
if (count == 0) {
ret = &PL_sv_undef;
}
else {
ret = SvREFCNT_inc(POPs);
while (count-- > 1) PERL_UNUSED_VAR(POPs);
}
PUTBACK;
FREETMPS;
LEAVE;
return ret;
}
static inline SV** _easyxs_fetch_list_return (pTHX_ int count) {
dSP;
SPAGAIN;
SV** ret;
Newx(ret, 1 + count, SV*);
ret[count] = NULL;
while (count-- > 0) {
ret[count] = SvREFCNT_inc(POPs);
}
PUTBACK;
FREETMPS;
LEAVE;
SAVEFREEPV(ret);
return ret;
}
static inline SV* _easyxs_call_method_scalar (pTHX_ SV* object, const char* methname, SV** args) {
_EASYXS_SET_ARGS(aTHX_ object, args);
int count = call_method(methname, G_SCALAR);
return _easyxs_fetch_scalar_return(aTHX_ count);
}
#define exs_call_method_scalar(object, methname, args) \
_easyxs_call_method_scalar(aTHX_ object, methname, args)
static inline SV* _easyxs_call_sv_scalar (pTHX_ SV* cb, SV** args) {
_EASYXS_SET_ARGS(aTHX_ NULL, args);
int count = call_sv(cb, G_SCALAR);
return _easyxs_fetch_scalar_return(aTHX_ count);
}
#define exs_call_sv_scalar(sv, args) \
_easyxs_call_sv_scalar(aTHX_ sv, args)
static inline SV** _easyxs_call_sv_list (pTHX_ SV* cb, SV** args) {
_EASYXS_SET_ARGS(aTHX_ NULL, args);
int count = call_sv(cb, G_ARRAY);
return _easyxs_fetch_list_return(aTHX_ count);
}
#define exs_call_sv_list(sv, args) \
_easyxs_call_sv_list(aTHX_ sv, args)
#define _handle_trapped_error(count, err_p) STMT_START { \
dSP; \
SV* err_tmp = ERRSV; \
if (SvTRUE(err_tmp)) { \
while (count--) PERL_UNUSED_VAR(POPs); \
\
*err_p = newSVsv(err_tmp); \
\
PUTBACK; \
FREETMPS; \
LEAVE; \
} \
} STMT_END
static inline void _easyxs_call_sv_void_trapped (pTHX_ SV* cb, SV** args, SV** error) {
_EASYXS_SET_ARGS(aTHX_ NULL, args);
int count = call_sv(cb, G_VOID | G_EVAL);
_handle_trapped_error(count, error);
}
#define exs_call_sv_void_trapped(sv, args, err_p) \
_easyxs_call_sv_void_trapped(aTHX_ sv, args, err_p)
static inline SV* _easyxs_call_sv_scalar_trapped (pTHX_ SV* cb, SV** args, SV** error) {
_EASYXS_SET_ARGS(aTHX_ NULL, args);
int count = call_sv(cb, G_SCALAR | G_EVAL);
_handle_trapped_error(count, error);
if (SvTRUE(ERRSV)) return NULL;
return _easyxs_fetch_scalar_return(aTHX_ count);
}
#define exs_call_sv_scalar_trapped(sv, args, err_p) \
_easyxs_call_sv_scalar_trapped(aTHX_ sv, args, err_p)
static inline SV** _easyxs_call_sv_list_trapped (pTHX_ SV* cb, SV** args, SV** error) {
_EASYXS_SET_ARGS(aTHX_ NULL, args);
int count = call_sv(cb, G_ARRAY | G_EVAL);
_handle_trapped_error(count, error);
if (SvTRUE(ERRSV)) return NULL;
return _easyxs_fetch_list_return(aTHX_ count);
}
#define exs_call_sv_list_trapped(sv, args, err_p) \
_easyxs_call_sv_list_trapped(aTHX_ sv, args, err_p)
#endif
|