This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add MAYBE_DEREF_GV macro
authorFather Chrysostomos <sprout@cpan.org>
Sat, 10 Sep 2011 13:09:26 +0000 (06:09 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 10 Sep 2011 13:43:49 +0000 (06:43 -0700)
There are so many parts of the core (mostly pp functions or functions
they call) that need a glob or a globref, including many that call
get-magic at the wrong time (or not at all in some cases, that it
makes sense to add a macro to do it.

It can be used like this:

   if (gv = MAYBE_DEREF_GV(sv)) /* calls get-magic */
   {

   }
   else { /* avoid magic here */

   }

pp.h
sv.h

diff --git a/pp.h b/pp.h
index 0ba877f..b6798ea 100644 (file)
--- a/pp.h
+++ b/pp.h
@@ -496,12 +496,25 @@ True if this op will be the return value of an lvalue subroutine
   )
 
 #ifdef PERL_CORE
+
 /* These are just for Perl_tied_method(), which is not part of the public API.
    Use 0x04 rather than the next available bit, to help the compiler if the
    architecture can generate more efficient instructions.  */
 #  define TIED_METHOD_MORTALIZE_NOT_NEEDED     0x04
 #  define TIED_METHOD_ARGUMENTS_ON_STACK       0x08
 #  define TIED_METHOD_SAY                      0x10
+
+/* Used in various places that need to dereference a glob or globref */
+#  define MAYBE_DEREF_GV(sv)                                       \
+    (                                                               \
+       SvGETMAGIC(sv),                                              \
+       isGV_with_GP(sv)                                              \
+         ? (GV *)sv                                                   \
+         : SvROK(sv) && (SvGETMAGIC(SvRV(sv)), isGV_with_GP(SvRV(sv))) \
+            ? (GV *)SvRV(sv)                                            \
+            : NULL                                                       \
+    )
+
 #endif
 
 /*
diff --git a/sv.h b/sv.h
index c838367..5345352 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -1919,7 +1919,7 @@ Returns a pointer to the character buffer.
 #define SvUNLOCK(sv) PL_unlockhook(aTHX_ sv)
 #define SvDESTROYABLE(sv) PL_destroyhook(aTHX_ sv)
 
-#define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
+#define SvGETMAGIC(x) ((void)(SvGMAGICAL(x) && mg_get(x)))
 #define SvSETMAGIC(x) STMT_START { if (SvSMAGICAL(x)) mg_set(x); } STMT_END
 
 #define SvSetSV_and(dst,src,finally) \