From: Vincent Pit Date: Mon, 28 Dec 2009 18:59:39 +0000 (+0100) Subject: Fix type coercions on values returned from callbacks X-Git-Tag: v0.40~9 X-Git-Url: http://git.vpit.fr/?a=commitdiff_plain;h=ca8e318c303fb28fc36f25ea16842cd768b4c52d;p=perl%2Fmodules%2FVariable-Magic.git Fix type coercions on values returned from callbacks --- diff --git a/Magic.xs b/Magic.xs index 3a170c0..e55503a 100644 --- a/Magic.xs +++ b/Magic.xs @@ -907,23 +907,15 @@ STATIC SV *vmg_op_info(pTHX_ unsigned int opinfo) { /* ... svt callbacks ....................................................... */ -#define VMG_CB_CALL_SET_RET(D) \ - { \ - SV *svr; \ - SPAGAIN; \ - svr = POPs; \ - ret = SvOK(svr) ? SvIV(svr) : (D); \ - PUTBACK; \ - } - #define VMG_CB_CALL_ARGS_MASK 15 #define VMG_CB_CALL_ARGS_SHIFT 4 #define VMG_CB_CALL_OPINFO (VMG_OP_INFO_NAME|VMG_OP_INFO_OBJECT) STATIC int vmg_cb_call(pTHX_ SV *cb, unsigned int flags, SV *sv, ...) { va_list ap; - int ret; + int ret = 0; unsigned int i, args, opinfo; + SV *svr; dSP; @@ -949,7 +941,11 @@ STATIC int vmg_cb_call(pTHX_ SV *cb, unsigned int flags, SV *sv, ...) { call_sv(cb, G_SCALAR); - VMG_CB_CALL_SET_RET(0); + SPAGAIN; + svr = POPs; + if (SvOK(svr)) + ret = (int) SvIV(svr); + PUTBACK; FREETMPS; LEAVE; @@ -978,6 +974,7 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { const MGWIZ *w = vmg_wizard_mgwiz(mg->mg_ptr); unsigned int opinfo = w->opinfo; U32 len, ret; + SV *svr; svtype t = SvTYPE(sv); dSP; @@ -1010,12 +1007,17 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { call_sv(w->cb_len, G_SCALAR); - VMG_CB_CALL_SET_RET(len); + SPAGAIN; + svr = POPs; + ret = SvOK(svr) ? (U32) SvUV(svr) : len; + if (t == SVt_PVAV) + --ret; + PUTBACK; FREETMPS; LEAVE; - return t == SVt_PVAV ? ret - 1 : ret; + return ret; } STATIC int vmg_svt_clear(pTHX_ SV *sv, MAGIC *mg) { @@ -1031,6 +1033,7 @@ STATIC int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) { #endif I32 had_err, has_err, flags = G_SCALAR | G_EVAL; int ret = 0; + SV *svr; dSP; @@ -1087,7 +1090,11 @@ STATIC int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) { if (IN_PERL_COMPILETIME && !had_err && has_err) ++PL_error_count; - VMG_CB_CALL_SET_RET(0); + SPAGAIN; + svr = POPs; + if (SvOK(svr)) + ret = (int) SvIV(svr); + PUTBACK; FREETMPS; LEAVE;